/* This procedure returns the value as the original DAS string */ OCerror oc_inq_attrstrings(OCconnection conn, OCobject node0, unsigned int i, char** namep, OCtype* octypep, unsigned int* nvaluesp, char*** stringsp) { OCstate* state; OCnode* node; OCattribute* attr; unsigned int nattrs; OCVERIFY(OCstate*,state,conn); OCDEREF(OCstate*,state,conn); OCVERIFY(OCnode*,node,node0); OCDEREF(OCnode*,node,node0); nattrs = oclistlength(node->attributes); if(i >= nattrs) return OC_EINVAL; attr = (OCattribute*)oclistget(node->attributes,i); if(namep) *namep = strdup(attr->name); if(octypep) *octypep = attr->etype; if(nvaluesp) *nvaluesp = attr->nvalues; if(stringsp) { size_t space = attr->nvalues * sizeof(char*); char** strings = (space > 0?ocmalloc(space):NULL); for(i=0;i<attr->nvalues;i++) strings[i] = nulldup(attr->values[i]); *stringsp = strings; } return OC_NOERR; }
/* Return all the OCobjects associated with a tree with specified root */ OCobject* oc_inq_objects(OCconnection conn, OCobject root0) { unsigned int i; OCstate* state; OCnode* root; OClist* nodes; OCobject* objects = NULL; unsigned int nobjects; OCVERIFYX(OCstate*,state,conn,OCNULL); OCDEREF(OCstate*,state,conn); OCVERIFYX(OCnode*,root,root0,OCNULL); OCDEREF(OCnode*,root,root0); if(root == NULL) return NULL; root = root->root; if(root == NULL) return NULL; nodes = root->tree->nodes; nobjects = oclistlength(nodes); if(nodes != NULL && nobjects > 0) { size_t len = sizeof(OCobject)*(1+nobjects); objects = (OCobject*)ocmalloc(len); for(i=0;i<oclistlength(nodes);i++) { objects[i] = (OCobject)oclistget(nodes,i); } objects[nobjects] = OCNULL; /* null terminate */ } return objects; }
static OCerror createtempfile(OCstate* state, OCtree* tree) { int fd,slen; char* name; slen = strlen(TMPPATH1); if(slen < strlen(TMPPATH2)) slen = strlen(TMPPATH2); slen += strlen("datadds") + strlen("XXXXXX"); name = (char*)ocmalloc(slen+1); MEMCHECK(name,OC_ENOMEM); fd = createtempfile1(name, TMPPATH1); if(fd < 0) fd = createtempfile1(name, TMPPATH2); if(fd < 0) { oc_log(LOGERR,"oc_open: attempt to open tmp file %s failed",name); return errno; } oc_log(LOGNOTE,"oc_open: using tmp file: %s",name); tree->data.filename = name; /* remember our tmp file name */ tree->data.file = fdopen(fd,"w+"); if(tree->data.file == NULL) return OC_EOPEN; /* unlink the temp file so it will automatically be reclaimed */ if(ocdebug == 0) unlink(tree->data.filename); return OC_NOERR; }
static OCerror ocextractddsinmemory(OCstate* state, OCtree* tree, OCflags flags) { OCerror stat = OC_NOERR; size_t ddslen, bod, bodfound; /* Read until we find the separator (or EOF)*/ bodfound = findbod(state->packet,&bod,&ddslen); if(!bodfound) {/* No BOD; pretend */ bod = tree->data.bod; ddslen = tree->data.datasize; } tree->data.bod = bod; tree->data.ddslen = ddslen; /* copy out the dds */ if(ddslen > 0) { tree->text = (char*)ocmalloc(ddslen+1); memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); tree->text[ddslen] = '\0'; } else tree->text = NULL; /* Extract the inmemory contents */ tree->data.memory = ocbytesextract(state->packet); #ifdef IGNORE /* guarantee the data part is on an 8 byte boundary */ if(tree->data.bod % 8 != 0) { unsigned long count = tree->data.datasize - tree->data.bod; memcpy(tree->xdrmemory,tree->xdrmemory+tree->data.bod,count); tree->data.datasize = count; tree->data.bod = 0; tree->data.ddslen = 0; } #endif if(tree->text == NULL) stat = OC_EDATADDS; return OCTHROW(stat); }
/* DRNO need to explicitly get and walk string values*/ int oc_stringcontent(OCstate* state, OCcontent* content, char** stringp, size_t* slenp) { int stat = OC_NOERR; XDR* xdrs; unsigned int slen; char* stringmemory; if(state == NULL || content == NULL) return OCTHROW(OC_EINVAL); if(content->node->octype != OC_Primitive) return OCTHROW(OC_EINVAL); if(content->node->etype != OC_String && content->node->etype != OC_URL) return OCTHROW(OC_EINVAL); xdrs = state->dap.xdrs; if(xdrs == NULL) return OCTHROW(OC_EXDR); if(oc_contentmode(state,content) != Datamode) return OCTHROW(OC_EINVAL); /* We are at a single instance of a string data type*/ if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror(); if(!xdr_u_int(xdrs,&slen)) return xdrerror(); stringmemory = (char*)ocmalloc(slen+1); MEMCHECK(stringmemory,OC_ENOMEM); if(!xdr_opaque(xdrs,stringmemory,slen)) return xdrerror(); stringmemory[slen] = '\0'; /* restore location*/ if(!xdr_setpos(xdrs,content->xdroffset)) return xdrerror(); if(stringp != NULL) *stringp = stringmemory; if(slenp != NULL) *slenp = slen; return OCTHROW(stat); }
/* Modify constraint to use %XX escapes */ static char* constraintescape(const char* url) { size_t len; char* p; int c; char* eurl; if(url == NULL) return NULL; len = strlen(url); eurl = ocmalloc(1+3*len); /* worst case: c -> %xx */ MEMCHECK(eurl,NULL); p = eurl; *p = '\0'; while((c=*url++)) { if(c >= '0' && c <= '9') {*p++ = c;} else if(c >= 'a' && c <= 'z') {*p++ = c;} else if(c >= 'A' && c <= 'Z') {*p++ = c;} else if(strchr(okchars,c) != NULL) {*p++ = c;} else { *p++ = '%'; *p++ = hexdigits[(c & 0xf0)>>4]; *p++ = hexdigits[(c & 0xf)]; } } *p = '\0'; return eurl; }
OCattribute* makeattribute(char* name, OCtype ptype, OClist* values) { OCattribute* att = (OCattribute*)ocmalloc(sizeof(OCattribute)); /* ocmalloc zeros*/ MEMCHECK(att,(OCattribute*)NULL); att->name = nulldup(name); att->etype = ptype; att->nvalues = oclistlength(values); att->values = NULL; if(att->nvalues > 0) { int i; att->values = (char**)ocmalloc(sizeof(char*)*att->nvalues); for(i=0;i<att->nvalues;i++) att->values[i] = nulldup((char*)oclistget(values,i)); } return att; }
static OCerror ocextractdds(OCstate* state, OCtree* tree) { OCerror stat = OC_NOERR; size_t ddslen, bod, bodfound; #ifdef OC_DISK_STORAGE /* Read until we find the separator (or EOF)*/ ocbytesclear(state->packet); rewind(tree->data.file); do { char chunk[128]; size_t count; /* read chunks of the file until we find the separator*/ count = fread(chunk,1,sizeof(chunk),tree->data.file); if(count <= 0) break; /* EOF;*/ ocbytesappendn(state->packet,chunk,count); bodfound = findbod(state->packet,&bod,&ddslen); } while(!bodfound); #else /*!OC_DISK_STORAGE*/ /* Read until we find the separator (or EOF)*/ bodfound = findbod(state->packet,&bod,&ddslen); #endif if(!bodfound) {/* No BOD; pretend */ bod = tree->data.bod; ddslen = tree->data.datasize; } tree->data.bod = bod; tree->data.ddslen = ddslen; /* copy out the dds */ if(ddslen > 0) { tree->text = (char*)ocmalloc(ddslen+1); memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); tree->text[ddslen] = '\0'; } else tree->text = NULL; #ifdef OC_DISK_STORAGE /* reset the position of the tmp file*/ fseek(tree->data.file,tree->data.bod,SEEK_SET); #else /* If the data part is not on an 8 byte boundary, make it so */ if(tree->data.bod % 8 != 0) { unsigned long count = tree->data.datasize - tree->data.bod; char* dst = ocbytescontents(state->packet); char* src = dst + tree->data.bod; int i; /* memcpy((void*)dst,(void*)src,count); overlap*/ for(i=0;i<count;i++) dst[i] = src[i]; /* avoid memcpy overlap */ tree->data.datasize = count; tree->data.bod = 0; tree->data.ddslen = 0; } #endif if(tree->text == NULL) stat = OC_EDATADDS; return THROW(stat); }
/* Not all systems have strndup, so provide one*/ char* ocstrndup(const char* s, size_t len) { char* dup; if(s == NULL) return NULL; dup = (char*)ocmalloc(len+1); MEMCHECK(dup,NULL); memcpy((void*)dup,s,len); dup[len] = '\0'; return dup; }
static char* dent(int n) { if(sindent == NULL) { sindent = (char*)ocmalloc(102); MEMCHECK(sindent,NULL); memset((void*)sindent,(int)' ',(size_t)101); sindent[101] = '\0'; } if(n > 100) n = 100; return sindent+(100-n); }
OCnode* makeocnode(char* name, OCtype ptype, OCnode* root) { OCnode* cdf = (OCnode*)ocmalloc(sizeof(OCnode)); MEMCHECK(cdf,(OCnode*)NULL); memset((void*)cdf,0,sizeof(OCnode)); cdf->magic = OCMAGIC; cdf->name = (name?strdup(name):NULL); cdf->octype = ptype; cdf->array.dimensions = NULL; cdf->root = root; return cdf; }
OCerror ocopen(OCstate** statep, const char* url) { int stat = OC_NOERR; OCstate * state = NULL; OCURI* tmpurl = NULL; CURL* curl = NULL; /* curl handle*/ if(!ocuriparse(url,&tmpurl)) {OCTHROWCHK(stat=OC_EBADURL); goto fail;} stat = occurlopen(&curl); if(stat != OC_NOERR) {OCTHROWCHK(stat); goto fail;} state = (OCstate*)ocmalloc(sizeof(OCstate)); /* ocmalloc zeros memory*/ if(state == NULL) {OCTHROWCHK(stat=OC_ENOMEM); goto fail;} /* Setup DAP state*/ state->header.magic = OCMAGIC; state->header.occlass = OC_State; state->curl = curl; state->trees = oclistnew(); state->uri = tmpurl; if(!ocuridecodeparams(state->uri)) { oclog(OCLOGWARN,"Could not parse client parameters"); } state->packet = ocbytesnew(); ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ /* capture curl properties for this link from rc file1*/ stat = ocset_curlproperties(state); if(stat != OC_NOERR) goto fail; /* Set the one-time curl flags */ if((stat=ocset_flags_perlink(state))!= OC_NOERR) goto fail; #if 1 /* temporarily make per-link */ if((stat=ocset_flags_perfetch(state))!= OC_NOERR) goto fail; #endif if(statep) *statep = state; else { if(state != NULL) ocfree(state); } return OCTHROW(stat); fail: ocurifree(tmpurl); if(state != NULL) ocfree(state); if(curl != NULL) occurlclose(curl); return OCTHROW(stat); }
static DAPparsestate* dap_parse_init(char* buf) { DAPparsestate* state = (DAPparsestate*)ocmalloc(sizeof(DAPparsestate)); /*ocmalloc zeros*/ MEMCHECK(state,NULL); if(buf==NULL) { dap_parse_error(state,"dap_parse_init: no input buffer"); state->error = OC_EINVAL; /* semantic error */ dap_parse_cleanup(state); return NULL; } daplexinit(buf,&state->lexstate); return state; }
OCcontent* ocnewcontent(OCstate* state) { OCcontent* content; if(state == NULL) return NULL; content = state->contentlist; /* Search for an unused content node*/ while(content != NULL && content->mode != Emptymode) {content = content->next;} if(content == NULL) { content = (OCcontent*)ocmalloc(sizeof(OCcontent)); MEMCHECK(content,(OCcontent*)NULL); content->magic = OCMAGIC; content->next = state->contentlist; state->contentlist = content; } return ocresetcontent(state,content); }
static OCmemdata* makememdata(OCtype octype, OCtype etype, unsigned long count) { unsigned long memsize; OCmemdata* memdata; if(octype == OC_Primitive) memsize = instancesize(etype)*count; else memsize = instancesize(octype)*count; memdata = (OCmemdata*)ocmalloc(sizeof(OCmemdata) + memsize); if(memdata == NULL) return NULL; memdata->octype = (unsigned long)octype; memdata->etype = (unsigned long)etype; if(memdata->etype > 107) OCPANIC("help"); memdata->count = count; return memdata; }
OCerror ocopen(OCstate** statep, const char* url) { int stat = OC_NOERR; OCstate * state = NULL; DAPURL tmpurl; CURL* curl = NULL; /* curl handle*/ memset((void*)&tmpurl,0,sizeof(tmpurl)); if(!dapurlparse(url,&tmpurl)) {THROWCHK(stat=OC_EBADURL); goto fail;} stat = occurlopen(&curl); if(stat != OC_NOERR) {THROWCHK(stat); goto fail;} state = (OCstate*)ocmalloc(sizeof(OCstate)); /* ocmalloc zeros memory*/ if(state == NULL) {THROWCHK(stat=OC_ENOMEM); goto fail;} /* Setup DAP state*/ state->magic = OCMAGIC; state->curl = curl; state->trees = oclistnew(); state->contentlist = NULL; state->url = tmpurl; state->clientparams = ocparamdecode(state->url.params); if(state->clientparams == NULL) { oc_log(LOGWARN,"Could not parse client parameters"); } state->packet = ocbytesnew(); ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ /* set curl properties for this link */ ocsetcurlproperties(state); if(statep) *statep = state; return THROW(stat); fail: dapurlclear(&tmpurl); if(state != NULL) ocfree(state); if(curl != NULL) occurlclose(curl); return THROW(stat); }
static void encodeurltext(char* text, OCbytes* buf) { /* Encode the URL to handle illegal characters */ len = strlen(url); encoded = ocmalloc(len*4+1); /* should never be larger than this*/ if(encoded==NULL) return; p = url; q = encoded; while((c=*p++)) { if(strchr(mustencode,c) != NULL) { char tmp[8]; int hex1, hex2; hex1 = (c & 0x0F); hex2 = (c & 0xF0) >> 4; tmp[0] = '0'; tmp[1] = 'x'; tmp[2] = hexchars[hex2]; tmp[3] = hexchars[hex1]; tmp[4] = '\0'; ocbytescat(buf,tmp); } else *q++ = (char)c;
static OCerror ocextractddsinfile(OCstate* state, OCtree* tree, OCflags flags) { OCerror stat = OC_NOERR; size_t ddslen, bod, bodfound; /* Read until we find the separator (or EOF)*/ ocbytesclear(state->packet); rewind(tree->data.file); bodfound = 0; do { char chunk[1024]; size_t count; /* read chunks of the file until we find the separator*/ count = fread(chunk,1,sizeof(chunk),tree->data.file); if(count <= 0) break; /* EOF;*/ ocbytesappendn(state->packet,chunk,count); bodfound = ocfindbod(state->packet,&bod,&ddslen); } while(!bodfound); if(!bodfound) {/* No BOD; pretend */ bod = tree->data.bod; ddslen = tree->data.datasize; #ifdef OCDEBUG fprintf(stderr,"missing bod: ddslen=%lu bod=%lu\n", (unsigned long)ddslen,(unsigned long)bod); #endif } tree->data.bod = bod; tree->data.ddslen = ddslen; /* copy out the dds */ if(ddslen > 0) { tree->text = (char*)ocmalloc(ddslen+1); memcpy((void*)tree->text,(void*)ocbytescontents(state->packet),ddslen); tree->text[ddslen] = '\0'; } else tree->text = NULL; /* reset the position of the tmp file*/ if(fseek(tree->data.file,(long)tree->data.bod,SEEK_SET) < 0 || tree->text == NULL) stat = OC_EDATADDS; return OCTHROW(stat); }
OCerror ocopen(OCstate** statep, const char* url) { int stat = OC_NOERR; OCstate * state = NULL; OCURI* tmpurl = NULL; CURL* curl = NULL; /* curl handle*/ if(!ocuriparse(url,&tmpurl)) {OCTHROWCHK(stat=OC_EBADURL); goto fail;} stat = occurlopen(&curl); if(stat != OC_NOERR) {OCTHROWCHK(stat); goto fail;} state = (OCstate*)ocmalloc(sizeof(OCstate)); /* ocmalloc zeros memory*/ if(state == NULL) {OCTHROWCHK(stat=OC_ENOMEM); goto fail;} /* Setup DAP state*/ state->magic = OCMAGIC; state->curl = curl; state->trees = oclistnew(); state->uri = tmpurl; if(!ocuridecodeparams(state->uri)) { oc_log(LOGWARN,"Could not parse client parameters"); } state->packet = ocbytesnew(); ocbytessetalloc(state->packet,DFALTPACKETSIZE); /*initial reasonable size*/ /* set curl properties for this link */ ocsetcurlproperties(state); /* Set up list to support reuse/reclamation of OCcontent objects. */ state->contentlist = NULL; if(statep) *statep = state; return OCTHROW(stat); fail: ocurifree(tmpurl); if(state != NULL) ocfree(state); if(curl != NULL) occurlclose(curl); return OCTHROW(stat); }
void* oclinearize(OCtype etype, unsigned int nstrings, char** strings) { int i; size_t typesize; char* memp; char* memory; if(nstrings == 0) return NULL; typesize = octypesize(etype); memory = (char*)ocmalloc(nstrings*typesize); MEMCHECK(memory,NULL); memp = memory; for(i=0;i<nstrings;i++) { char* value = strings[i]; converttype(etype,value,memp); memp += typesize; } return memory; }
void dap_parse_error(DAPparsestate* state, const char *fmt, ...) { size_t len, suffixlen, prefixlen; va_list argv; char* tmp = NULL; va_start(argv,fmt); (void) vfprintf(stderr,fmt,argv) ; (void) fputc('\n',stderr) ; len = strlen(state->lexstate->input); suffixlen = strlen(state->lexstate->next); prefixlen = (len - suffixlen); tmp = (char*)ocmalloc(len+1); flatten(state->lexstate->input,tmp,prefixlen); (void) fprintf(stderr,"context: %s",tmp); flatten(state->lexstate->next,tmp,suffixlen); (void) fprintf(stderr,"^%s\n",tmp); (void) fflush(stderr); /* to ensure log files are current */ ocfree(tmp); va_end(argv); }
/* Convert path to a string; leave off the dataset name*/ static char* pathtostring(OClist* path, char* separator, int usecdfname) { int slen,i,len; char* pathname; if(path == NULL || (len = oclistlength(path))==0) return NULL; for(slen=0,i=0;i<len;i++) { OCnode* node = (OCnode*)oclistget(path,i); if(node->container == NULL || node->name == NULL) continue; slen += strlen(node->name); } slen += ((len-1)*strlen(separator)); slen += 1; /* for null terminator*/ pathname = (char*)ocmalloc(slen); MEMCHECK(pathname,NULL); pathname[0] = '\0'; for(i=0;i<len;i++) { OCnode* node = (OCnode*)oclistget(path,i); if(node->container == NULL || node->name == NULL) continue; if(strlen(pathname) > 0) strcat(pathname,separator); strcat(pathname,node->name); } return pathname; }
/* Extract data from the xdr packet into a chunk of memory. Normally, it is assumed that we are (at least virtually) "at" a single instance in the xdr packet; which we read. Virtually because for packed data, we need to point to the beginning of the packed data and use the index to indicate which packed element to get. */ int ocxdrread(XDR* xdrs, char* memory, size_t memsize, int packed, OCtype octype, unsigned int start, size_t count) { int stat = OC_NOERR; unsigned int i; size_t elemsize = octypesize(octype); char* localmem = NULL; char* startmem = NULL; size_t totalsize; size_t xdrsize; unsigned int xdrckp = xdr_getpos(xdrs); /* validate memory space*/ totalsize = elemsize*count; if(memsize < totalsize) return THROW(OC_EINVAL); /* Handle packed data specially*/ /* WARNING: assumes that the initial count has been read*/ if(packed) { char tmp[LOCALMEMMAX]; unsigned int readsize = start+count; if(readsize <= LOCALMEMMAX) /* avoid malloc/free for common case*/ localmem = tmp; else { localmem = (char*)ocmalloc(readsize); MEMCHECK(localmem,OC_ENOMEM); } if(!xdr_opaque(xdrs,(char*)localmem,readsize)) return xdrerror(); memcpy((void*)memory,(void*)(localmem+start),count); if(readsize > LOCALMEMMAX) ocfree(localmem); if(!xdr_setpos(xdrs,xdrckp)) return xdrerror(); /* revert to beginning*/ return THROW(OC_NOERR); } /* Not packed: extract count items; use xdr_opaque to speed up*/ if(octype == OC_String || octype == OC_URL) { /* do nothing here; handle below*/ } else if(octype == OC_Float64 || octype == OC_UInt64 || octype == OC_Int64) { unsigned int* p; xdrsize = 2*(start+count)*BYTES_PER_XDR_UNIT; localmem = (char*)ocmalloc(xdrsize); startmem = localmem+(2*start*BYTES_PER_XDR_UNIT); MEMCHECK(localmem,OC_ENOMEM); if(!xdr_opaque(xdrs,(char*)localmem,xdrsize)) return xdrerror(); if(!oc_network_order) { for(p=(unsigned int*)startmem,i=0;i<2*count;i++,p++) { unsigned int swap = *p; swapinline(*p,swap); } } } else { unsigned int* p; xdrsize = (start+count)*BYTES_PER_XDR_UNIT; localmem = (char*)ocmalloc(xdrsize); MEMCHECK(localmem,OC_ENOMEM); startmem = localmem+(start*BYTES_PER_XDR_UNIT); if(!xdr_opaque(xdrs,(char*)localmem,xdrsize)) return xdrerror(); if(!oc_network_order) { for(p=(unsigned int*)startmem,i=0;i<count;i++,p++) { unsigned int swap = *p; swapinline(*p,swap); } } } switch (octype) { case OC_Char: case OC_Byte: case OC_UByte: { char* pmem = (char*)memory; unsigned int* p = (unsigned int*)startmem; for(i=0;i<count;i++) {*pmem++ = (char)(*p++);} } break; case OC_Int16: case OC_UInt16: { unsigned short* pmem = (unsigned short*)memory; unsigned int* p = (unsigned int*)startmem; for(i=0;i<count;i++) {*pmem++ = (unsigned short)(*p++);} } break; case OC_Int32: case OC_UInt32: { memcpy((void*)memory,(void*)startmem,count*sizeof(unsigned int)); } break; case OC_Float32: { memcpy((void*)memory,(void*)startmem,count*sizeof(float)); } break; case OC_Int64: case OC_UInt64: case OC_Float64: { unsigned int* p; unsigned int* pmem = (unsigned int*)memory; /* Sometimes need to invert order*/ for(p=(unsigned int*)startmem,i=0;i<count;i++) { if(oc_invert_xdr_double) { pmem[1] = (unsigned int)(*p++); pmem[0] = (unsigned int)(*p++); } else { pmem[0] = (unsigned int)(*p++); pmem[1] = (unsigned int)(*p++); } pmem += 2; } } break; case OC_String: case OC_URL: { char* s = NULL; char** pmem = (char**)memory; /* First skip to the starting string */ for(i=0;i<start;i++) { s = NULL; /* make xdr_string alloc the space */ if(!xdr_string(xdrs,&s,OC_INT32_MAX)) return xdrerror(); ocfree(s); } /* Read count strings */ for(i=0;i<count;i++) { s = NULL; /* make xdr_string alloc the space */ if(!xdr_string(xdrs,&s,OC_INT32_MAX)) return xdrerror(); pmem[i] = s; } } break; default: return THROW(OC_EINVAL); } ocfree(localmem); if(!xdr_setpos(xdrs,xdrckp)) return xdrerror(); /* revert to beginning*/ return THROW(stat); }
OCerror ocfetchf(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; 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 & OCINMEMORY) == 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 unwind;} 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; }/*switch*/ if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oc_log(LOGWARN,"oc_open: Could not read url"); } return OCTHROW(stat); } 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) { oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {OCTHROWCHK(stat); goto unwind;} 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 unwind;} break; case OCDDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDDS); goto unwind;} break; case OCDATADDS: if(root->octype != OC_Dataset) {OCTHROWCHK(stat=OC_EDATADDS); goto unwind;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to assign offsets and sizes where possible */ occomputeskipdata(state,root); /* 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 & OCINMEMORY) == 0) { tree->data.xdrs = xxdr_filecreate(tree->data.file,tree->data.bod); } else { /* 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); } /* Put root into the state->trees list */ oclistpush(state->trees,(ocelem)root); if(rootp) *rootp = root; return stat; unwind: ocfreetree(tree); fail: return OCTHROW(stat); }
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 per-fetch curl properties */ #if 0 /* temporarily make per-link */ if((stat=ocset_flags_perfetch(state))!= OC_NOERR) goto fail; #endif 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*/ /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(stat != OC_NOERR) { 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); }
OCerror ocfetch(OCstate* state, const char* constraint, OCdxd kind, 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); 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: #ifdef OC_DISK_STORAGE /* Create the datadds file immediately so that DRNO can reference it*/ /* Make the tmp file*/ stat = createtempfile(state,tree); if(stat) {THROWCHK(stat); goto unwind;} stat = readDATADDS(state,tree); if(stat == OC_NOERR) { /* Separate the DDS from data and return the dds; will modify packet */ stat = ocextractdds(state,tree); } #else stat = readDATADDS(state,tree); if(stat == OC_NOERR) { /* Separate the DDS from data*/ stat = ocextractdds(state,tree); tree->data.xdrdata = ocbytesdup(state->packet); } #endif break; } if(stat != OC_NOERR) { /* Obtain any http code */ state->error.httpcode = ocfetchhttpcode(state->curl); if(state->error.httpcode >= 400) { oc_log(LOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode); } else { oc_log(LOGWARN,"oc_open: Could not read url"); } return THROW(stat); } 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) { oc_log(LOGERR,"oc_open: server error retrieving url: code=%s message=\"%s\"", state->error.code, (state->error.message?state->error.message:"")); } if(stat) {THROWCHK(stat); goto unwind;} root = tree->root; /* make sure */ tree->root = root; root->tree = tree; /* Verify the parse */ switch (kind) { case OCDAS: if(root->octype != OC_Attributeset) {THROWCHK(stat=OC_EDAS); goto unwind;} break; case OCDDS: if(root->octype != OC_Dataset) {THROWCHK(stat=OC_EDDS); goto unwind;} break; case OCDATADDS: if(root->octype != OC_Dataset) {THROWCHK(stat=OC_EDATADDS); goto unwind;} /* Modify the tree kind */ tree->dxdclass = OCDATADDS; break; default: return OC_EINVAL; } if(kind != OCDAS) { /* Process ocnodes to fix various semantic issues*/ computeocsemantics(tree->nodes); } /* Process ocnodes to compute name info*/ computeocfullnames(tree->root); if(kind != OCDAS) { /* Process ocnodes to compute sizes when uniform in size*/ ocsetsize(tree->root); } if(kind == OCDATADDS) { tree->data.xdrs = (XDR*)ocmalloc(sizeof(XDR)); MEMCHECK(tree->data.xdrs,OC_ENOMEM); #ifdef OC_DISK_STORAGE ocxdrstdio_create(tree->data.xdrs,tree->data.file,XDR_DECODE); #else xdrmem_create(tree->data.xdrs,tree->data.xdrdata,tree->data.datasize,XDR_DECODE); #endif if(!xdr_setpos(tree->data.xdrs,tree->data.bod)) return xdrerror(); } #ifdef OC_DISK_STORAGE if(ocdebug == 0 && tree->data.filename != NULL) { unlink(tree->data.filename); } #endif /* Put root into the state->trees list */ oclistpush(state->trees,(ocelem)root); if(rootp) *rootp = root; return stat; unwind: ocfreetree(tree); return THROW(stat); }
static int occompileprim(OCstate* state, OCnode* xnode, OCmemdata** memdatap, XDR* xdrs) { unsigned int xdrcount,i; size_t nelements = 0; OCerror ocstat = OC_NOERR; OCmemdata* memdata = NULL; OCASSERT((xnode->octype == OC_Primitive)); /* Use the count from the datadds */ nelements = totaldimsize(xnode); if(xnode->array.rank > 0) { /* Get first copy of the dimension count */ if(!xdr_u_int(xdrs,&xdrcount)) {ocstat = OC_EXDR; goto fail;} if(xdrcount != nelements) {ocstat=OC_EINVALCOORDS; goto fail;} if(xnode->etype != OC_String && xnode->etype != OC_URL) { /* Get second copy of the dimension count */ if(!xdr_u_int(xdrs,&xdrcount)) {ocstat = OC_EXDR; goto fail;} if(xdrcount != nelements) {ocstat=OC_EINVALCOORDS; goto fail;} } } else { nelements = 1; xdrcount = 1; } memdata = makememdata(xnode->octype,xnode->etype,nelements); MEMCHECK(memdata,OC_ENOMEM); memdata->mode = (xnode->array.rank > 0?Dimmode:Datamode); switch (xnode->etype) { case OC_String: case OC_URL: {/* Get the array of strings and store pointers in buf */ char** dst = (char**)memdata->data.data; for(i=0;i<xdrcount;i++) { char* s = NULL; if(!xdr_string(xdrs,(void*)&s,OC_INT32_MAX)) {ocstat = OC_EXDR; goto fail;} dst[i] = s; } } break; case OC_Byte: case OC_UByte: case OC_Char: { if(xnode->array.rank == 0) { /* Single unpacked character/byte */ union {unsigned int i; char c[BYTES_PER_XDR_UNIT];} u; if(!xdr_opaque(xdrs,u.c,BYTES_PER_XDR_UNIT)) {ocstat = OC_EXDR; goto fail;} u.i = ocntoh(u.i); memdata->data.data[0] = (char)u.i; } else { /* Packed characters; count will have already been read */ char* dst = memdata->data.data; if(!xdr_opaque(xdrs,dst,xdrcount)) {ocstat = OC_EXDR; goto fail;} } } break; case OC_Int16: case OC_UInt16: { unsigned short* dst = (unsigned short*)memdata->data.data; unsigned int* src; size_t xdrsize = xdrcount*BYTES_PER_XDR_UNIT; src = (unsigned int*)ocmalloc(xdrsize); if(!xdr_opaque(xdrs,(char*)src,xdrsize)) {ocfree(src); ocstat = OC_EXDR; goto fail;} if(!oc_network_order) { for(i=0;i<xdrcount;i++) { /* Write in place */ unsigned int hostint = src[i]; swapinline(dst[i],hostint); } } ocfree(src); } break; case OC_Int32: case OC_UInt32: case OC_Float32: { unsigned int* dst = (unsigned int*)memdata->data.data; size_t xdrsize = xdrcount*BYTES_PER_XDR_UNIT; if(!xdr_opaque(xdrs,(char*)dst,xdrsize)) {ocstat = OC_EXDR; goto fail;} if(!oc_network_order) { for(i=0;i<xdrcount;i++) { unsigned int hostint = dst[i]; swapinline(dst[i],hostint); } } } break; case OC_Int64: case OC_UInt64: case OC_Float64: { unsigned int* dst = (unsigned int*)memdata->data.data; size_t xdrsize = 2*xdrcount*BYTES_PER_XDR_UNIT; if(!xdr_opaque(xdrs,(char*)dst,xdrsize)) {ocstat = OC_EXDR; goto fail;} if(!oc_network_order) { for(i=0;i<2*xdrcount;i++) { unsigned int hostint = dst[i]; swapinline(dst[i],hostint); } } if(oc_invert_xdr_double) { /* May need to invert each pair */ for(i=0;i<2*xdrcount;i+=2) { unsigned int tmp = dst[i]; dst[i] = dst[i+1]; dst[i+1] = tmp; } } } break; default: OCPANIC1("unexpected etype: %d",xnode->etype); } /* switch */ /*ok:*/ if(memdatap) *memdatap = memdata; return THROW(ocstat); fail: freeocmemdata(memdata); return THROW(ocstat); }