OCerror ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCflags flags, OCnode** rootp) { OCtree* tree = NULL; OCnode* root = NULL; OCerror stat = OC_NOERR; tree = (OCtree*)ocmalloc(sizeof(OCtree)); MEMCHECK(tree,OC_ENOMEM); memset((void*)tree,0,sizeof(OCtree)); tree->dxdclass = kind; tree->state = state; tree->constraint = constraintescape(constraint); if(tree->constraint == NULL) tree->constraint = nulldup(constraint); /* Set curl properties: pwd, flags, proxies, ssl */ if((stat=ocset_user_password(state))!= OC_NOERR) goto fail; if((stat=ocset_curl_flags(state)) != OC_NOERR) goto fail; if((stat=ocset_proxy(state)) != OC_NOERR) goto fail; if((stat=ocset_ssl(state)) != OC_NOERR) goto fail; if(state->usercurl) state->usercurl((void*)state->curl,state->usercurldata); ocbytesclear(state->packet); switch (kind) { case OCDAS: stat = readDAS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDAS; } break; case OCDDS: stat = readDDS(state,tree); if(stat == OC_NOERR) { tree->text = ocbytesdup(state->packet); if(tree->text == NULL) stat = OC_EDDS; } break; case OCDATADDS: if((flags & OCONDISK) != 0) {/* store in file */ /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {OCTHROWCHK(stat); goto fail;} stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinfile(state,tree,flags); } } else { /*inmemory*/ stat = readDATADDS(state,tree,flags); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractddsinmemory(state,tree,flags); } } break; default: break; }/*switch*/ if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oclog(OCLOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oclog(OCLOGWARN,"oc_open: Could not read url"); } goto fail; } tree->nodes = NULL; stat = DAPparse(state,tree,tree->text); /* Check and report on an error return from the server */ if(stat == OC_EDAPSVC && state->error.code != NULL) { oclog(OCLOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {OCTHROWCHK(stat); goto fail;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {OCTHROWCHK(stat=OC_EDAS); goto fail;} break; case OCDDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDDS); goto fail;} break; case OCDATADDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDATADDS); goto fail;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to mark those that are cacheable */ ocmarkcacheable(state,root); /* Process ocnodes to handle various semantic issues*/ occomputesemantics(tree->nodes); } /* Process ocnodes to compute name info*/ occomputefullnames(tree->root); if(kind == OCDATADDS) { if((flags & OCONDISK) != 0) { tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod); } else { #ifdef OCDEBUG fprintf(stderr,"ocfetch.datadds.memory: datasize=%lu bod=%lu\n", (unsigned long)tree->data.datasize,(unsigned long)tree->data.bod); #endif /* Switch to zero based memory */ tree->data.xdrs = xxdr_memcreate(tree->data.memory,tree->data.datasize,tree->data.bod); } MEMCHECK(tree->data.xdrs,OC_ENOMEM); /* Do a quick check to see if server returned an ERROR {} at the beginning of the data */ if(dataError(tree->data.xdrs,state)) { stat = OC_EDATADDS; oclog(OCLOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); goto fail; } /* Compile the data into a more accessible format */ stat = occompile(state,tree->root); if(stat != OC_NOERR) goto fail; } /* Put root into the state->trees list */ oclistpush(state->trees,(void*)root); if(rootp) *rootp = root; return stat; fail: if(root != NULL) ocroot_free(root); else if(tree != NULL) octree_free(tree); return OCTHROW(stat); }
/* Do a simple uri parse: return 0 if fail, 1 otherwise*/ int ncuriparse(const char* uri0, NCURI** durip) { NCURI* duri = NULL; char* uri = NULL; char* p; struct NC_ProtocolInfo* proto; int i,nprotos; /* accumulate parse points*/ char* protocol = NULL; char* host = NULL; char* port = NULL; char* constraint = NULL; char* user = NULL; char* pwd = NULL; char* file = NULL; char* prefixparams = NULL; char* suffixparams = NULL; if(uri0 == NULL || strlen(uri0) == 0) {THROW(1); goto fail;} duri = (NCURI*)calloc(1,sizeof(NCURI)); if(duri == NULL) {THROW(2); goto fail;} /* save original uri */ duri->uri = nulldup(uri0); /* make local copy of uri */ uri = (char*)malloc(strlen(uri0)+1+PADDING); /* +1 for trailing null, +PADDING for shifting */ if(uri == NULL) {THROW(3); goto fail;} /* strings will be broken into pieces with intermixed '\0; characters; first char is guaranteed to be '\0' */ duri->strings = uri; uri++; /* dup the incoming url */ strcpy(uri,uri0); /* Walk the uri and do the following: 1. remove all whitespace 2. remove all '\\' (Temp hack to remove escape characters inserted by Windows or MinGW) */ for(p=uri;*p;p++) { if(*p == '\\' || *p < ' ') nclshift1(p); /* compress out */ } p = uri; /* break up the uri string into big chunks: prefixparams, protocol, host section, and the file section (i.e. remainder) */ /* collect any prefix bracketed parameters */ if(*p == LBRACKET) { prefixparams = p+1; /* find end of the clientparams; convert LB,RB to '&' */ for(;*p;p++) { if(p[0] == RBRACKET && p[1] == LBRACKET) { p[0] = '&'; nclshift1(p+1); } else if(p[0] == RBRACKET && p[1] != LBRACKET) break; } if(*p == 0) {THROW(4); goto fail; /* malformed client params*/} terminate(p); /* nul term the prefixparams (overwrites the final RBRACKET) */ p++; /* move past the final RBRACKET */ } /* Tag the protocol */ protocol = p; p = strchr(p,':'); if(!p) {THROW(5); goto fail;} terminate(p); /*overwrite colon*/ p++; /* skip the colon */ /* verify that the uri starts with an acceptable protocol*/ nprotos = (sizeof(legalprotocols)/sizeof(struct NC_ProtocolInfo)); proto = NULL; for(i=0;i<nprotos;i++) { if(strcmp(protocol,legalprotocols[i].name)==0) { proto = &legalprotocols[i]; break; } } if(proto == NULL) {THROW(6); goto fail; /* illegal protocol*/} /* skip // */ if(p[0] != '/' && p[1] != '/') {THROW(7); goto fail;} p += 2; /* If this is all we have (proto://) then fail */ if(*p == EOFCHAR) {THROW(8); goto fail;} /* establish the start of the file section */ if(proto->filelike) {/* everything after proto:// */ file = p; host = NULL; /* and no host section */ } else { /*!proto->filelike => This means there should be a host section */ /* locate the end of the host section and therefore the start of the file section */ host = p; p = nclocate(p,"/?#"); if(p == NULL) { file = endof(host); /* there is no file section */ } else { ncrshift1(p); /* make room to terminate the host section without overwriting the leading character */ terminate(p); /* terminate the host section */ file = p+1; /* +1 becauseof the shift */ } } /* If you shift in the code below, you must reset file beginning */ if(host != NULL) {/* Parse the host section */ /* Check for leading user:pwd@ */ p = strchr(host,'@'); if(p) { if(p == host) {THROW(9); goto fail; /* we have proto://@ */} user = host; terminate(p); /* overwrite '@' */ host = p+1; /* start of host ip name */ p = strchr(user,':'); if(p == NULL) {THROW(10); goto fail; /* malformed */} terminate(p); /*overwrite colon */ pwd = p+1; } /* extract host and port */ p = host; p = strchr(p,':'); if(p != NULL) { terminate(p); p++; port = p; if(*port == EOFCHAR) {THROW(11); goto fail; /* we have proto://...:/ */} /* The port must look something like a number */ for(;*p;p++) { if(strchr("0123456789-",*p) == NULL) {THROW(12); goto fail; /* probably not a real port, fail */} } } /* else *p == NULL */ /* check for empty host section */ if(*host == EOFCHAR) {THROW(13); goto fail;} } assert(file != NULL); p = file; /* find the end of the file section and the start of the constraints and/or suffixparams */ p = nclocate(p,"?#"); if(p != NULL) { /* we have constraint and/or suffixparams */ char* fileend = p; /* save the end of the file section */ char* constraintend = NULL; if(*p == '?') constraint = p+1; else constraint = NULL; p = strchr(p,'#'); /* may repeat effect of nclocate above */ if(p != NULL) { constraintend = p; suffixparams = p+1; } else suffixparams = NULL; /* Ok, terminate the pieces */ terminate(fileend); /* terminate file section */ if(constraint != NULL && constraintend != NULL) terminate(constraintend); /* Suffix params are already terminated since they should be the last section of the original url */ } /* check for empty sections */ if(file != NULL && *file == EOFCHAR) file = NULL; /* empty file section */ if(constraint != NULL && *constraint == EOFCHAR) constraint = NULL; /* empty constraint section */ if(suffixparams != NULL && *suffixparams == EOFCHAR) suffixparams = NULL; /* empty suffixparams section */ if(suffixparams != NULL) { /* there really are suffix params; so rebuild the suffix params */ if(*suffixparams == LBRACKET) suffixparams++; p = suffixparams; /* convert RBRACKET LBRACKET to '&' */ for(;*p;p++) { if(p[0] == RBRACKET && p[1] == LBRACKET) { p[0] = '&'; nclshift1(p+1); } else if(p[0] == RBRACKET && p[1] != LBRACKET) { /* terminate suffixparams */ *p = EOFCHAR; break; } } if(*suffixparams == EOFCHAR) suffixparams = NULL; /* suffixparams are empty */ } /* do last minute empty check */ if(protocol != NULL && *protocol == EOFCHAR) protocol = NULL; if(user != NULL && *user == EOFCHAR) user = NULL; if(pwd != NULL && *pwd == EOFCHAR) pwd = NULL; if(host != NULL && *host == EOFCHAR) host = NULL; if(port != NULL && *port == EOFCHAR) port = NULL; if(file != NULL && *file == EOFCHAR) file = NULL; if(constraint != NULL && *constraint == EOFCHAR) constraint = NULL; /* assemble the component pieces */ duri->protocol = protocol; duri->user = user; duri->password = pwd; duri->host = host; duri->port = port; duri->file = file; ncurisetconstraints(duri,constraint); /* concat suffix and prefix params */ if(prefixparams != NULL || suffixparams != NULL) { int plen = prefixparams ? strlen(prefixparams) : 0; int slen = suffixparams ? strlen(suffixparams) : 0; int space = plen + slen + 1; /* add 1 for an extra ampersand if both are defined */ space++; duri->params = (char*)malloc(space); duri->params[0] = EOFCHAR; /* so we can use strcat */ if(plen > 0) { strcat(duri->params,prefixparams); if(slen > 0) strcat(duri->params,"&"); } if(slen > 0) strcat(duri->params,suffixparams); } #ifdef NCXDEBUG { fprintf(stderr,"duri:"); fprintf(stderr," params=|%s|",FIX(duri->params)); fprintf(stderr," protocol=|%s|",FIX(duri->protocol)); fprintf(stderr," host=|%s|",FIX(duri->host)); fprintf(stderr," port=|%s|",FIX(duri->port)); fprintf(stderr," file=|%s|",FIX(duri->file)); fprintf(stderr," constraint=|%s|",FIX(duri->constraint)); fprintf(stderr,"\n"); } #endif if(durip != NULL) *durip = duri; else ncurifree(duri); return 1; fail: if(duri != NULL) { ncurifree(duri); } return 0; }
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; }
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; }
/* See ncd4dispatch.c for other version */ int NCCR_open(const char * path, int mode, int basepe, size_t *chunksizehintp, int useparallel, void* mpidata, NC_Dispatch* dispatch, NC** ncpp) { NCerror ncstat = NC_NOERR; NC_URL* tmpurl; NCCR* nccr = NULL; /* reuse the ncdap3 structure*/ NCCDMR* cdmr = NULL; NC_HDF5_FILE_INFO_T* h5 = NULL; NC_GRP_INFO_T *grp = NULL; int ncid = -1; int fd; char* tmpname = NULL; NClist* shows; bytes_t buf; long filetime; ast_runtime* rt = NULL; ast_err aststat = AST_NOERR; Header* hdr = NULL; LOG((1, "nc_open_file: path %s mode %d", path, mode)); if(nc_urlparse(path,&tmpurl) != NC_NOERR) PANIC("libcdmr: non-url path"); nc_urlfree(tmpurl); /* no longer needed */ /* Check for legal mode flags */ if((mode & NC_WRITE) != 0) ncstat = NC_EINVAL; else if(mode & (NC_WRITE|NC_CLOBBER)) ncstat = NC_EPERM; if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} mode = (mode & ~(NC_MPIIO | NC_MPIPOSIX)); /* Despite the above check, we want the file to be initially writable */ mode |= (NC_WRITE|NC_CLOBBER); /* Use NCCR code to establish a pseudo file */ tmpname = nulldup(PSEUDOFILE); fd = mkstemp(tmpname); if(fd < 0) {THROWCHK(errno); goto done;} /* Now, use the file to create the hdf5 file */ ncstat = NC4_create(tmpname,NC_NETCDF4|NC_CLOBBER, 0,0,NULL,0,NULL,dispatch,(NC**)&nccr); ncid = nccr->info.ext_ncid; /* unlink the temp file so it will automatically be reclaimed */ unlink(tmpname); free(tmpname); /* Avoid fill */ dispatch->set_fill(ncid,NC_NOFILL,NULL); if(ncstat) {THROWCHK(ncstat); goto done;} /* Find our metadata for this file. */ ncstat = nc4_find_nc_grp_h5(ncid, (NC_FILE_INFO_T**)&nccr, &grp, &h5); if(ncstat) {THROWCHK(ncstat); goto done;} /* Setup tentative NCCR state*/ nccr->info.dispatch = dispatch; cdmr = (NCCDMR*)calloc(1,sizeof(NCCDMR)); if(cdmr == NULL) {ncstat = NC_ENOMEM; goto done;} nccr->cdmr = cdmr; nccr->cdmr->controller = (NC*)nccr; nccr->cdmr->urltext = nulldup(path); nc_urlparse(nccr->cdmr->urltext,&nccr->cdmr->url); /* Create the curl connection (does not make the server connection)*/ ncstat = nccr_curlopen(&nccr->cdmr->curl.curl); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} shows = nc_urllookup(nccr->cdmr->url,"show"); if(nc_urllookupvalue(shows,"fetch")) nccr->cdmr->controls |= SHOWFETCH; /* Parse the projection */ /* fetch meta data */ buf = bytes_t_null; NCbytes* completeurl = ncbytesnew(); ncbytescat(completeurl,nccr->cdmr->url->url); ncbytescat(completeurl,"?req=header"); ncstat = nccr_fetchurl(nccr->cdmr->curl.curl,ncbytescontents(completeurl), &buf,&filetime); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Parse the meta data */ ncstat = nccr_decodeheader(&buf,&hdr); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} if(buf.bytes != NULL) free(buf.bytes); /* Compute various things about the Header tree */ /* Collect all nodes and fill in the CRnode part*/ cdmr->nodeset = nclistnew(); ncstat = nccr_walk_Header(hdr,cdmr->nodeset); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Compute the pathnames */ ncstat = nccr_compute_pathnames(cdmr->nodeset); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Map dimension references to matching declaration */ ncstat = nccr_map_dimensions(cdmr->nodeset); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Replace dimension references with matching declaration */ nccr_deref_dimensions(cdmr->nodeset); /* Elide any variables not in the url projection */ ncstat = nccr_elide_vars(cdmr); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* build the meta data */ ncstat = nccr_buildnc(nccr,hdr); if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;} /* Mark as no longer indef and no longer writable*/ h5->flags &= ~(NC_INDEF); h5->no_write = 1; done: if(aststat != AST_NOERR) {ncstat = nccr_cvtasterr(aststat);} if(ncstat) { if(nccr != NULL) { int ncid = nccr->info.ext_ncid; NCCR_abort(ncid); } } else { if(ncpp) *ncpp = (NC*)nccr; } return THROW(ncstat); }
static void dcedump(DCEnode* node, NCbytes* buf) { int i; char tmp[1024]; if(buf == NULL) return; if(node == NULL) {ncbytescat(buf,"<null>"); return;} switch (node->sort) { case CES_SLICE: { DCEslice* slice = (DCEslice*)node; size_t last = (slice->first+slice->length)-1; if(slice->count == 1) { snprintf(tmp,sizeof(tmp),"[%lu%s]", (unsigned long)slice->first,dimdecl(slice->declsize)); } else if(slice->stride == 1) { snprintf(tmp,sizeof(tmp),"[%lu:%lu%s]", (unsigned long)slice->first, (unsigned long)last, dimdecl(slice->declsize)); } else { snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu%s]", (unsigned long)slice->first, (unsigned long)slice->stride, (unsigned long)last, dimdecl(slice->declsize)); } ncbytescat(buf,tmp); } break; case CES_SEGMENT: { DCEsegment* segment = (DCEsegment*)node; int rank = segment->rank; char* name = (segment->name?segment->name:"<unknown>"); name = nulldup(name); ncbytescat(buf,name); nullfree(name); if(dceverbose && dceiswholesegment(segment)) ncbytescat(buf,"*"); if(dceverbose || !dceiswholesegment(segment)) { for(i=0;i<rank;i++) { DCEslice* slice = segment->slices+i; dcetobuffer((DCEnode*)slice,buf); } } } break; case CES_VAR: { DCEvar* var = (DCEvar*)node; dcelisttobuffer(var->segments,buf,"."); } break; case CES_FCN: { DCEfcn* fcn = (DCEfcn*)node; ncbytescat(buf,fcn->name); ncbytescat(buf,"("); dcelisttobuffer(fcn->args,buf,","); ncbytescat(buf,")"); } break; case CES_CONST: { DCEconstant* value = (DCEconstant*)node; switch (value->discrim) { case CES_STR: ncbytescat(buf,value->text); break; case CES_INT: snprintf(tmp,sizeof(tmp),"%lld",value->intvalue); ncbytescat(buf,tmp); break; case CES_FLOAT: snprintf(tmp,sizeof(tmp),"%g",value->floatvalue); ncbytescat(buf,tmp); break; default: assert(0); } } break; case CES_VALUE: { DCEvalue* value = (DCEvalue*)node; switch (value->discrim) { case CES_CONST: dcetobuffer((DCEnode*)value->constant,buf); break; case CES_VAR: dcetobuffer((DCEnode*)value->var,buf); break; case CES_FCN: dcetobuffer((DCEnode*)value->fcn,buf); break; default: assert(0); } } break; case CES_PROJECT: { DCEprojection* target = (DCEprojection*)node; switch (target->discrim) { case CES_VAR: dcetobuffer((DCEnode*)target->var,buf); break; case CES_FCN: dcetobuffer((DCEnode*)target->fcn,buf); break; default: assert(0); } } break; case CES_SELECT: { DCEselection* sel = (DCEselection*)node; dcetobuffer((DCEnode*)sel->lhs,buf); if(sel->operator == CES_NIL) break; ncbytescat(buf,opstrings[(int)sel->operator]); if(nclistlength(sel->rhs) > 1) ncbytescat(buf,"{"); dcelisttobuffer(sel->rhs,buf,","); if(nclistlength(sel->rhs) > 1) ncbytescat(buf,"}"); } break; case CES_CONSTRAINT: { DCEconstraint* con = (DCEconstraint*)node; if(con->projections != NULL && nclistlength(con->projections) > 0) { dcelisttobuffer(con->projections,buf,","); } if(con->selections != NULL && nclistlength(con->selections) > 0) { ncbytescat(buf,"&"); /* because & is really a prefix */ dcelisttobuffer(con->selections,buf,"&"); } } break; case CES_NIL: { ncbytescat(buf,"<nil>"); } break; default: assert(0); } }
void convert1(NCConstant* src, NCConstant* dst) { Constvalue tmp; unsigned char* bytes = NULL; size_t bytelen; dst->lineno = src->lineno; /* Need to translate all possible sources to all possible sinks.*/ /* Rather than have a nested switch, combine the src and target into*/ /* a single value so we can do a single n*n-way switch*/ /* special case for src being NC_FILLVALUE*/ if(src->nctype == NC_FILLVALUE) { if(dst->nctype != NC_FILLVALUE) { nc_getfill(dst); } return; } /* special case handling for src being NC_ECONST*/ if(src->nctype == NC_ECONST) { if(dst->nctype == NC_ECONST) { dst->value = src->value; } else { Symbol* econst; econst = src->value.enumv; convert1(&econst->typ.econst,dst); } return; } else if(dst->nctype == NC_ECONST) { /* special case for dst being NC_ECONST*/ semerror(lineno,"Conversion to enum not supported (yet)"); return; } if(src->nctype == NC_OPAQUE) { bytes = makebytestring(src->value.opaquev.stringv,&bytelen); } #define CASE(nc1,nc2) (nc1*256+nc2) switch (CASE(src->nctype,dst->nctype)) { case CASE(NC_CHAR,NC_CHAR): tmp.charv = src->value.charv; break; case CASE(NC_CHAR,NC_BYTE): tmp.int8v = (unsigned char)src->value.charv; break; case CASE(NC_CHAR,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.charv; break; case CASE(NC_CHAR,NC_USHORT): tmp.uint16v = (unsigned short)src->value.charv; break; case CASE(NC_CHAR,NC_UINT): tmp.uint32v = (unsigned int)src->value.charv; break; case CASE(NC_CHAR,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.charv; break; case CASE(NC_CHAR,NC_SHORT): tmp.int16v = (short)src->value.charv; break; case CASE(NC_CHAR,NC_INT): tmp.int32v = (int)src->value.charv; break; case CASE(NC_CHAR,NC_INT64): tmp.int64v = (long long)src->value.charv; break; case CASE(NC_CHAR,NC_FLOAT): tmp.floatv = (float)src->value.charv; break; case CASE(NC_CHAR,NC_DOUBLE): tmp.doublev = (double)src->value.charv; break; case CASE(NC_BYTE,NC_CHAR): tmp.charv = (char)src->value.uint8v; break; case CASE(NC_BYTE,NC_BYTE): tmp.uint8v = (unsigned char)src->value.uint8v; break; case CASE(NC_BYTE,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.uint8v; break; case CASE(NC_BYTE,NC_USHORT): tmp.uint16v = (unsigned short)src->value.uint8v; break; case CASE(NC_BYTE,NC_UINT): tmp.uint32v = (unsigned int)src->value.uint8v; break; case CASE(NC_BYTE,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.uint8v; break; case CASE(NC_BYTE,NC_SHORT): tmp.int16v = (short)src->value.uint8v; break; case CASE(NC_BYTE,NC_INT): tmp.int32v = (int)src->value.uint8v; break; case CASE(NC_BYTE,NC_INT64): tmp.int64v = (long long)src->value.uint8v; break; case CASE(NC_BYTE,NC_FLOAT): tmp.floatv = (float)src->value.uint8v; break; case CASE(NC_BYTE,NC_DOUBLE): tmp.doublev = (double)src->value.uint8v; break; case CASE(NC_UBYTE,NC_CHAR): tmp.charv = (char)src->value.uint8v; break; case CASE(NC_UBYTE,NC_BYTE): tmp.uint8v = (unsigned char)src->value.uint8v; break; case CASE(NC_UBYTE,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.uint8v; break; case CASE(NC_UBYTE,NC_USHORT): tmp.uint16v = (unsigned short)src->value.uint8v; break; case CASE(NC_UBYTE,NC_UINT): tmp.uint32v = (unsigned int)src->value.uint8v; break; case CASE(NC_UBYTE,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.uint8v; break; case CASE(NC_UBYTE,NC_SHORT): tmp.int16v = (short)src->value.uint8v; break; case CASE(NC_UBYTE,NC_INT): tmp.int32v = (int)src->value.uint8v; break; case CASE(NC_UBYTE,NC_INT64): tmp.int64v = (long long)src->value.uint8v; break; case CASE(NC_UBYTE,NC_FLOAT): tmp.floatv = (float)src->value.uint8v; break; case CASE(NC_UBYTE,NC_DOUBLE): tmp.doublev = (double)src->value.uint8v; break; case CASE(NC_USHORT,NC_BYTE): tmp.uint8v = (unsigned char)src->value.uint16v; break; case CASE(NC_USHORT,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.uint16v; break; case CASE(NC_USHORT,NC_USHORT): tmp.uint16v = (unsigned short)src->value.uint16v; break; case CASE(NC_USHORT,NC_UINT): tmp.uint32v = (unsigned int)src->value.uint16v; break; case CASE(NC_USHORT,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.uint16v; break; case CASE(NC_USHORT,NC_SHORT): tmp.int16v = (short)src->value.uint16v; break; case CASE(NC_USHORT,NC_INT): tmp.int32v = (int)src->value.uint16v; break; case CASE(NC_USHORT,NC_INT64): tmp.int64v = (long long)src->value.uint16v; break; case CASE(NC_USHORT,NC_FLOAT): tmp.floatv = (float)src->value.uint16v; break; case CASE(NC_USHORT,NC_DOUBLE): tmp.doublev = (double)src->value.uint16v; break; case CASE(NC_UINT,NC_BYTE): tmp.uint8v = (unsigned char)src->value.uint32v; break; case CASE(NC_UINT,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.uint32v; break; case CASE(NC_UINT,NC_USHORT): tmp.uint16v = (unsigned short)src->value.uint32v; break; case CASE(NC_UINT,NC_UINT): tmp.uint32v = (unsigned int)src->value.uint32v; break; case CASE(NC_UINT,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.uint32v; break; case CASE(NC_UINT,NC_SHORT): tmp.int16v = (short)src->value.uint32v; break; case CASE(NC_UINT,NC_INT): tmp.int32v = (int)src->value.uint32v; break; case CASE(NC_UINT,NC_INT64): tmp.int64v = (long long)src->value.uint32v; break; case CASE(NC_UINT,NC_FLOAT): tmp.floatv = (float)src->value.uint32v; break; case CASE(NC_UINT,NC_DOUBLE): tmp.doublev = (double)src->value.uint32v; break; case CASE(NC_UINT64,NC_BYTE): tmp.uint8v = (unsigned char)src->value.uint64v; break; case CASE(NC_UINT64,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.uint64v; break; case CASE(NC_UINT64,NC_USHORT): tmp.uint16v = (unsigned short)src->value.uint64v; break; case CASE(NC_UINT64,NC_UINT): tmp.uint32v = (unsigned int)src->value.uint64v; break; case CASE(NC_UINT64,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.uint64v; break; case CASE(NC_UINT64,NC_SHORT): tmp.int16v = (short)src->value.uint64v; break; case CASE(NC_UINT64,NC_INT): tmp.int32v = (int)src->value.uint64v; break; case CASE(NC_UINT64,NC_INT64): tmp.int64v = (long long)src->value.uint64v; break; case CASE(NC_UINT64,NC_FLOAT): tmp.floatv = (float)src->value.uint64v; break; case CASE(NC_UINT64,NC_DOUBLE): tmp.doublev = (double)src->value.uint64v; break; case CASE(NC_SHORT,NC_BYTE): tmp.uint8v = (unsigned char)src->value.int16v; break; case CASE(NC_SHORT,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.int16v; break; case CASE(NC_SHORT,NC_USHORT): tmp.uint16v = (unsigned short)src->value.int16v; break; case CASE(NC_SHORT,NC_UINT): tmp.uint32v = (unsigned int)src->value.int16v; break; case CASE(NC_SHORT,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.int16v; break; case CASE(NC_SHORT,NC_SHORT): tmp.int16v = (short)src->value.int16v; break; case CASE(NC_SHORT,NC_INT): tmp.int32v = (int)src->value.int16v; break; case CASE(NC_SHORT,NC_INT64): tmp.int64v = (long long)src->value.int16v; break; case CASE(NC_SHORT,NC_FLOAT): tmp.floatv = (float)src->value.int16v; break; case CASE(NC_SHORT,NC_DOUBLE): tmp.doublev = (double)src->value.int16v; break; case CASE(NC_INT,NC_BYTE): tmp.uint8v = (unsigned char)src->value.int32v; break; case CASE(NC_INT,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.int32v; break; case CASE(NC_INT,NC_USHORT): tmp.uint16v = (unsigned short)src->value.int32v; break; case CASE(NC_INT,NC_UINT): tmp.uint32v = (unsigned int)src->value.int32v; break; case CASE(NC_INT,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.int32v; break; case CASE(NC_INT,NC_SHORT): tmp.int16v = (short)src->value.int32v; break; case CASE(NC_INT,NC_INT): tmp.int32v = (int)src->value.int32v; break; case CASE(NC_INT,NC_INT64): tmp.int64v = (long long)src->value.int32v; break; case CASE(NC_INT,NC_FLOAT): tmp.floatv = (float)src->value.int32v; break; case CASE(NC_INT,NC_DOUBLE): tmp.doublev = (double)src->value.int32v; break; case CASE(NC_INT64,NC_BYTE): tmp.uint8v = (unsigned char)src->value.int64v; break; case CASE(NC_INT64,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.int64v; break; case CASE(NC_INT64,NC_USHORT): tmp.uint16v = (unsigned short)src->value.int64v; break; case CASE(NC_INT64,NC_UINT): tmp.uint32v = (unsigned int)src->value.int64v; break; case CASE(NC_INT64,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.int64v; break; case CASE(NC_INT64,NC_SHORT): tmp.int16v = (short)src->value.int64v; break; case CASE(NC_INT64,NC_INT): tmp.int32v = (int)src->value.int64v; break; case CASE(NC_INT64,NC_INT64): tmp.int64v = (long long)src->value.int64v; break; case CASE(NC_INT64,NC_FLOAT): tmp.floatv = (float)src->value.int64v; break; case CASE(NC_INT64,NC_DOUBLE): tmp.doublev = (double)src->value.int64v; break; case CASE(NC_FLOAT,NC_BYTE): tmp.uint8v = (unsigned char)src->value.floatv; break; case CASE(NC_FLOAT,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.floatv; break; case CASE(NC_FLOAT,NC_USHORT): tmp.uint16v = (unsigned short)src->value.floatv; break; case CASE(NC_FLOAT,NC_UINT): tmp.uint32v = (unsigned int)src->value.floatv; break; case CASE(NC_FLOAT,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.floatv; break; case CASE(NC_FLOAT,NC_SHORT): tmp.int16v = (short)src->value.floatv; break; case CASE(NC_FLOAT,NC_INT): tmp.int32v = (int)src->value.floatv; break; case CASE(NC_FLOAT,NC_INT64): tmp.int64v = (long long)src->value.floatv; break; case CASE(NC_FLOAT,NC_FLOAT): tmp.floatv = src->value.floatv; break; case CASE(NC_FLOAT,NC_DOUBLE): tmp.doublev = (isnan(src->value.floatv)?NAN:(double)src->value.floatv); break; case CASE(NC_DOUBLE,NC_BYTE): tmp.uint8v = (unsigned char)src->value.doublev; break; case CASE(NC_DOUBLE,NC_UBYTE): tmp.uint8v = (unsigned char)src->value.doublev; break; case CASE(NC_DOUBLE,NC_USHORT): tmp.uint16v = (unsigned short)src->value.doublev; break; case CASE(NC_DOUBLE,NC_UINT): tmp.uint32v = (unsigned int)src->value.doublev; break; case CASE(NC_DOUBLE,NC_UINT64): tmp.uint64v = (unsigned long long)src->value.doublev; break; case CASE(NC_DOUBLE,NC_SHORT): tmp.int16v = (short)src->value.doublev; break; case CASE(NC_DOUBLE,NC_INT): tmp.int32v = (int)src->value.doublev; break; case CASE(NC_DOUBLE,NC_INT64): tmp.int64v = (long long)src->value.doublev; break; case CASE(NC_DOUBLE,NC_FLOAT): tmp.floatv = (isnan(src->value.doublev)?NANF:(float)src->value.doublev); break; case CASE(NC_DOUBLE,NC_DOUBLE): tmp.doublev = (double)src->value.doublev; break; /* Conversion of a string to e.g. an integer should be what?*/ case CASE(NC_STRING,NC_BYTE): sscanf(src->value.stringv.stringv,"%hhd",&tmp.int8v); break; case CASE(NC_STRING,NC_UBYTE): sscanf(src->value.stringv.stringv,"%hhu",&tmp.uint8v); break; case CASE(NC_STRING,NC_USHORT): sscanf(src->value.stringv.stringv,"%hu",&tmp.uint16v); break; case CASE(NC_STRING,NC_UINT): sscanf(src->value.stringv.stringv,"%u",&tmp.uint32v); break; case CASE(NC_STRING,NC_UINT64): sscanf(src->value.stringv.stringv,"%llu",&tmp.uint64v); break; case CASE(NC_STRING,NC_SHORT): sscanf(src->value.stringv.stringv,"%hd",&tmp.int16v); break; case CASE(NC_STRING,NC_INT): sscanf(src->value.stringv.stringv,"%d",&tmp.int32v); break; case CASE(NC_STRING,NC_INT64): sscanf(src->value.stringv.stringv,"%lld",&tmp.int64v); break; case CASE(NC_STRING,NC_FLOAT): sscanf(src->value.stringv.stringv,"%g",&tmp.floatv); break; case CASE(NC_STRING,NC_DOUBLE): sscanf(src->value.stringv.stringv,"%lg",&tmp.doublev); break; case CASE(NC_STRING,NC_CHAR): tmp.charv = src->value.stringv.stringv[0]; break; case CASE(NC_STRING,NC_STRING): tmp.stringv.stringv = nulldup(src->value.stringv.stringv); tmp.stringv.len = src->value.stringv.len; break; /* What is the proper conversion for T->STRING?*/ case CASE(NC_CHAR,NC_STRING): sprintf(stmp,"%c",src->value.charv); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_BYTE,NC_STRING): sprintf(stmp,"%hhd",src->value.uint8v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_UBYTE,NC_STRING): sprintf(stmp,"%hhu",src->value.uint8v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_USHORT,NC_STRING): sprintf(stmp,"%hu",src->value.uint16v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_UINT,NC_STRING): sprintf(stmp,"%u",src->value.uint32v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_UINT64,NC_STRING): sprintf(stmp,"%llu",src->value.uint64v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_SHORT,NC_STRING): sprintf(stmp,"%hd",src->value.int16v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_INT,NC_STRING): sprintf(stmp,"%d",src->value.int32v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_INT64,NC_STRING): sprintf(stmp,"%lld",src->value.int64v); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_FLOAT,NC_STRING): sprintf(stmp,"%.8g",src->value.floatv); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_DOUBLE,NC_STRING): sprintf(stmp,"%.8g",src->value.doublev); tmp.stringv.len = nulllen(stmp); tmp.stringv.stringv = nulldup(stmp); break; case CASE(NC_OPAQUE,NC_CHAR): if(bytes) tmp.charv = *(char*)bytes; break; case CASE(NC_OPAQUE,NC_BYTE): if(bytes) tmp.uint8v = *(unsigned char*)bytes; break; case CASE(NC_OPAQUE,NC_UBYTE): if(bytes) tmp.uint8v = *(unsigned char*)bytes; break; case CASE(NC_OPAQUE,NC_USHORT): if(bytes) tmp.uint16v = *(unsigned short*)bytes; break; case CASE(NC_OPAQUE,NC_UINT): if(bytes) tmp.uint32v = *(unsigned int*)bytes; break; case CASE(NC_OPAQUE,NC_UINT64): if(bytes) tmp.uint64v = *(unsigned long long*)bytes; break; case CASE(NC_OPAQUE,NC_SHORT): if(bytes) tmp.int16v = *(short*)bytes; break; case CASE(NC_OPAQUE,NC_INT): if(bytes) tmp.int32v = *(int*)bytes; break; case CASE(NC_OPAQUE,NC_INT64): if(bytes) tmp.int64v = *(long long*)bytes; break; case CASE(NC_OPAQUE,NC_FLOAT): if(bytes) tmp.floatv = *(float*)bytes; break; case CASE(NC_OPAQUE,NC_DOUBLE): if(bytes) tmp.doublev = *(double*)bytes; break; case CASE(NC_OPAQUE,NC_OPAQUE): tmp.opaquev.stringv = (char*)malloc(src->value.opaquev.len+1); memcpy(tmp.opaquev.stringv,src->value.opaquev.stringv,src->value.opaquev.len); tmp.opaquev.len = src->value.opaquev.len; tmp.opaquev.stringv[tmp.opaquev.len] = '\0'; break; case CASE(NC_NIL,NC_NIL): break; /* probably will never happen */ case CASE(NC_NIL,NC_STRING): tmp.stringv.len = 0; tmp.stringv.stringv = NULL; break; /* We are missing all CASE(X,NC_ECONST) cases*/ default: semerror(lineno,"transform: illegal conversion: %s/%d -> %s/%d", nctypename(src->nctype),src->nctype, nctypename(dst->nctype),dst->nctype); break;; } if(bytes != NULL) efree(bytes); /* cleanup*/ /* overwrite minimum necessary parts*/ dst->value = tmp; }
DCEnode* dceclone(DCEnode* node) { DCEnode* result = NULL; result = (DCEnode*)dcecreate(node->sort); if(result == NULL) goto done; switch (node->sort) { case CES_SLICE: { DCEslice* clone = (DCEslice*)result; DCEslice* orig = (DCEslice*)node; *clone = *orig; } break; case CES_SEGMENT: { DCEsegment* clone = (DCEsegment*)result; DCEsegment* orig = (DCEsegment*)node; *clone = *orig; clone->name = nulldup(orig->name); if(orig->rank > 0) memcpy(clone->slices,orig->slices,orig->rank*sizeof(DCEslice)); } break; case CES_VAR: { DCEvar* clone = (DCEvar*)result; DCEvar* orig = (DCEvar*)node; *clone = *orig; clone->segments = dceclonelist(clone->segments); } break; case CES_FCN: { DCEfcn* clone = (DCEfcn*)result; DCEfcn* orig = (DCEfcn*)node; *clone = *orig; clone->name = nulldup(orig->name); clone->args = dceclonelist(orig->args); } break; case CES_CONST: { DCEconstant* clone = (DCEconstant*)result; DCEconstant* orig = (DCEconstant*)node; *clone = *orig; if(clone->discrim == CES_STR) clone->text = nulldup(clone->text); } break; case CES_VALUE: { DCEvalue* clone = (DCEvalue*)result; DCEvalue* orig = (DCEvalue*)node; *clone = *orig; switch (clone->discrim) { case CES_CONST: clone->constant = (DCEconstant*)dceclone((DCEnode*)orig->constant); break; case CES_VAR: clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break; case CES_FCN: clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break; default: assert(0); } } break; case CES_PROJECT: { DCEprojection* clone = (DCEprojection*)result; DCEprojection* orig = (DCEprojection*)node; *clone = *orig; switch (orig->discrim) { case CES_VAR: clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break; case CES_FCN: clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break; default: assert(0); } } break; case CES_SELECT: { DCEselection* clone = (DCEselection*)result; DCEselection* orig = (DCEselection*)node; *clone = *orig; clone->lhs = (DCEvalue*)dceclone((DCEnode*)orig->lhs); clone->rhs = dceclonelist(orig->rhs); } break; case CES_CONSTRAINT: { DCEconstraint* clone = (DCEconstraint*)result; DCEconstraint* orig = (DCEconstraint*)node; *clone = *orig; clone->projections = dceclonelist(orig->projections); clone->selections = dceclonelist(orig->selections); } break; default: assert(0); } done: return result; }
NCerror addstringdims(NCDAPCOMMON* dapcomm) { /* for all variables of string type, we will need another dimension to represent the string; Accumulate the needed sizes and create the dimensions with a specific name: either as specified in DODS{...} attribute set or defaulting to the variable name. All such dimensions are global. */ int i; NClist* varnodes = dapcomm->cdf.ddsroot->tree->varnodes; CDFnode* globalsdim = NULL; char dimname[4096]; size_t dimsize; /* Start by creating the global string dimension */ snprintf(dimname,sizeof(dimname),"maxStrlen%lu", (unsigned long)dapcomm->cdf.defaultstringlength); globalsdim = makecdfnode34(dapcomm, dimname, OC_Dimension, NULL, dapcomm->cdf.ddsroot); nclistpush(dapcomm->cdf.ddsroot->tree->nodes,(void*)globalsdim); DIMFLAGSET(globalsdim,CDFDIMSTRING); globalsdim->dim.declsize = dapcomm->cdf.defaultstringlength; globalsdim->dim.declsize0 = globalsdim->dim.declsize; globalsdim->dim.array = dapcomm->cdf.ddsroot; globalsdim->ncbasename = cdflegalname3(dimname); globalsdim->ncfullname = nulldup(globalsdim->ncbasename); dapcomm->cdf.globalstringdim = globalsdim; for(i=0;i<nclistlength(varnodes);i++) { CDFnode* var = (CDFnode*)nclistget(varnodes,i); CDFnode* sdim = NULL; /* Does this node need a string dim? */ if(var->etype != NC_STRING && var->etype != NC_URL) continue; dimsize = 0; if(var->dodsspecial.maxstrlen > 0) dimsize = var->dodsspecial.maxstrlen; else dimsize = var->maxstringlength; /* check is a variable-specific string length was specified */ if(dimsize == 0) sdim = dapcomm->cdf.globalstringdim; /* use default */ else { /* create a psuedo dimension for the charification of the string*/ if(var->dodsspecial.dimname != NULL) strncpy(dimname,var->dodsspecial.dimname,sizeof(dimname)); else snprintf(dimname,sizeof(dimname),"maxStrlen%lu", (unsigned long)dimsize); sdim = makecdfnode34(dapcomm, dimname, OC_Dimension, NULL, dapcomm->cdf.ddsroot); if(sdim == NULL) return THROW(NC_ENOMEM); nclistpush(dapcomm->cdf.ddsroot->tree->nodes,(void*)sdim); DIMFLAGSET(sdim,CDFDIMSTRING); sdim->dim.declsize = dimsize; sdim->dim.declsize0 = dimsize; sdim->dim.array = var; sdim->ncbasename = cdflegalname3(sdim->ocname); sdim->ncfullname = nulldup(sdim->ncbasename); } /* tag the variable with its string dimension*/ var->array.stringdim = sdim; } return NC_NOERR; }
static int mergedas1(NCDAPCOMMON* nccomm, OClink conn, CDFnode* dds, OCddsnode das) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; unsigned int i,j,k; 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*/ OCCHECK(oc_inq_nsubnodes(conn,das,&nsubnodes)); OCCHECK(oc_inq_subnodes(conn,das,&subnodes)); for(i=0;i<nsubnodes;i++) { OCobject attnode = subnodes[i]; OCtype octype, ocetype; char* ocname = NULL; unsigned int ocnvalues; OCCHECK(oc_inq_name(conn,attnode,&ocname)); OCCHECK(oc_inq_class(conn,attnode,&octype)); if(octype == OC_Attribute) { NCattribute* att = NULL; NClist* stringvalues; OCCHECK(oc_inq_primtype(conn,attnode,&ocetype)); OCCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues)); stringvalues = nclistnew(); for(j=0;j<ocnvalues;j++) { char* stringval; OCCHECK(oc_inq_dasattr(conn,attnode,j,&ocetype,&stringval)); nclistpush(stringvalues,(void*)stringval); } ncstat = buildattribute(ocname, octypetonc(ocetype), stringvalues, &att); if(ncstat) goto done; nclistpush(dds->attributes,(void*)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 */ OCCHECK(oc_inq_nsubnodes(conn,attnode,&ndodsnodes)); OCCHECK(oc_inq_subnodes(conn,attnode,&dodsnodes)); for(j=0;j<ndodsnodes;j++) { char* dodsname = NULL; char newname[4096]; OCobject attnode = dodsnodes[j]; NCattribute* att = NULL; NClist* stringvalues; OCCHECK(oc_inq_class(conn,attnode,&octype)); if(octype != OC_Attribute) continue; OCCHECK(oc_inq_primtype(conn,attnode,&ocetype)); OCCHECK(oc_inq_dasattr_nvalues(conn,attnode,&ocnvalues)); stringvalues = nclistnew(); for(k=0;k<ocnvalues;k++) { char* stringval; OCCHECK(oc_inq_dasattr(conn,attnode,k,&ocetype,&stringval)); nclistpush(stringvalues,(void*)stringval); } OCCHECK(oc_inq_name(conn,attnode,&dodsname)); /* Compute new special name */ strcpy(newname,"_DODS_"); strcat(newname,dodsname); ncstat = buildattribute(newname, octypetonc(ocetype), stringvalues, &att); if(ncstat) goto done; att->invisible = 1; nclistpush(dds->attributes,(void*)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); }
/* Invoke oc_merge_das and then extract special attributes such as "strlen" and "dimname" and stuff from DODS_EXTRA. */ int dapmerge3(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot) { int i,j; NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; NClist* allnodes; OClink conn; char* ocname = NULL; char** values = NULL; conn = nccomm->oc.conn; if(ddsroot == NULL || dasroot == NULL) return NC_NOERR; /* Merge the das tree onto the dds tree */ ocstat = oc_merge_das(nccomm->oc.conn,dasroot,ddsroot); if(ocstat != OC_NOERR) goto done; /* Create attributes on CDFnodes */ allnodes = nccomm->cdf.ddsroot->tree->nodes; for(i=0;i<nclistlength(allnodes);i++) { CDFnode* node = (CDFnode*)nclistget(allnodes,i); OCddsnode ocnode = node->ocnode; size_t attrcount; OCtype ocetype; OCCHECK(oc_dds_attr_count(conn,ocnode,&attrcount)); for(j=0;j<attrcount;j++) { size_t nvalues; NCattribute* att = NULL; if(ocname != NULL) { free(ocname); ocname = NULL; } /* from last loop */ OCCHECK(oc_dds_attr(conn,ocnode,j,&ocname,&ocetype,&nvalues,NULL)); if(nvalues > 0) { values = (char**)malloc(sizeof(char*)*nvalues); if(values == NULL) {ncstat = NC_ENOMEM; goto done;} OCCHECK(oc_dds_attr(conn,ocnode,j,NULL,NULL,NULL,values)); } ncstat = buildattribute(ocname,octypetonc(ocetype),nvalues,values,&att); if(ncstat != NC_NOERR) goto done; if(node->attributes == NULL) node->attributes = nclistnew(); nclistpush(node->attributes,(void*)att); if(strncmp(ocname,"DODS",strlen("DODS"))==0) { att->invisible = 1; /* Define extra semantics associated with DODS and DODS_EXTRA attributes */ if(strcmp(ocname,"DODS.strlen")==0 || strcmp(ocname,"DODS_EXTRA.strlen")==0) { unsigned int maxstrlen = 0; if(values != NULL) { if(0==sscanf(values[0],"%u",&maxstrlen)) maxstrlen = 0; } node->dodsspecial.maxstrlen = maxstrlen; #ifdef DEBUG fprintf(stderr,"%s.maxstrlen=%d\n",node->ocname,(int)node->dodsspecial.maxstrlen); #endif } else if(strcmp(ocname,"DODS.dimName")==0 || strcmp(ocname,"DODS_EXTRA.dimName")==0) { if(values != NULL) { node->dodsspecial.dimname = nulldup(values[0]); #ifdef DEBUG fprintf(stderr,"%s.dimname=%s\n",node->ocname,node->dodsspecial.dimname); #endif } else node->dodsspecial.dimname = NULL; } else if(strcmp(ocname,"DODS.Unlimited_Dimension")==0 || strcmp(ocname,"DODS_EXTRA.Unlimited_Dimension")==0) { if(values != NULL) { if(nccomm->cdf.recorddimname != NULL) nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications"); else nccomm->cdf.recorddimname = nulldup(values[0]); #ifdef DEBUG fprintf(stderr,"%s.Unlimited_Dimension=%s\n",node->ocname,nccomm->cdf.recorddimname); #endif } } } /* clean up */ if(values) { oc_reclaim_strings(nvalues,values); free(values); values = NULL; } } } done: if(values != NULL) free(values); if(ocname != NULL) free(ocname); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
NCerror fixgrid(NCDAPCOMMON* nccomm, CDFnode* grid) { unsigned int i,glen; CDFnode* array; glen = nclistlength(grid->subnodes); array = (CDFnode*)nclistget(grid->subnodes,0); if(nccomm->controls.flags & (NCF_NC3)) { /* Rename grid Array: variable, but leave its oc base name alone */ nullfree(array->ncbasename); array->ncbasename = nulldup(grid->ncbasename); if(!array->ncbasename) return NC_ENOMEM; } /* validate and modify the grid structure */ if((glen-1) != nclistlength(array->array.dimset0)) goto invalid; for(i=1;i<glen;i++) { CDFnode* arraydim = (CDFnode*)nclistget(array->array.dimset0,i-1); CDFnode* map = (CDFnode*)nclistget(grid->subnodes,i); CDFnode* mapdim; /* map must have 1 dimension */ if(nclistlength(map->array.dimset0) != 1) goto invalid; /* and the map name must match the ith array dimension */ if(arraydim->ocname != NULL && map->ocname != NULL && strcmp(arraydim->ocname,map->ocname) != 0) goto invalid; /* and the map name must match its dim name (if any) */ mapdim = (CDFnode*)nclistget(map->array.dimset0,0); if(mapdim->ocname != NULL && map->ocname != NULL && strcmp(mapdim->ocname,map->ocname) != 0) goto invalid; /* Add appropriate names for the anonymous dimensions */ /* Do the map name first, so the array dim may inherit */ if(mapdim->ocname == NULL) { nullfree(mapdim->ncbasename); mapdim->ocname = nulldup(map->ocname); if(!mapdim->ocname) return NC_ENOMEM; mapdim->ncbasename = cdflegalname(mapdim->ocname); if(!mapdim->ncbasename) return NC_ENOMEM; } if(arraydim->ocname == NULL) { nullfree(arraydim->ncbasename); arraydim->ocname = nulldup(map->ocname); if(!arraydim->ocname) return NC_ENOMEM; arraydim->ncbasename = cdflegalname(arraydim->ocname); if(!arraydim->ncbasename) return NC_ENOMEM; } if(FLAGSET(nccomm->controls,(NCF_NCDAP|NCF_NC3))) { char tmp[3*NC_MAX_NAME]; /* Add the grid name to the basename of the map */ snprintf(tmp,sizeof(tmp),"%s%s%s",map->container->ncbasename, nccomm->cdf.separator, map->ncbasename); nullfree(map->ncbasename); map->ncbasename = nulldup(tmp); if(!map->ncbasename) return NC_ENOMEM; } } return NC_NOERR; invalid: return NC_EINVAL; /* mal-formed grid */ }