/* Estimate variables sizes and then resort the variable list by that size */ void estimatevarsizes3(NCDAPCOMMON* dapcomm) { int ivar; unsigned int rank; size_t totalsize = 0; for(ivar=0;ivar<nclistlength(dapcomm->cdf.ddsroot->tree->varnodes);ivar++) { CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.ddsroot->tree->varnodes,ivar); NClist* ncdims = var->array.dimset0; rank = nclistlength(ncdims); if(rank == 0) { /* use instance size of the type */ var->estimatedsize = nctypesizeof(var->etype); #ifdef DEBUG1 fprintf(stderr,"scalar %s.estimatedsize = %lu\n", makecdfpathstring3(var,"."),var->estimatedsize); #endif } else { unsigned long size = cdftotalsize3(ncdims); size *= nctypesizeof(var->etype); #ifdef DEBUG1 fprintf(stderr,"array %s(%u).estimatedsize = %lu\n", makecdfpathstring3(var,"."),rank,size); #endif var->estimatedsize = size; } totalsize += var->estimatedsize; } #ifdef DEBUG1 fprintf(stderr,"total estimatedsize = %lu\n",totalsize); #endif dapcomm->cdf.totalestimatedsize = totalsize; }
static NCerror cvttype(nc_type etype, char** srcp, char** dstp) { unsigned int typesize = nctypesizeof(etype); char* src = *srcp; char* dst = *dstp; switch (etype) { case NC_STRING: case NC_URL: { char* ssrc = *(char**)src; *((char**)dst) = nulldup(ssrc); srcp += typesize; dstp += typesize; } break; default: if(typesize == 0) goto fail; memcpy((void*)dst,(void*)src,typesize); srcp += typesize; dstp += typesize; break; } return NC_NOERR; fail: oc_log(OCLOGERR,"cvttype bad value: %s",oc_typetostring(etype)); return NC_EINVAL; }
static NCerror buildattribute3a(NCDAPCOMMON* dapcomm, NCattribute* att, nc_type vartype, int varid) { int i; NCerror ncstat = NC_NOERR; unsigned int nvalues = nclistlength(att->values); NC* drno = dapcomm->controller; /* If the type of the attribute is string, then we need*/ /* to convert to a single character string by concatenation. modified: 10/23/09 to insert newlines. modified: 10/28/09 to interpret escapes */ if(att->etype == NC_STRING || att->etype == NC_URL) { char* newstring; size_t newlen = 0; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(att->values,i); newlen += (1+strlen(s)); } newstring = (char*)malloc(newlen); MEMCHECK(newstring,NC_ENOMEM); newstring[0] = '\0'; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(att->values,i); if(i > 0) strcat(newstring,"\n"); strcat(newstring,s); } dapexpandescapes(newstring); if(newstring[0]=='\0') ncstat = nc_put_att_text(drno->substrate,varid,att->name,1,newstring); else ncstat = nc_put_att_text(drno->substrate,varid,att->name,strlen(newstring),newstring); free(newstring); } else { nc_type atype; unsigned int typesize; void* mem; /* It turns out that some servers upgrade the type of _FillValue in order to correctly preserve the original value. However, since the type of the underlying variable is not changes, we get a type mismatch. So, make sure the type of the fillvalue is the same as that of the controlling variable. */ if(varid != NC_GLOBAL && strcmp(att->name,"_FillValue")==0) atype = nctypeconvert(dapcomm,vartype); else atype = nctypeconvert(dapcomm,att->etype); typesize = nctypesizeof(atype); mem = malloc(typesize * nvalues); ncstat = dapcvtattrval3(atype,mem,att->values); ncstat = nc_put_att(drno->substrate,varid,att->name,atype,nvalues,mem); nullfree(mem); } return THROW(ncstat); }
static int conversionrequired(nc_type t1, nc_type t2) { if(t1 == t2) return 0; if(nctypesizeof(t1) != nctypesizeof(t2)) return 1; /* Avoid too many cases by making t1 < t2 */ if(t1 > t2) {int tmp = t1; t1 = t2; t2 = tmp;} #undef CASE #define CASE(t1,t2) ((t1)<<5 | (t2)) switch (CASE(t1,t2)) { case CASE(NC_BYTE,NC_UBYTE): case CASE(NC_BYTE,NC_CHAR): case CASE(NC_CHAR,NC_UBYTE): case CASE(NC_SHORT,NC_USHORT): case CASE(NC_INT,NC_UINT): case CASE(NC_INT64,NC_UINT64): return 0; default: break; } return 1; }
int dumpmetadata(int ncid, NChdr** hdrp) { int stat,i,j,k; NChdr* hdr = (NChdr*)calloc(1,sizeof(NChdr)); MEMCHECK(hdr,NC_ENOMEM); hdr->ncid = ncid; hdr->content = ncbytesnew(); if(hdrp) *hdrp = hdr; stat = nc_inq(hdr->ncid, &hdr->ndims, &hdr->nvars, &hdr->ngatts, &hdr->unlimid); CHECK(stat); if(ncdap3debug > 0) { fprintf(stdout,"ncid=%d ngatts=%d ndims=%d nvars=%d unlimid=%d\n", hdr->ncid,hdr->ngatts,hdr->ndims,hdr->nvars,hdr->unlimid); } hdr->gatts = (NCattribute*)calloc(1,hdr->ngatts*sizeof(NCattribute)); MEMCHECK(hdr->gatts,NC_ENOMEM); if(hdr->ngatts > 0) fprintf(stdout,"global attributes:\n"); for(i=0;i<hdr->ngatts;i++) { NCattribute* att = &hdr->gatts[i]; char attname[NC_MAX_NAME]; nc_type nctype; size_t typesize; size_t nvalues; stat = nc_inq_attname(hdr->ncid,NC_GLOBAL,i,attname); CHECK(stat); att->name = nulldup(attname); stat = nc_inq_att(hdr->ncid,NC_GLOBAL,att->name,&nctype,&nvalues); CHECK(stat); att->etype = nctypetodap(nctype); typesize = nctypesizeof(att->etype); fprintf(stdout,"\t[%d]: name=%s type=%s values(%lu)=", i,att->name,nctypetostring(octypetonc(att->etype)), (unsigned long)nvalues); if(nctype == NC_CHAR) { size_t len = typesize*nvalues; char* values = (char*)malloc(len+1);/* for null terminate*/ MEMCHECK(values,NC_ENOMEM); stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values); CHECK(stat); values[len] = '\0'; fprintf(stdout," '%s'",values); } else { size_t len = typesize*nvalues; char* values = (char*)malloc(len); MEMCHECK(values,NC_ENOMEM); stat = nc_get_att(hdr->ncid,NC_GLOBAL,att->name,values); CHECK(stat); for(k=0;k<nvalues;k++) { fprintf(stdout," "); dumpdata1(octypetonc(att->etype),k,values); } } fprintf(stdout,"\n"); } hdr->dims = (Dim*)malloc(hdr->ndims*sizeof(Dim)); MEMCHECK(hdr->dims,NC_ENOMEM); for(i=0;i<hdr->ndims;i++) { hdr->dims[i].dimid = i; stat = nc_inq_dim(hdr->ncid, hdr->dims[i].dimid, hdr->dims[i].name, &hdr->dims[i].size); CHECK(stat); fprintf(stdout,"dim[%d]: name=%s size=%lu\n", i,hdr->dims[i].name,(unsigned long)hdr->dims[i].size); } hdr->vars = (Var*)malloc(hdr->nvars*sizeof(Var)); MEMCHECK(hdr->vars,NC_ENOMEM); for(i=0;i<hdr->nvars;i++) { Var* var = &hdr->vars[i]; nc_type nctype; var->varid = i; stat = nc_inq_var(hdr->ncid, var->varid, var->name, &nctype, &var->ndims, var->dimids, &var->natts); CHECK(stat); var->nctype = (nctype); fprintf(stdout,"var[%d]: name=%s type=%s |dims|=%d", i, var->name, nctypetostring(var->nctype), var->ndims); fprintf(stdout," dims={"); for(j=0;j<var->ndims;j++) { fprintf(stdout," %d",var->dimids[j]); } fprintf(stdout,"}\n"); var->atts = (NCattribute*)malloc(var->natts*sizeof(NCattribute)); MEMCHECK(var->atts,NC_ENOMEM); for(j=0;j<var->natts;j++) { NCattribute* att = &var->atts[j]; char attname[NC_MAX_NAME]; size_t typesize; char* values; nc_type nctype; size_t nvalues; stat = nc_inq_attname(hdr->ncid,var->varid,j,attname); CHECK(stat); att->name = nulldup(attname); stat = nc_inq_att(hdr->ncid,var->varid,att->name,&nctype,&nvalues); CHECK(stat); att->etype = nctypetodap(nctype); typesize = nctypesizeof(att->etype); values = (char*)malloc(typesize*nvalues); MEMCHECK(values,NC_ENOMEM); stat = nc_get_att(hdr->ncid,var->varid,att->name,values); CHECK(stat); fprintf(stdout,"\tattr[%d]: name=%s type=%s values(%lu)=", j,att->name,nctypetostring(octypetonc(att->etype)),(unsigned long)nvalues); for(k=0;k<nvalues;k++) { fprintf(stdout," "); dumpdata1(octypetonc(att->etype),k,values); } fprintf(stdout,"\n"); } } fflush(stdout); return NC_NOERR; }
NCerror dapconvert3(nc_type srctype, nc_type dsttype, char* memory0, char* value0, size_t count) { NCerror ncstat = NC_NOERR; size_t i; char* memory = memory0; char* value = value0; /* In order to deal with the DAP upgrade problem, try to preserve the bit patterns */ /* Provide space and pointer casts for intermediate results */ signed char ncbyte; signed char* ncbytep; char ncchar; char* nccharp; short ncshort; short* ncshortp; int ncint; int* ncintp; float ncfloat; float* ncfloatp; double ncdouble; double* ncdoublep; unsigned char ncubyte; unsigned char* ncubytep; unsigned short ncushort; unsigned short* ncushortp; unsigned int ncuint; unsigned int* ncuintp; long long ncint64; long long* ncint64p; unsigned long long ncuint64; unsigned long long* ncuint64p; #define CASE(nc1,nc2) (nc1*256+nc2) #define CUT8(e) ((unsigned char)((e) & 0xff)) #define CUT16(e) ((unsigned short)((e) & 0xffff)) #define CUT32(e) ((unsigned int)((e) & 0xffffffff)) #define ARM(vs,ncs,ts,vd,ncd,td) \ case CASE(ncs,ncd):\ vs##p = (ts *)value;\ vs = *vs##p;\ vd##p = (td *)memory;\ *vd##p = (td)vs;\ break; for(i=0;i<count;i++) { switch (CASE(srctype,dsttype)) { ARM(ncchar,NC_CHAR,char,ncchar,NC_CHAR,char) ARM(ncchar,NC_CHAR,char,ncbyte,NC_BYTE,signed char) ARM(ncchar,NC_CHAR,char,ncubyte,NC_UBYTE,unsigned char) ARM(ncchar,NC_CHAR,char,ncshort,NC_SHORT,short) ARM(ncchar,NC_CHAR,char,ncushort,NC_USHORT,unsigned short) ARM(ncchar,NC_CHAR,char,ncint,NC_INT,int) ARM(ncchar,NC_CHAR,char,ncuint,NC_UINT,unsigned int) ARM(ncchar,NC_CHAR,char,ncint64,NC_INT64,long long) ARM(ncchar,NC_CHAR,char,ncuint64,NC_UINT64,unsigned long long) ARM(ncchar,NC_CHAR,char,ncfloat,NC_FLOAT,float) ARM(ncchar,NC_CHAR,char,ncdouble,NC_DOUBLE,double) ARM(ncbyte,NC_BYTE,signed char,ncchar,NC_CHAR,char) ARM(ncbyte,NC_BYTE,signed char,ncbyte,NC_BYTE,signed char) ARM(ncbyte,NC_BYTE,signed char,ncubyte,NC_UBYTE,unsigned char) ARM(ncbyte,NC_BYTE,signed char,ncshort,NC_SHORT,short) ARM(ncbyte,NC_BYTE,signed char,ncushort,NC_USHORT,unsigned short) ARM(ncbyte,NC_BYTE,signed char,ncint,NC_INT,int) ARM(ncbyte,NC_BYTE,signed char,ncuint,NC_UINT,unsigned int) ARM(ncbyte,NC_BYTE,signed char,ncint64,NC_INT64,long long) ARM(ncbyte,NC_BYTE,signed char,ncuint64,NC_UINT64,unsigned long long) ARM(ncbyte,NC_BYTE,signed char,ncfloat,NC_FLOAT,float) ARM(ncbyte,NC_BYTE,signed char,ncdouble,NC_DOUBLE,double) ARM(ncubyte,NC_UBYTE,unsigned char,ncchar,NC_CHAR,char) ARM(ncubyte,NC_UBYTE,unsigned char,ncbyte,NC_BYTE,signed char) ARM(ncubyte,NC_UBYTE,unsigned char,ncubyte,NC_UBYTE,unsigned char) ARM(ncubyte,NC_UBYTE,unsigned char,ncshort,NC_SHORT,short) ARM(ncubyte,NC_UBYTE,unsigned char,ncushort,NC_USHORT,unsigned short) ARM(ncubyte,NC_UBYTE,unsigned char,ncint,NC_INT,int) ARM(ncubyte,NC_UBYTE,unsigned char,ncuint,NC_UINT,unsigned int) ARM(ncubyte,NC_UBYTE,unsigned char,ncint64,NC_INT64,long long) ARM(ncubyte,NC_UBYTE,unsigned char,ncuint64,NC_UINT64,unsigned long long) ARM(ncubyte,NC_UBYTE,unsigned char,ncfloat,NC_FLOAT,float) ARM(ncubyte,NC_UBYTE,unsigned char,ncdouble,NC_DOUBLE,double) ARM(ncshort,NC_SHORT,short,ncchar,NC_CHAR,char) ARM(ncshort,NC_SHORT,short,ncbyte,NC_BYTE,signed char) ARM(ncshort,NC_SHORT,short,ncubyte,NC_UBYTE,unsigned char) ARM(ncshort,NC_SHORT,short,ncshort,NC_SHORT,short) ARM(ncshort,NC_SHORT,short,ncushort,NC_USHORT,unsigned short) ARM(ncshort,NC_SHORT,short,ncint,NC_INT,int) ARM(ncshort,NC_SHORT,short,ncuint,NC_UINT,unsigned int) ARM(ncshort,NC_SHORT,short,ncint64,NC_INT64,long long) ARM(ncshort,NC_SHORT,short,ncuint64,NC_UINT64,unsigned long long) ARM(ncshort,NC_SHORT,short,ncfloat,NC_FLOAT,float) ARM(ncshort,NC_SHORT,short,ncdouble,NC_DOUBLE,double) ARM(ncushort,NC_USHORT,unsigned short,ncchar,NC_CHAR,char) ARM(ncushort,NC_USHORT,unsigned short,ncbyte,NC_BYTE,signed char) ARM(ncushort,NC_USHORT,unsigned short,ncubyte,NC_UBYTE,unsigned char) ARM(ncushort,NC_USHORT,unsigned short,ncshort,NC_SHORT,short) ARM(ncushort,NC_USHORT,unsigned short,ncushort,NC_USHORT,unsigned short) ARM(ncushort,NC_USHORT,unsigned short,ncint,NC_INT,int) ARM(ncushort,NC_USHORT,unsigned short,ncuint,NC_UINT,unsigned int) ARM(ncushort,NC_USHORT,unsigned short,ncint64,NC_INT64,long long) ARM(ncushort,NC_USHORT,unsigned short,ncuint64,NC_UINT64,unsigned long long) ARM(ncushort,NC_USHORT,unsigned short,ncfloat,NC_FLOAT,float) ARM(ncushort,NC_USHORT,unsigned short,ncdouble,NC_DOUBLE,double) ARM(ncint,NC_INT,int,ncchar,NC_CHAR,char) ARM(ncint,NC_INT,int,ncbyte,NC_BYTE,signed char) ARM(ncint,NC_INT,int,ncubyte,NC_UBYTE,unsigned char) ARM(ncint,NC_INT,int,ncshort,NC_SHORT,short) ARM(ncint,NC_INT,int,ncushort,NC_USHORT,unsigned short) ARM(ncint,NC_INT,int,ncint,NC_INT,int) ARM(ncint,NC_INT,int,ncuint,NC_UINT,unsigned int) ARM(ncint,NC_INT,int,ncint64,NC_INT64,long long) ARM(ncint,NC_INT,int,ncuint64,NC_UINT64,unsigned long long) ARM(ncint,NC_INT,int,ncfloat,NC_FLOAT,float) ARM(ncint,NC_INT,int,ncdouble,NC_DOUBLE,double) ARM(ncuint,NC_UINT,unsigned int,ncchar,NC_CHAR,char) ARM(ncuint,NC_UINT,unsigned int,ncbyte,NC_BYTE,signed char) ARM(ncuint,NC_UINT,unsigned int,ncubyte,NC_UBYTE,unsigned char) ARM(ncuint,NC_UINT,unsigned int,ncshort,NC_SHORT,short) ARM(ncuint,NC_UINT,unsigned int,ncushort,NC_USHORT,unsigned short) ARM(ncuint,NC_UINT,unsigned int,ncint,NC_INT,int) ARM(ncuint,NC_UINT,unsigned int,ncuint,NC_UINT,unsigned int) ARM(ncuint,NC_UINT,unsigned int,ncint64,NC_INT64,long long) ARM(ncuint,NC_UINT,unsigned int,ncuint64,NC_UINT64,unsigned long long) ARM(ncuint,NC_UINT,unsigned int,ncfloat,NC_FLOAT,float) ARM(ncuint,NC_UINT,unsigned int,ncdouble,NC_DOUBLE,double) ARM(ncint64,NC_INT64,long long,ncchar,NC_CHAR,char) ARM(ncint64,NC_INT64,long long,ncbyte,NC_BYTE,signed char) ARM(ncint64,NC_INT64,long long,ncubyte,NC_UBYTE,unsigned char) ARM(ncint64,NC_INT64,long long,ncshort,NC_SHORT,short) ARM(ncint64,NC_INT64,long long,ncushort,NC_USHORT,unsigned short) ARM(ncint64,NC_INT64,long long,ncint,NC_INT,int) ARM(ncint64,NC_INT64,long long,ncuint,NC_UINT,unsigned int) ARM(ncint64,NC_INT64,long long,ncint64,NC_INT64,long long) ARM(ncint64,NC_INT64,long long,ncuint64,NC_UINT64,unsigned long long) ARM(ncint64,NC_INT64,long long,ncfloat,NC_FLOAT,float) ARM(ncint64,NC_INT64,long long,ncdouble,NC_DOUBLE,double) ARM(ncuint64,NC_UINT64,unsigned long long,ncchar,NC_CHAR,char) ARM(ncuint64,NC_UINT64,unsigned long long,ncbyte,NC_BYTE,signed char) ARM(ncuint64,NC_UINT64,unsigned long long,ncubyte,NC_UBYTE,unsigned char) ARM(ncuint64,NC_UINT64,unsigned long long,ncshort,NC_SHORT,short) ARM(ncuint64,NC_UINT64,unsigned long long,ncushort,NC_USHORT,unsigned short) ARM(ncuint64,NC_UINT64,unsigned long long,ncint,NC_INT,int) ARM(ncuint64,NC_UINT64,unsigned long long,ncuint,NC_UINT,unsigned int) ARM(ncuint64,NC_UINT64,unsigned long long,ncint64,NC_INT64,long long) ARM(ncuint64,NC_UINT64,unsigned long long,ncuint64,NC_UINT64,unsigned long long) ARM(ncuint64,NC_UINT64,unsigned long long,ncfloat,NC_FLOAT,float) ARM(ncuint64,NC_UINT64,unsigned long long,ncdouble,NC_DOUBLE,double) ARM(ncfloat,NC_FLOAT,float,ncchar,NC_CHAR,char) ARM(ncfloat,NC_FLOAT,float,ncbyte,NC_BYTE,signed char) ARM(ncfloat,NC_FLOAT,float,ncubyte,NC_UBYTE,unsigned char) ARM(ncfloat,NC_FLOAT,float,ncshort,NC_SHORT,short) ARM(ncfloat,NC_FLOAT,float,ncushort,NC_USHORT,unsigned short) ARM(ncfloat,NC_FLOAT,float,ncint,NC_INT,int) ARM(ncfloat,NC_FLOAT,float,ncuint,NC_UINT,unsigned int) ARM(ncfloat,NC_FLOAT,float,ncint64,NC_INT64,long long) ARM(ncfloat,NC_FLOAT,float,ncuint64,NC_UINT64,unsigned long long) ARM(ncfloat,NC_FLOAT,float,ncfloat,NC_FLOAT,float) ARM(ncfloat,NC_FLOAT,float,ncdouble,NC_DOUBLE,double) ARM(ncdouble,NC_DOUBLE,double,ncchar,NC_CHAR,char) ARM(ncdouble,NC_DOUBLE,double,ncbyte,NC_BYTE,signed char) ARM(ncdouble,NC_DOUBLE,double,ncubyte,NC_UBYTE,unsigned char) ARM(ncdouble,NC_DOUBLE,double,ncshort,NC_SHORT,short) ARM(ncdouble,NC_DOUBLE,double,ncushort,NC_USHORT,unsigned short) ARM(ncdouble,NC_DOUBLE,double,ncint,NC_INT,int) ARM(ncdouble,NC_DOUBLE,double,ncuint,NC_UINT,unsigned int) ARM(ncdouble,NC_DOUBLE,double,ncint64,NC_INT64,long long) ARM(ncdouble,NC_DOUBLE,double,ncuint64,NC_UINT64,unsigned long long) ARM(ncdouble,NC_DOUBLE,double,ncfloat,NC_FLOAT,float) ARM(ncdouble,NC_DOUBLE,double,ncdouble,NC_DOUBLE,double) default: ncstat = NC_EINVAL; THROWCHK(ncstat); goto fail; } value += nctypesizeof(srctype); memory += nctypesizeof(dsttype); } fail: return THROW(ncstat); }
NCerror dapcvtattrval3(nc_type etype, void* dst, NClist* src) { int i,ok; NCerror ncstat = NC_NOERR; unsigned int memsize = nctypesizeof(etype); unsigned int nvalues = nclistlength(src); char* dstmem = (char*)dst; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(src,i); ok = 0; switch (etype) { case NC_BYTE: { unsigned char* p = (unsigned char*)dstmem; ok = sscanf(s,"%hhu",p); } break; case NC_CHAR: { signed char* p = (signed char*)dstmem; ok = sscanf(s,"%c",p); } break; case NC_SHORT: { short* p = (short*)dstmem; ok = sscanf(s,"%hd",p); } break; case NC_INT: { int* p = (int*)dstmem; ok = sscanf(s,"%d",p); } break; case NC_FLOAT: { float* p = (float*)dstmem; ok = sscanf(s,"%g",p); } break; case NC_DOUBLE: { double* p = (double*)dstmem; ok = sscanf(s,"%lg",p); } break; case NC_UBYTE: { unsigned char* p = (unsigned char*)dstmem; ok = sscanf(s,"%hhu",p); } break; case NC_USHORT: { unsigned short* p = (unsigned short*)dstmem; ok = sscanf(s,"%hu",p); } break; case NC_UINT: { unsigned int* p = (unsigned int*)dstmem; ok = sscanf(s,"%u",p); } break; case NC_INT64: { long long* p = (long long*)dstmem; ok = sscanf(s,"%lld",p); } break; case NC_UINT64: { unsigned long long* p = (unsigned long long*)dstmem; ok = sscanf(s,"%llu",p); } break; case NC_STRING: case NC_URL: { char** p = (char**)dstmem; *p = nulldup(s); ok = 1; } break; default: PANIC1("unexpected nc_type: %d",(int)etype); } if(ok != 1) {ncstat = NC_EINVAL; goto done;} dstmem += memsize; } done: return THROW(ncstat); }
/* We are at a primitive variable or scalar that has no string dimensions. Extract the data. (This is way too complicated) */ static int extract( NCDAPCOMMON* nccomm, Getvara* xgetvar, CDFnode* xnode, DCEsegment* segment, size_t dimindex,/*notused*/ OClink conn, OCdatanode currentcontent, struct NCMEMORY* memory ) { OCerror ocstat = OC_NOERR; NCerror ncstat = NC_NOERR; size_t count,rank0; Dapodometer* odom = NULL; size_t externtypesize; size_t interntypesize; int requireconversion; char value[16]; ASSERT((segment != NULL)); requireconversion = conversionrequired(xgetvar->dsttype,xnode->etype); ASSERT(xgetvar->cache != NULL); externtypesize = nctypesizeof(xgetvar->dsttype); interntypesize = nctypesizeof(xnode->etype); rank0 = nclistlength(xnode->array.dimset0); #ifdef DEBUG2 fprintf(stderr,"moveto: primitive: segment=%s", dcetostring((DCEnode*)segment)); fprintf(stderr," iswholevariable=%d",xgetvar->cache->wholevariable); fprintf(stderr,"\n"); #endif if(rank0 == 0) {/* scalar */ char* mem = (requireconversion?value:memory->next); ASSERT(externtypesize <= sizeof(value)); /* Read the whole scalar directly into memory */ ocstat = oc_data_readscalar(conn,currentcontent,externtypesize,mem); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} if(requireconversion) { /* convert the value to external type */ ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} } memory->next += (externtypesize); } else if(xgetvar->cache->wholevariable) {/* && rank0 > 0 */ /* There are multiple cases, assuming no conversion required. 1) client is asking for whole variable => start=0, count=totalsize, stride=1 => read whole thing at one shot 2) client is asking for non-strided subset and edges are maximal => start=x, count=y, stride=1 => read whole subset at one shot 3) client is asking for strided subset or edges are not maximal => start=x, count=y, stride=s => we have to use odometer on leading prefix. If conversion required, then read one-by-one */ int safeindex = dcesafeindex(segment,0,rank0); assert(safeindex >= 0 && safeindex <= rank0); if(!requireconversion && safeindex == 0) { /* can read whole thing */ size_t internlen; count = dcesegmentsize(segment,0,rank0); /* how many to read */ internlen = interntypesize*count; /* Read the whole variable directly into memory.*/ ocstat = oc_data_readn(conn,currentcontent,dap_zero,count,internlen,memory->next); /* bump memory pointer */ memory->next += internlen; if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} } else if(!requireconversion && safeindex > 0 && safeindex < rank0) { size_t internlen; /* We need to build an odometer for the unsafe prefix of the slices */ odom = dapodom_fromsegment(segment,0,safeindex); count = dcesegmentsize(segment,safeindex,rank0); /* read in count chunks */ internlen = interntypesize*count; while(dapodom_more(odom)) { ocstat = oc_data_readn(conn,currentcontent,odom->index,count,internlen,memory->next); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} memory->next += internlen; dapodom_next(odom); } dapodom_free(odom); } else { /* Cover following cases, all of which require reading values one-by-one: 1. requireconversion 2. !requireconversion but safeindex == rank0 =>no safe indices Note that in case 2, we will do a no-op conversion. */ odom = dapodom_fromsegment(segment,0,rank0); while(dapodom_more(odom)) { char value[16]; /* Big enough to hold any numeric value */ ocstat = oc_data_readn(conn,currentcontent,odom->index,1,interntypesize,value); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} memory->next += (externtypesize); dapodom_next(odom); } dapodom_free(odom); } } else { /* !xgetvar->cache->wholevariable && rank0 > 0 */ /* This is the case where the constraint was applied by the server, so we just read it in, possibly with conversion */ if(requireconversion) { /* read one-by-one */ odom = dapodom_fromsegment(segment,0,rank0); while(dapodom_more(odom)) { char value[16]; /* Big enough to hold any numeric value */ ocstat = oc_data_readn(conn,currentcontent,odom->index,1,interntypesize,value); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} ncstat = dapconvert3(xnode->etype,xgetvar->dsttype,memory->next,value,1); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} memory->next += (externtypesize); dapodom_next(odom); } dapodom_free(odom); } else {/* Read straight to memory */ size_t internlen; count = dcesegmentsize(segment,0,rank0); /* how many to read */ internlen = interntypesize*count; ocstat = oc_data_readn(conn,currentcontent,dap_zero,count,internlen,memory->next); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} } } done: return THROW(ncstat); }
int nc3d_getvarmx(int ncid, int varid, const size_t *start, const size_t *edges, const ptrdiff_t* stride, const ptrdiff_t* map, void* data, nc_type dsttype0) { NCerror ncstat = NC_NOERR; int i; NC* drno; NC* substrate; NC3_INFO* substrate3; NCDAPCOMMON* dapcomm; NC_var* var; CDFnode* cdfvar; /* cdf node mapping to var*/ NClist* varnodes; nc_type dsttype; size_t externsize; size_t dimsizes[NC_MAX_VAR_DIMS]; Dapodometer* odom = NULL; unsigned int ncrank; NClist* ncdims = NULL; size_t nelems; #ifdef NEWVARM char* localcopy; /* of whole variable */ #endif ncstat = NC_check_id(ncid, (NC**)&drno); if(ncstat != NC_NOERR) goto done; dapcomm = (NCDAPCOMMON*)drno->dispatchdata; ncstat = NC_check_id(drno->substrate, &substrate); if(ncstat != NC_NOERR) goto done; substrate3 = (NC3_INFO*)drno->dispatchdata; var = NC_lookupvar(substrate3,varid); if(var == NULL) {ncstat = NC_ENOTVAR; goto done;} /* Locate var node via varid */ varnodes = dapcomm->cdf.ddsroot->tree->varnodes; for(i=0;i<nclistlength(varnodes);i++) { CDFnode* node = (CDFnode*)nclistget(varnodes,i); if(node->array.basevar == NULL && node->nctype == NC_Atomic && node->ncid == varid) { cdfvar = node; break; } } ASSERT((cdfvar != NULL)); ASSERT((strcmp(cdfvar->ncfullname,var->name->cp)==0)); if(nclistlength(cdfvar->array.dimsetplus) == 0) { /* The variable is a scalar; consequently, there is only one thing to get and only one place to put it. */ /* recurse with additional parameters */ return THROW(nc3d_getvarx(ncid,varid, NULL,NULL,NULL, data,dsttype0)); } dsttype = (dsttype0); /* Default to using the inquiry type for this var*/ if(dsttype == NC_NAT) dsttype = cdfvar->externaltype; /* Validate any implied type conversion*/ if(cdfvar->etype != dsttype && dsttype == NC_CHAR) { /* The only disallowed conversion is to/from char and non-byte numeric types*/ switch (cdfvar->etype) { case NC_STRING: case NC_URL: case NC_CHAR: case NC_BYTE: case NC_UBYTE: break; default: return THROW(NC_ECHAR); } } externsize = nctypesizeof(dsttype); /* Accumulate the dimension sizes and the total # of elements */ ncdims = cdfvar->array.dimsetall; ncrank = nclistlength(ncdims); nelems = 1; /* also Compute the number of elements being retrieved */ for(i=0;i<ncrank;i++) { CDFnode* dim = (CDFnode*)nclistget(ncdims,i); dimsizes[i] = dim->dim.declsize; nelems *= edges[i]; } /* Originally, this code repeatedly extracted single values using get_var1. In an attempt to improve performance, I have converted to reading the whole variable at once and walking it locally. */ #ifdef NEWVARM localcopy = (char*)malloc(nelems*externsize); /* We need to use the varieties of get_vars in order to properly do conversion to the external type */ switch (dsttype) { case NC_CHAR: ncstat = nc_get_vars_text(ncid,varid,start, edges, stride, (char*)localcopy); break; case NC_BYTE: ncstat = nc_get_vars_schar(ncid,varid,start, edges, stride, (signed char*)localcopy); break; case NC_SHORT: ncstat = nc_get_vars_short(ncid,varid, start, edges, stride, (short*)localcopy); break; case NC_INT: ncstat = nc_get_vars_int(ncid,varid,start, edges, stride, (int*)localcopy); break; case NC_FLOAT: ncstat = nc_get_vars_float(ncid,varid,start, edges, stride, (float*)localcopy); break; case NC_DOUBLE: ncstat = nc_get_vars_double(ncid,varid, start, edges, stride, (double*)localcopy); break; default: break; } odom = dapodom_new(ncrank,start,edges,stride,NULL); /* Walk the local copy */ for(i=0;i<nelems;i++) { size_t voffset = dapodom_varmcount(odom,map,dimsizes); void* dataoffset = (void*)(((char*)data) + (externsize*voffset)); char* localpos = (localcopy + externsize*i); /* extract the indexset'th value from local copy */ memcpy(dataoffset,(void*)localpos,externsize); /* fprintf(stderr,"new: %lu -> %lu %f\n", (unsigned long)(i), (unsigned long)voffset, *(float*)localpos); */ dapodom_next(odom); } #else odom = dapodom_new(ncrank,start,edges,stride,NULL); while(dapodom_more(odom)) { size_t* indexset = odom->index; size_t voffset = dapodom_varmcount(odom,map,dimsizes); char internalmem[128]; char externalmem[128]; void* dataoffset = (void*)(((char*)data) + (externsize*voffset)); /* get the indexset'th value using variable's internal type */ ncstat = nc_get_var1(ncid,varid,indexset,(void*)&internalmem); if(ncstat != NC_NOERR) goto done; /* Convert to external type */ ncstat = dapconvert3(cdfvar->etype,dsttype,externalmem,internalmem); if(ncstat != NC_NOERR) goto done; memcpy(dataoffset,(void*)externalmem,externsize); /* fprintf(stderr,"old: %lu -> %lu %f\n", (unsigned long)dapodom_count(odom), (unsigned long)voffset, *(float*)externalmem); */ dapodom_next(odom); } #endif done: return ncstat; }
NCerror dapcvtattrval(nc_type etype, void* dst, NClist* src) { int i,ok; NCerror ncstat = NC_NOERR; unsigned int memsize = nctypesizeof(etype); unsigned int nvalues = nclistlength(src); char* dstmem = (char*)dst; for(i=0;i<nvalues;i++) { char* s = (char*)nclistget(src,i); size_t slen = strlen(s); int nread = 0; /* # of chars read by sscanf */ ok = 0; switch (etype) { case NC_BYTE: { char tmp[128]; unsigned char* p = (unsigned char*)dstmem; #ifdef _MSC_VER ok = sscanf(s,"%hC%n",p,&nread); _ASSERTE(_CrtCheckMemory()); #else ok = sscanf(s,"%hhu%n",p,&nread); #endif } break; case NC_CHAR: { signed char* p = (signed char*)dstmem; ok = sscanf(s,"%c%n",p,&nread); } break; case NC_SHORT: { short* p = (short*)dstmem; ok = sscanf(s,"%hd%n",p,&nread); } break; case NC_INT: { int* p = (int*)dstmem; ok = sscanf(s,"%d%n",p,&nread); } break; case NC_FLOAT: { float* p = (float*)dstmem; ok = sscanf(s,"%g%n",p,&nread); } break; case NC_DOUBLE: { double* p = (double*)dstmem; ok = sscanf(s,"%lg%n",p,&nread); } break; case NC_UBYTE: { unsigned char* p = (unsigned char*)dstmem; #ifdef _MSC_VER ok = sscanf(s, "%hc%n", p,&nread); _ASSERTE(_CrtCheckMemory()); #else ok = sscanf(s,"%hhu%n",p,&nread); #endif } break; case NC_USHORT: { unsigned short* p = (unsigned short*)dstmem; ok = sscanf(s,"%hu%n",p,&nread); } break; case NC_UINT: { unsigned int* p = (unsigned int*)dstmem; ok = sscanf(s,"%u%n",p,&nread); } break; case NC_INT64: { long long* p = (long long*)dstmem; #ifdef _MSC_VER ok = sscanf(s, "%I64d%n", p,&nread); #else ok = sscanf(s,"%lld%n",p,&nread); #endif } break; case NC_UINT64: { unsigned long long* p = (unsigned long long*)dstmem; ok = sscanf(s,"%llu%n",p,&nread); } break; case NC_STRING: case NC_URL: { char** p = (char**)dstmem; *p = nulldup(s); ok = 1; } break; default: PANIC1("unexpected nc_type: %d",(int)etype); } if(ok != 1 || nread != slen) {ncstat = NC_EINVAL; goto done;} dstmem += memsize; } done: return THROW(ncstat); }
int main(int argc, char **argv) { int c, stat; int ncid; NChdr* hdr; init(); opterr=1; while ((c = getopt(argc, argv, "dvau:D:l:p:c:t:R:")) != EOF) { switch(c) { case 'v': verbose=1; break; case 'd': debug=1; break; case 'D': debug=atoi(optarg); break; default: break; } } if(debug > 0) {ocdebug = debug;} argc -= optind; argv += optind; if(argc > 0 && fileurl == NULL) fileurl = nulldup(argv[0]); if(fileurl == NULL) fileurl = getenv("FILEURL"); if(fileurl == NULL) { fprintf(stderr,"no file url specified\n"); usage(); } if(verbose) dumpflags(); if(verbose) {fprintf(stdout,"initializing\n"); fflush(stdout);} stat = nc_open(fileurl,NC_NOWRITE,&ncid); check_err(stat); /* dump meta data */ stat = dumpmetadata(ncid,&hdr); check_err(stat); /* Get data */ if(1) { int i,j,limited; size_t start[NC_MAX_VAR_DIMS]; size_t count[NC_MAX_VAR_DIMS]; /* Walk each variable */ for(i=0;i<hdr->nvars;i++) { Var* var = &hdr->vars[i]; size_t nelems = 1; limited = 0; for(j=0;j<var->ndims;j++) { start[j] = 0; assert(var->dimids[j] == hdr->dims[var->dimids[j]].dimid); count[j] = hdr->dims[var->dimids[j]].size; /* put a limit on each count */ if(count[j] > LIMIT) {count[j] = LIMIT; limited = 1;} nelems *= count[j]; } if(nelems > 0) { size_t typesize = nctypesizeof(var->nctype); size_t memsize = typesize*nelems; void* memory = malloc(memsize); fprintf(stdout,"%s: size=%lu (%lu * %lu) ; ", var->name, (unsigned long)memsize, (unsigned long)typesize, (unsigned long)nelems); fflush(stdout); stat = nc_get_vara(ncid,var->varid,start,count,memory); check_err(stat); /* dump memory */ switch (var->nctype){ case NC_CHAR: fprintf(stdout,"\""); fflush(stdout); dumpchars(nelems,memory); fprintf(stdout,"\""); break; default: for(j=0;j<nelems;j++) { if(j > 0) fprintf(stdout," "); dumpdata1(var->nctype,j,memory); } } if(limited) fprintf(stdout,"..."); fprintf(stdout,"\n"); free(memory); } else fprintf(stdout,"%s: no data\n",var->name); } fprintf(stdout,"\n"); } nc_close(ncid); return 0; }