#include #include #include #include #include "netcdf.h" #undef DEBUG #ifdef DEBUG static char* buf = NULL; #endif #define totalNumStrings 13 static const char* charPointers[totalNumStrings] = {"banana", "kiwi", "apple", "grape", "apple", "cherry", "lemon", "melon", "watermelon", "strawberry", "peach", "raspberry", "pineapple"}; #define first_size 2 #define second_size 1 #define third_size 5 #define fourth_size 3 #define fifth_size 0 #define sixth_size 2 #define attlength 6 void checkErrorCode(int status, const char* message) { if (status != NC_NOERR){ fprintf(stderr,"Error code: %d from %s\n",status,message); fprintf(stderr,"\t%s\n\n",nc_strerror(status)); } } void writeVariable(size_t dimlength, int ncid, nc_type vlen_typeID) { int retval = NC_NOERR; int dimid; int varid; /* Setup data */ nc_vlen_t* data = calloc(sizeof(nc_vlen_t),dimlength); /* create six variable length arrays of strings */ int stringIndex = 0; data[0].len = first_size; data[0].p = charPointers+stringIndex; stringIndex += first_size; data[1].len = second_size; data[1].p = charPointers+stringIndex; stringIndex += second_size; data[2].len = third_size; data[2].p = charPointers+stringIndex; stringIndex += third_size; data[3].len = fourth_size; data[3].p = charPointers+stringIndex; stringIndex += fourth_size; data[4].len = fifth_size; data[4].p = charPointers+stringIndex; stringIndex += fifth_size; data[5].len = sixth_size; data[5].p = charPointers+stringIndex; stringIndex += sixth_size; /* Write vlen variable named Fruits */ /* Define dimension */ retval = nc_def_dim(ncid, "D1", dimlength, &dimid); checkErrorCode(retval, "nc_def_dim"); /* Define variable */ retval = nc_def_var(ncid, "Fruits", vlen_typeID, 1, &dimid, &varid); checkErrorCode(retval, "nc_def_var"); /* Write variable */ retval = nc_put_var(ncid, varid, data); checkErrorCode(retval, "nc_put_var"); free(data); } static void createFruitsData(int elemno, size_t vlensize, size_t* stringIndexp, nc_vlen_t* data) { data[elemno].len = vlensize; data[elemno].p = NULL; if(vlensize > 0) { data[elemno].p = charPointers+(*stringIndexp); (*stringIndexp) += vlensize; } } void writeAttribute(size_t len, int ncid, nc_type vlen_typeID) { int retval = NC_NOERR; /* Setup data */ nc_vlen_t* data = calloc(sizeof(nc_vlen_t), len); /* create six variable length arrays of strings */ size_t stringIndex = 0; createFruitsData(0,first_size,&stringIndex,data); createFruitsData(1,second_size,&stringIndex,data); createFruitsData(2,third_size,&stringIndex,data); createFruitsData(3,fourth_size,&stringIndex,data); createFruitsData(4,fifth_size,&stringIndex,data); createFruitsData(5,sixth_size,&stringIndex,data); #ifdef DEBUG if(buf) {free(buf); buf = NULL;} nc_dump_data(ncid,vlen_typeID,data,len,&buf); fprintf(stderr,">>> attribute = %s\n",buf); #endif /* Write vlen attribute named Fruits */ retval = nc_put_att(ncid, NC_GLOBAL, "Fruit", vlen_typeID, len, data); checkErrorCode(retval, "nc_put_att"); free(data); } int main(int argc, const char * argv[]) { /* Open file */ int ncid; int retval; nc_type vlen_typeID; retval = nc_create("tst_vlenstr.nc", NC_NETCDF4, &ncid); checkErrorCode(retval, "nc_create"); /* Define vlen type named MY_VLEN_STRING */ retval = nc_def_vlen(ncid, "MY_VLEN_STRING", NC_STRING, &vlen_typeID); checkErrorCode(retval, "nc_def_vlen"); /* write variable - will be able to read it back fine */ writeVariable(attlength, ncid, vlen_typeID); /* write attribute - will read back garbled values */ writeAttribute(attlength, ncid, vlen_typeID); retval = nc_close(ncid); checkErrorCode(retval, "nc_close"); #ifdef DEBUG if(buf) free(buf); #endif return retval; }