/* 8/22/96 (Current release HDF4.0r2)
 * This program illustrates how to write external vdata.
 * Routine VSsetexternalfile is added since HDF4.0r1. (was it
 * announced in our ABOUT or newsletters?)
 * Users should use VSsetexternalfile() to make external vdata.
 * The calling sequence is, see the first external vdata in this
 * program:
 *   VSattach()
 *   ...
 *   VSsetexternalfile()
 *   VSwrite()
 *   VSdetach() 
 *
 * Before VSsetexternalfile() was available some users created
 * external vdata by using HXcreate(). Such as:
 *     VSattach()
 *     ...
 *     vs_ref = VSQueryref(vs_id);
 *     HXcreate()
 *     VSwrite()
 *     VSdetah()
 *     Hendaccess()
 * 
 * We urge these users to modify their code, use VSsetexternalfile() 
 * instead of using HXcreate(). There are two reasons. First, 
 * VSsetexternalfile() is now available and it is a high level
 * routine. It is safer to use API routines than mixing routines
 * of different layers. The second reason is that the way how access 
 * id is handled internally has been changed. In order to improve 
 * performance of HDF libraries, the access record of the vdata will
 * not be closed until VSdetach is called. Therefore, HXcreate()
 * can't change the access id of a vdata unless VSdetach is called to
 * release the access id. 
 * If someone has to use HXcreate(), he/she needs
 * to call VSdetach() to detach the vdata before calling
 * HXcreate() to promote the vdata as an external vdata.
 * The calling sequence should be, see the second external vdata 
 * in this program:
 *   VSattach()
 *   ...
 *   VSdetach()
 *   HXcreate()
 *   Hendaccess()
 *   VSattach()
 *   ...
 *   VSwrite()
 *   VSdetach()
 *
 *
*/
#include "hdf.h"
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#define  NELTS  6
#define  NROWS  3
#define  RANK   2

char *fn = "myext.hdf";
char *dfn = "myext.dat";
char *dfn2 = "myext2.dat";

int32  dims[RANK] = {NROWS, NELTS};
int32 start[RANK] = {0, 0};
int32 data1[NROWS][NELTS] = { 5, 8, 11, 14, 17, 20,
                            25, 28, 31, 34, 37, 40,
                            45, 48, 51, 54, 57, 60};
int32 data2[NROWS][NELTS] = { 15, 18, 21, 24, 27, 30,
                            35, 38, 41, 44, 47, 50,
                            55, 58, 61, 64, 67, 70};
                        
main()   {

    int ret, i, vs_id;
    int32 fid, vs_ref, aid;
    int32 indata1[NROWS][NELTS], indata2[NROWS][NELTS], *p;
    int  num, sz;
    FILE *fp, *fopen();

    fid = Hopen(fn, DFACC_CREATE,0);
    Vstart(fid);
/* create the first external vdata */
    vs_id = VSattach(fid, -1, "w");
    ret = VSfdefine(vs_id, "f1", DFNT_INT32, NELTS);
    ret = VSsetfields(vs_id, "f1");
    VSsetname(vs_id, "ext1");   /* not required */
    ret = VSsetexternalfile(vs_id, dfn, 0);
    ret = VSwrite(vs_id, (unsigned char *)data1, NROWS, FULL_INTERLACE);
    VSdetach(vs_id);

/* make the second vdata */
    vs_id = VSattach(fid, -1, "w");
    ret = VSfdefine(vs_id, "f2", DFNT_INT32, NELTS);
    ret = VSsetfields(vs_id, "f2");
/*    VSsetname(vs_id, "ext2");    */
    vs_ref = VSQueryref(vs_id);
    ret = VSdetach(vs_id); /* have to be detached before
                              HXcreate is called  */
/* promote to external element */
    aid = HXcreate(fid, DFTAG_VS, vs_ref, dfn2, 0, 0);
    ret = Hendaccess(aid);
    vs_id = VSattach(fid, vs_ref, "w");
    ret = VSwrite(vs_id, (unsigned char *)data2, NROWS, FULL_INTERLACE);
    VSdetach(vs_id);
    Vend(fid);
    ret = Hclose(fid);

/*  read back */

    fid = Hopen(fn, DFACC_RDWR, 0);
    Vstart(fid);
/*    vs_ref = VSfind(fid, "ext1");  */
    vs_ref = VSgetid(fid, -1);
    vs_id = VSattach(fid, vs_ref,"w"); 
    ret = VSsetfields(vs_id, "f1");
    ret = VSread(vs_id, (unsigned char *)indata1, NROWS, FULL_INTERLACE);
    VSdetach(vs_id);
    p = &(indata1[0][0]);
    for (i=0; i<18; i++) {
       printf("%d ", *p);
       p++;
    }
    printf("\n\n");
/* read in the second */
/*    vs_ref = VSfind(fid, "ext2");  */
    vs_ref = VSgetid(fid, vs_ref);
    vs_id = VSattach(fid, vs_ref,"w"); 
    ret = VSsetfields(vs_id, "f2");
    ret = VSread(vs_id, (unsigned char *)indata2, NROWS, FULL_INTERLACE);
    VSdetach(vs_id);
    p = &(indata2[0][0]);
    for (i=0; i<18; i++) {
       printf("%d ", *p);
       p++;
    }
    printf("\n\n");

    Vend(fid);
    ret = Hclose(fid);
}

