/********************************************************************* * Copyright 1993, UCAR/Unidata * See netcdf/COPYRIGHT file for copying and redistribution conditions. * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapattr3.c,v 1.14 2009/12/03 03:42:38 dmh Exp $ *********************************************************************/ #include "ncdap3.h" #define OCHECK(exp) if((ocstat = (exp))) goto done; /* Forward */ static NCerror buildattribute(char*,nc_type,NClist*,NCattribute**); static int mergedas1(OCconnection, CDFnode* dds, OCobject das); static NCerror dodsextra3(NCDAPCOMMON*, CDFnode*, NClist*); static int isglobalname3(char* name); #ifdef IGNORE /* Extract attributes from the underlying oc objects and rematerialize them with the CDFnodes. */ NCerror dapmerge3(NCDAPCOMMON* nccomm, CDFnode* node) { unsigned int i; char* aname; unsigned int nvalues,nattrs; void* values; OCtype atype; OCerror ocstat = OC_NOERR; NCerror ncstat = NC_NOERR; NCattribute* att; if(node->dds == OCNULL) goto done; OCHECK(oc_inq_nattr(nccomm->conn,node->dds,&nattrs)); if(nattrs == 0) goto done; if(node->attributes == NULL) node->attributes = nclistnew(); for(i=0;iconn,node->dds,i, &aname, &atype, &nvalues, &values); if(ocstat != OC_NOERR) continue; /* ignore */ if(aname == NULL || nvalues == 0 || values == NULL) continue; /* nothing to do */ ncstat = buildattribute(aname,octypetonc(atype), nvalues,values,&att); if(ncstat == NC_NOERR) nclistpush(node->attributes,(ncelem)att); efree(aname); oc_attr_reclaim(atype,nvalues,values); } done: if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); } #endif static NCerror buildattribute(char* name, nc_type ptype, NClist* values, NCattribute** attp) { NCerror ncstat = NC_NOERR; NCattribute* att; att = (NCattribute*)emalloc(sizeof(NCattribute)); MEMCHECK(att,NC_ENOMEM); att->name = nulldup(name); att->etype = ptype; att->values = values; if(attp) *attp = att; return THROW(ncstat); } #ifdef IGNORE 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; } #endif /* Duplicate the oc merge das and dds code, but modify to capture such things as "strlen" and "dimname". */ int dapmerge3(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCobject dasroot) { unsigned int i,j; NCerror ncerr = NC_NOERR; OCerror ocstat = OC_NOERR; OCconnection conn = nccomm->oc.conn; unsigned int nsubnodes, nobjects; OCobject* dasobjects = NULL; NClist* dasglobals = nclistnew(); NClist* dodsextra = nclistnew(); NClist* dasnodes = nclistnew(); NClist* varnodes = nclistnew(); NClist* allddsnodes = ddsroot->tree->nodes; if(ddsroot == NULL || dasroot == NULL) return NC_NOERR; nobjects = oc_inq_nobjects(conn,dasroot); dasobjects = oc_inq_objects(conn,dasroot); /* 1. collect all the relevant DAS nodes; namely those that contain at least one attribute value. Simultaneously look for potential ambiguities if found; complain but continue: result are indeterminate. also collect globals and DODS_EXTRAs separately*/ for(i=0;inctype == NC_Primitive) nclistpush(varnodes,(ncelem)dds); } /* 3. For each das node, lncate matching DDS node(s) and attach attributes to the DDS node(s). Match means: 1. DAS->fullname :: DDS->fullname 2. DAS->name :: DDS->fullname (support DAS names with embedded '.' 3. DAS->name :: DDS->name */ for(i=0;iname)==0) { mergedas1(conn,dds,das); /* remove from dasnodes list*/ nclistset(dasnodes,i,(ncelem)NULL); } efree(ddsfullname); } efree(ocfullname); efree(ocbasename); } /* 4. Assign globals*/ for(i=0;i 0) dodsextra3(nccomm,ddsroot,dodsextra); done: /* cleanup*/ efree(dasobjects); nclistfree(dasglobals); nclistfree(dasnodes); nclistfree(dodsextra); nclistfree(varnodes); if(ocstat != OC_NOERR) ncerr = ocerrtoncerr(ocstat); return THROW(ncerr); } static int mergedas1(OCconnection conn, CDFnode* dds, OCobject das) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; unsigned int i,j; unsigned int nsubnodes; OCobject* subnodes = NULL; OCobject* dodsnodes = NULL; unsigned int ndodsnodes; if(dds == NULL || das == OCNULL) return NC_NOERR; /* nothing to do */ if(dds->attributes == NULL) dds->attributes = nclistnew(); /* assign the simple attributes in the das set to this dds node*/ OCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); OCHECK(oc_inq_subnodes(conn,das,&subnodes)); for(i=0;iattributes,(ncelem)att); } else if(octype == OC_Attributeset && strcmp(ocname,"DODS")==0) { /* This is a DODS special attribute set */ OCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes)); OCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes)); for(j=0;j 0) { OCHECK(oc_inq_dasattr(conn,dodsnode,0,NULL,&stringval)); if(0==sscanf(stringval,"%u",&maxstrlen)) maxstrlen = 0; efree(stringval); } dds->dodsspecial.maxstrlen = maxstrlen; #ifdef DEBUG fprintf(stderr,"%s.maxstrlen=%d\n",dds->name,(int)dds->dodsspecial.maxstrlen); #endif } else if(strcmp(dodsname,"dimName")==0) { if(ocnvalues > 0) { OCHECK(oc_inq_dasattr(conn,dodsnode,0,NULL, &dds->dodsspecial.dimname)); #ifdef DEBUG fprintf(stderr,"%s.dimname=%s\n",dds->name,dds->dodsspecial.dimname); #endif } else dds->dodsspecial.dimname = NULL; } /* else ignore */ efree(dodsname); } efree(dodsnodes); } /* else ignore */ efree(ocname); } done: efree(subnodes); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); } static NCerror dodsextra3(NCDAPCOMMON* nccomm, CDFnode* root, NClist* dodsextra) { int i,j; OCtype octype; NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; OCconnection conn = nccomm->oc.conn; for(i=0;i 0) { OCHECK(oc_inq_dasattr(conn,extranode,0,NULL,&stringval)); nccomm->cdf.recorddim = stringval; } efree(dodsname); } efree(dodsnodes); } done: return ncstat; } static int isglobalname3(char* name) { int len = strlen(name); int glen = strlen("global"); char* p; if(len < glen) return 0; p = name + (len - glen); if(strcasecmp(p,"global") != 0) return 0; return 1; }