void ocfreeroot(OCnode* root) { OCtree* tree; OCstate* state; int i; if(root == NULL || root->tree == NULL) return; tree = root->tree; /* Remove the root from the state->trees list */ state = tree->state; for(i=0;i<oclistlength(state->trees);i++) { OCnode* node = (OCnode*)oclistget(state->trees,i); if(root == node) oclistremove(state->trees,i); } /* Note: it is ok if state->trees does not contain this root */ ocfreetree(tree); }
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, 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); }