/********************************************************************* * 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(NCDAPCOMMON*, OCconnection, CDFnode* dds, OCobject das); static int isglobalname3(char* name); static NCerror buildattribute(char* name, nc_type ptype, NClist* values, NCattribute** attp) { NCerror ncstat = NC_NOERR; NCattribute* att; att = (NCattribute*)calloc(1,sizeof(NCattribute)); MEMCHECK(att,NC_ENOMEM); att->name = nulldup(name); att->etype = ptype; att->values = values; if(attp) *attp = att; return THROW(ncstat); } /* Given a das attribute walk it to see if it has at least 1 actual attribute (no recursion) */ static int hasattribute3(OCconnection conn, OCobject dasnode) { int i; OCerror ocstat = OC_NOERR; int tf = 0; /* assume false */ unsigned int nsubnodes; OCtype ocsubtype; OCobject* subnodes = NULL; OCHECK(oc_inq_class(conn,dasnode,&ocsubtype)); if(ocsubtype == OC_Attribute) return 1; /* this is an attribute */ ASSERT((ocsubtype == OC_Attributeset)); OCHECK(oc_inq_nsubnodes(conn,dasnode,&nsubnodes)); OCHECK(oc_inq_subnodes(conn,dasnode,&subnodes)); for(i=0;ioc.conn; unsigned int nsubnodes, nobjects; OCobject* dasobjects = NULL; NClist* dasglobals = nclistnew(); NClist* dasnodes = nclistnew(); NClist* dodsextra = 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_EXTRA 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 4. special case for DODS. Apply 1-3 on DODS parent. */ for(i=0;iocname)==0) { mergedas1(nccomm,conn,dds,das); /* remove from dasnodes list*/ nclistset(dasnodes,i,(ncelem)NULL); } nullfree(ddsfullname); } nullfree(ocfullname); nullfree(ocbasename); } /* 4. Assign globals */ for(i=0;iattributes == 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 || strcmp(ocname,"DODS_EXTRA")==0)) { /* Turn the DODS special attributes into into special attributes for dds node */ OCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes)); OCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes)); for(j=0;jinvisible = 1; nclistpush(dds->attributes,(ncelem)att); /* Define extra semantics associated with DODS and DODS_EXTRA attribute */ if(strcmp(dodsname,"strlen")==0) { unsigned int maxstrlen = 0; if(nclistlength(stringvalues) > 0) { char* stringval = (char*)nclistget(stringvalues,0); if(0==sscanf(stringval,"%u",&maxstrlen)) maxstrlen = 0; } dds->dodsspecial.maxstrlen = maxstrlen; #ifdef DEBUG fprintf(stderr,"%s.maxstrlen=%d\n",dds->ocname,(int)dds->dodsspecial.maxstrlen); #endif } else if(strcmp(dodsname,"dimName")==0) { if(nclistlength(stringvalues) > 0) { char* stringval = (char*)nclistget(stringvalues,0); dds->dodsspecial.dimname = nulldup(stringval); #ifdef DEBUG fprintf(stderr,"%s.dimname=%s\n",dds->ocname,dds->dodsspecial.dimname); #endif } else dds->dodsspecial.dimname = NULL; } else if(strcmp(dodsname,"Unlimited_Dimension")==0) { if(nccomm->cdf.recorddimname != NULL) { nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications"); } else if(nclistlength(stringvalues) > 0) { char* stringval = (char*)nclistget(stringvalues,0); nccomm->cdf.recorddimname = nulldup(stringval); #ifdef DEBUG fprintf(stderr,"%s.Unlimited_Dimension=%s\n",dds->ocname,nccomm->cdf.recorddimname); #endif } } /* else ignore */ nullfree(dodsname); } nullfree(dodsnodes); } nullfree(ocname); } done: nullfree(subnodes); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(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; }