OC Updated for version 2.0
oc.c
Go to the documentation of this file.
00001 /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
00002    See the COPYRIGHT file for more information. */
00003 
00004 #include "config.h"
00005 #include <stdlib.h>
00006 #include <assert.h>
00007 #include <string.h>
00008 
00009 #include "ocinternal.h"
00010 #include "ocdebug.h"
00011 #include "ocdump.h"
00012 #include "oclog.h"
00013 #include "occlientparams.h"
00014 
00015 #undef TRACK
00016 
00017 /**************************************************/
00018 
00019 static int ocinitialized = 0;
00020 
00021 /**************************************************/
00022 /* Track legal ids */
00023 
00024 #define ocverify(o) ((o) != NULL && (((OCheader*)(o))->magic == OCMAGIC)?1:0)
00025 
00026 #define ocverifyclass(o,cl) ((o) != NULL && (((OCheader*)(o))->occlass == cl)?1:0)
00027 
00028 #define OCVERIFYX(k,x,r) if(!ocverify(x)||!ocverifyclass(x,k)) {return (r);}
00029 #define OCVERIFY(k,x) OCVERIFYX(k,x,OCTHROW(OC_EINVAL))
00030 
00031 #define OCDEREF(T,s,x) (s)=(T)(x)
00032 
00033 /**************************************************/
00034 
00035 static int
00036 oc_initialize(void)
00037 {
00038     int status = OC_NOERR;
00039     status = ocinternalinitialize();
00040     ocinitialized = 1;
00041     return status;
00042 }
00043 
00044 
00045 /**************************************************/
00065 OCerror
00066 oc_open(const char* url, OCobject* linkp)
00067 {
00068     OCerror ocerr;
00069     OCstate* state;
00070     if(!ocinitialized) oc_initialize();
00071     ocerr = ocopen(&state,url);
00072     if(ocerr == OC_NOERR && linkp) {
00073     *linkp = (OCobject)(state);
00074     }
00075     return ocerr;
00076 }
00077 
00088 OCerror
00089 oc_close(OCobject link)
00090 {
00091     OCstate* state;
00092     OCVERIFY(OC_State,link);
00093     OCDEREF(OCstate*,state,link);
00094     occlose(state);
00095     return OC_NOERR;
00096 }
00097 
00125 OCerror
00126 oc_fetch(OCobject link, const char* constraint,
00127                  OCdxd dxdkind, OCflags flags, OCobject* rootp)
00128 {
00129     OCstate* state;
00130     OCerror ocerr = OC_NOERR;
00131     OCnode* root;
00132     OCVERIFY(OC_State,link);
00133     OCDEREF(OCstate*,state,link);
00134 
00135     ocerr = ocfetch(state,constraint,dxdkind,flags,&root);
00136     if(ocerr) return ocerr;
00137 
00138     if(rootp) *rootp = (OCobject)(root);
00139     return ocerr;
00140 }
00141 
00142 
00157 OCerror
00158 oc_root_free(OCobject link, OCobject ddsroot)
00159 {
00160     OCnode* root;
00161     OCVERIFY(OC_Node,ddsroot);
00162     OCDEREF(OCnode*,root,ddsroot);
00163 
00164     ocroot_free(root);
00165     return OC_NOERR;
00166 }
00167 
00179 const char*
00180 oc_tree_text(OCobject link, OCobject ddsroot)
00181 {
00182     OCnode* root;
00183     OCVERIFYX(OC_Node,ddsroot,NULL);
00184     OCDEREF(OCnode*,root,ddsroot);
00185 
00186     if(root == NULL) return NULL;
00187     root = root->root;
00188     if(root == NULL) return NULL;
00189     return root->tree->text;
00190 }
00191 
00227 OCerror
00228 oc_dds_properties(OCobject link,
00229       OCobject ddsnode,
00230       char** namep,
00231       OCtype* octypep,
00232       OCtype* atomtypep, /* if objecttype == OC_Atomic */
00233       OCobject* containerp,
00234       size_t* rankp,
00235       size_t* nsubnodesp,
00236       size_t* nattrp)
00237 {
00238     OCnode* node;
00239     OCVERIFY(OC_Node,ddsnode);
00240     OCDEREF(OCnode*,node,ddsnode);
00241 
00242     if(namep) *namep = nulldup(node->name);
00243     if(octypep) *octypep = node->octype;
00244     if(etypep) *etypep = node->etype;
00245     if(rankp) *rankp = node->array.rank;
00246     if(containerp) *containerp = (OCobject)node->container;    
00247     if(nsubnodesp) *nsubnodesp = oclistlength(node->subnodes);
00248     if(nattrp) {
00249         if(node->octype == OC_Attribute) {
00250             *nattrp = oclistlength(node->att.values);
00251         } else {
00252             *nattrp = oclistlength(node->attributes);
00253     }
00254     }
00255     return OC_NOERR;
00256 }
00257 
00270 OCerror
00271 oc_dds_name(OCobject link, OCobject ddsnode, char** namep)
00272 {
00273     OCstate* state;
00274     OCnode* node;
00275     OCVERIFY(OC_State,link);
00276     OCDEREF(OCstate*,state,link);
00277     OCVERIFY(OC_Node,ddsnode);
00278     OCDEREF(OCnode*,node,ddsnode);
00279 
00280     if(state == NULL || node == NULL) return OCTHROW(OC_EINVAL);
00281     if(namep) *namep = nulldup(node->name);
00282     return OC_NOERR;
00283 }
00284 
00296 OCerror
00297 oc_dds_nsubnodes(OCobject link, OCobject ddsnode, size_t* nsubnodesp)
00298 {
00299     OCnode* node;
00300     OCVERIFY(OC_Node,ddsnode);
00301     OCDEREF(OCnode*,node,ddsnode);
00302 
00303     if(nsubnodesp) *nsubnodesp = oclistlength(node->subnodes);
00304     return OC_NOERR;
00305 }
00306 
00317 OCerror
00318 oc_dds_atomictype(OCobject link, OCobject ddsnode, OCtype* typep)
00319 {
00320     OCnode* node;
00321     OCVERIFY(OC_Node,ddsnode);
00322     OCDEREF(OCnode*,node,ddsnode);
00323 
00324     if(typep) *typep = node->etype;
00325     return OC_NOERR;
00326 }
00327 
00338 OCerror
00339 oc_dds_class(OCobject link, OCobject ddsnode, OCtype* typep)
00340 {
00341     OCnode* node;
00342     OCVERIFY(OC_Node,ddsnode);
00343     OCDEREF(OCnode*,node,ddsnode);
00344 
00345     if(typep) *typep = node->octype;
00346     return OC_NOERR;
00347 }
00348 
00359 OCerror
00360 oc_dds_rank(OCobject link, OCobject ddsnode, size_t* rankp)
00361 {
00362     OCnode* node;
00363     OCVERIFY(OC_Node,ddsnode);
00364     OCDEREF(OCnode*,node,ddsnode);
00365 
00366     if(rankp) *rankp = node->array.rank;
00367     return OC_NOERR;
00368 }
00369 
00380 OCerror
00381 oc_dds_attr_count(OCobject link, OCobject ddsnode, size_t* nattrp)
00382 {
00383     OCnode* node;
00384     OCVERIFY(OC_Node,ddsnode);
00385     OCDEREF(OCnode*,node,ddsnode);
00386 
00387     if(nattrp) {
00388         if(node->octype == OC_Attribute) {
00389             *nattrp = oclistlength(node->att.values);
00390         } else {
00391             *nattrp = oclistlength(node->attributes);
00392     }
00393     }
00394     return OC_NOERR;
00395 }
00396 
00408 OCerror
00409 oc_dds_root(OCobject link, OCobject ddsnode, OCobject* rootp)
00410 {
00411     OCnode* node;
00412     OCVERIFY(OC_Node,ddsnode);
00413     OCDEREF(OCnode*,node,ddsnode);
00414 
00415     if(rootp) *rootp = (OCobject)node->root;
00416     return OC_NOERR;
00417 }
00418 
00430 OCerror
00431 oc_dds_container(OCobject link, OCobject ddsnode, OCobject* containerp)
00432 {
00433     OCnode* node;
00434     OCVERIFY(OC_Node,ddsnode);
00435     OCDEREF(OCnode*,node,ddsnode);
00436 
00437     if(containerp) *containerp = (OCobject)node->container;
00438     return OC_NOERR;
00439 }
00440 
00455 OCerror
00456 oc_dds_ithfield(OCobject link, OCobject ddsnode, size_t index, OCobject* fieldnodep)
00457 {
00458     OCnode* node;
00459     OCnode* field;
00460     OCVERIFY(OC_Node,ddsnode);
00461     OCDEREF(OCnode*,node,ddsnode);
00462 
00463     if(!iscontainer(node->octype))
00464     return OC_EBADTYPE;
00465 
00466     if(index >= oclistlength(node->subnodes))
00467     return OC_EINDEX;
00468 
00469     field = (OCnode*)oclistget(node->subnodes,index);
00470     if(fieldp) *fieldp = (OCobject)field;
00471     return OC_NOERR;
00472 }
00473 
00486 OCerror
00487 oc_dds_gridarray(OCobject link, OCobject grid, OCobject* arraynodep)
00488 {
00489     return oc_dds_ithfield(link,grid,0,arrayp);
00490 }
00491 
00507 OCerror
00508 oc_dds_gridmap(OCobject link, OCobject grid, size_t index, OCobject* mapnodep)
00509 {
00510     return oc_dds_ithfield(link,grid,index+1,mapp);
00511 }
00512 
00526 OCerror
00527 oc_dds_dimensions(OCobject link, OCobject ddsnode, OCobject* dims)
00528 {
00529     OCnode* node;
00530     size_t i;
00531 
00532     OCVERIFY(OC_Node,ddsnode);
00533     OCDEREF(OCnode*,node,ddsnode);
00534 
00535     if(node->array.rank == 0) return OCTHROW(OC_ESCALAR);
00536     if(dims != NULL) {
00537         for(i=0;i<node->array.rank;i++) {
00538             OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i);
00539         dims[i] = (OCobject)dim;
00540     }   
00541     }
00542     return OC_NOERR;
00543 }
00544 
00559 OCerror
00560 oc_dds_ithdimension(OCobject link, OCobject ddsnode, size_t index, OCobject* dimidp)
00561 {
00562     OCnode* node;
00563     OCobject dimid = NULL;
00564     OCVERIFY(OC_Node,ddsnode);
00565     OCDEREF(OCnode*,node,ddsnode);
00566 
00567     if(node->array.rank == 0) return OCTHROW(OC_ESCALAR);
00568     if(index >= node->array.rank) return OCTHROW(OC_EINDEX);
00569     dimid = (OCobject)oclistget(node->array.dimensions,index);
00570     if(dimidp) *dimidp = dimid;
00571     return OC_NOERR;
00572 }
00573 
00589 OCerror
00590 oc_dimension_properties(OCobject link, OCobject ddsnode, size_t* sizep, char** namep)
00591 {
00592     OCnode* dim;
00593     OCVERIFY(OC_Node,ddsnode);
00594     OCDEREF(OCnode*,dim,ddsnode);
00595 
00596     if(dim->octype != OC_Dimension) return OCTHROW(OC_EBADTYPE);
00597     if(sizep) *sizep = dim->dim.declsize;
00598     if(namep) *namep = nulldup(dim->name);
00599     return OC_NOERR;
00600 }
00601 
00617 OCerror
00618 oc_dds_dimensionsizes(OCobject link, OCobject ddsnode, size_t* dimsizes)
00619 {
00620     OCnode* node;
00621     OCVERIFY(OC_Node,ddsnode);
00622     OCDEREF(OCnode*,node,ddsnode);
00623 
00624     if(node->array.rank == 0) return OCTHROW(OC_ESCALAR);
00625     if(dimsizes != NULL) {
00626     int i;
00627         for(i=0;i<node->array.rank;i++) {
00628             OCnode* dim = (OCnode*)oclistget(node->array.dimensions,i);
00629         dimsizes[i] = dim->dim.declsize;
00630     }   
00631     }
00632     return OC_NOERR;
00633 }
00634 
00662 OCerror
00663 oc_dds_attr(OCobject link, OCobject ddsnode, size_t index,
00664                char** namep, OCtype* octypep,
00665                size_t* nvaluesp, char** strings)
00666 {
00667     OCnode* node;
00668     OCattribute* attr;
00669     size_t nattrs;
00670     OCVERIFY(OC_Node,ddsnode);
00671     OCDEREF(OCnode*,node,ddsnode);
00672 
00673     nattrs = oclistlength(node->attributes);
00674     if(index >= nattrs) return OCTHROW(OC_EINDEX);
00675     attr = (OCattribute*)oclistget(node->attributes,index);
00676     if(namep) *namep = strdup(attr->name);
00677     if(octypep) *octypep = attr->etype;
00678     if(nvaluesp) *nvaluesp = attr->nvalues;
00679     if(strings) {
00680     if(attr->nvalues > 0) {
00681         for(i=0;i<attr->nvalues;i++)
00682             strings[i] = nulldup(attr->values[i]);
00683     }
00684     }
00685     return OC_NOERR;    
00686 }
00687 
00696 void
00697 oc_reclaim_strings(size_t n, char** svec)
00698 {
00699     int i;
00700     for(i=0;i<n;i++) if(svec[i] != NULL) free(svec[i]);
00701 }
00702 
00716 OCerror
00717 oc_das_attr_count(OCobject link, OCobject dasnode, size_t* nvaluesp)
00718 {
00719     OCnode* attr;
00720     OCVERIFY(OC_Node,dasnode);
00721     OCDEREF(OCnode*,attr,dasnode);
00722     if(attr->octype != OC_Attribute) return OCTHROW(OC_EBADTYPE);
00723     if(nvaluesp) *nvaluesp = oclistlength(attr->att.values);
00724     return OC_NOERR;
00725 }
00726 
00749 OCerror
00750 oc_das_attr(OCobject link, OCobject dasnode, size_t index, OCtype* etypep, char** valuep)
00751 {
00752     OCnode* attr;
00753     size_t nvalues;
00754     OCVERIFY(OC_Node,dasnode);
00755     OCDEREF(OCnode*,attr,dasnode);
00756 
00757     if(attr->octype != OC_Attribute) return OCTHROW(OC_EBADTYPE);
00758     nvalues = oclistlength(attr->att.values);
00759     if(index >= nvalues) return OCTHROW(OC_EINDEX);
00760     if(etypep) *etypep = attr->etype;
00761     if(valuep) *valuep = nulldup((char*)oclistget(attr->att.values,));
00762     return OC_NOERR;
00763 }
00764 
00767 /**************************************************/
00787 OCerror
00788 oc_merge_das(OCobject link, OCobject dasroot, OCobject ddsroot)
00789 {
00790     OCstate* state;
00791     OCnode* das;
00792     OCnode* dds;
00793     OCVERIFY(OC_State,link);
00794     OCDEREF(OCstate*,state,link);
00795     OCVERIFY(OC_Node,dasroot);
00796     OCDEREF(OCnode*,das,dasroot);
00797     OCVERIFY(OC_Node,ddsroot);
00798     OCDEREF(OCnode*,dds,ddsroot);
00799 
00800     return ocddsdasmerge(state,das,dds);
00801 }
00802 
00805 /**************************************************/
00806 
00821 OCerror
00822 oc_data_getroot(OCobject link, OCobject ddsroot, OCobject* datarootp)
00823 {
00824     OCerror ocerr = OC_NOERR;
00825     OCstate* state;
00826     OCnode* root;
00827     OCdata* droot;
00828     OCVERIFY(OC_State,link);
00829     OCDEREF(OCstate*,state,link);
00830     OCVERIFY(OC_Node,ddsroot);
00831     OCDEREF(OCnode*,root,ddsroot);
00832 
00833     if(datarootp == NULL)
00834     return OCTHROW(OC_EINVAL);
00835     ocerr = ocdata_getroot(state,root,&droot);
00836     if(ocerr == OC_NOERR && drootp)
00837     *datarootp = (OCobject)droot;
00838     return ocerr;
00839 }
00840 
00855 OCerror
00856 oc_data_ithfield(OCobject link, OCobject datanode, size_t index, OCobject* fieldp)
00857 {
00858     OCerror ocerr = OC_NOERR;
00859     OCstate* state;
00860     OCdata* data;
00861     OCdata* field;
00862     OCVERIFY(OC_State,link);
00863     OCDEREF(OCstate*,state,link);
00864     OCVERIFY(OC_Data,datanode);
00865     OCDEREF(OCdata*,data,datanode);
00866 
00867     if(fieldp == NULL) return OCTHROW(OC_EINVAL);
00868     ocerr = ocdata_ithfield(state,data,index,&field);
00869     if(ocerr == OC_NOERR)
00870     *fieldp = (OCobject)field;
00871     return ocerr;
00872 }
00873 
00887 OCerror
00888 oc_data_gridarray(OCobject link, OCobject grid, OCobject* arraydatap)
00889 {
00890     return oc_data_ithfield(link,grid,0,arrayp);
00891 }
00892 
00908 OCerror
00909 oc_data_gridmap(OCobject link, OCobject grid, size_t index, OCobject* mapdatap)
00910 {
00911     return oc_data_ithfield(link,grid,index+1,mapp);
00912 }
00913 
00928 OCerror
00929 oc_data_container(OCobject link,  OCobject datanode, OCobject* containerp)
00930 {
00931     OCerror ocerr = OC_NOERR;
00932     OCstate* state;
00933     OCdata* data;
00934     OCdata* container;
00935     OCVERIFY(OC_State,link);
00936     OCDEREF(OCstate*,state,link);
00937     OCVERIFY(OC_Data,datanode);
00938     OCDEREF(OCdata*,data,datanode);
00939 
00940     if(containerp == NULL) return OCTHROW(OC_EINVAL);
00941     ocerr = ocdata_container(state,data,&container);
00942     if(ocerr == OC_NOERR)
00943     *containerp = (OCobject)container;
00944     return ocerr;
00945 }
00946 
00959 OCerror
00960 oc_data_root(OCobject link, OCobject datanode, OCobject* rootp)
00961 {
00962     OCerror ocerr = OC_NOERR;
00963     OCstate* state;
00964     OCdata* data;
00965     OCdata* root;
00966     OCVERIFY(OC_State,link);
00967     OCDEREF(OCstate*,state,link);
00968     OCVERIFY(OC_Data,datanode);
00969     OCDEREF(OCdata*,data,datanode);
00970 
00971     if(rootp == NULL) return OCTHROW(OC_EINVAL);
00972     ocerr = ocdata_root(state,data,&root);
00973     if(ocerr == OC_NOERR)
00974     *rootp = (OCobject)root;
00975     return ocerr;
00976 }
00977 
00995 OCerror
00996 oc_data_ithelement(OCobject link, OCobject datanode, size_t* indices, OCobject* elementp)
00997 {
00998     OCerror ocerr = OC_NOERR;
00999     OCstate* state;
01000     OCdata* data;
01001     OCdata* element;
01002     OCVERIFY(OC_State,link);
01003     OCDEREF(OCstate*,state,link);
01004     OCVERIFY(OC_Data,datanode);
01005     OCDEREF(OCdata*,data,datanode);
01006 
01007     if(indices == NULL || elementp == NULL) return OCTHROW(OC_EINVAL);
01008     ocerr = ocdata_ithelement(state,data,indices,&element);
01009     if(ocerr == OC_NOERR)
01010     *elementp = (OCobject)element;
01011     return ocerr;
01012 }
01013 
01030 extern OCerror oc_data_ithrecord(OCobject link, OCobject datanode, size_t index, OCobject* recordp)
01031 {
01032     OCerror ocerr = OC_NOERR;
01033     OCstate* state;
01034     OCdata* data;
01035     OCdata* record;
01036     OCVERIFY(OC_State,link);
01037     OCDEREF(OCstate*,state,link);
01038     OCVERIFY(OC_Data,datanode);
01039     OCDEREF(OCdata*,data,datanode);
01040 
01041     if(recordp == NULL) return OCTHROW(OC_EINVAL);
01042     ocerr = ocdata_ithrecord(state,data,index,&record);
01043     if(ocerr == OC_NOERR)
01044     *recordp = (OCobject)record;
01045     return ocerr;
01046 }
01047 
01066 OCerror
01067 oc_data_position(OCobject link, OCobject datanode, size_t* indices)
01068 {
01069     OCstate* state;
01070     OCdata* data;
01071     OCVERIFY(OC_State,link);
01072     OCDEREF(OCstate*,state,link);
01073     OCVERIFY(OC_Data,datanode);
01074     OCDEREF(OCdata*,data,datanode);
01075     if(indices == NULL) return OCTHROW(OC_EINVAL);
01076     return ocdata_position(state,data,indices);
01077 }
01078 
01097 OCerror
01098 oc_data_recordcount(OCobject link, OCobject datanode, size_t* countp)
01099 {
01100     OCstate* state;
01101     OCdata* data;
01102     OCVERIFY(OC_State,link);
01103     OCDEREF(OCstate*,state,link);
01104     OCVERIFY(OC_Data,datanode);
01105     OCDEREF(OCdata*,data,datanode);
01106     if(countp == NULL) return OCTHROW(OC_EINVAL);
01107     return ocdata_recordcount(state,data,countp);
01108 }
01109 
01122 OCerror
01123 oc_data_ddsnode(OCobject link, OCobject datanode, OCobject* nodep)
01124 {
01125     OCerror ocerr = OC_NOERR;
01126     OCdata* data;
01127     OCVERIFY(OC_Data,datanode);
01128     OCDEREF(OCdata*,data,datanode);
01129 
01130     OCASSERT(data->template != NULL);
01131     if(nodep == NULL) ocerr = OC_EINVAL;
01132     else *nodep = (OCobject)data->template;
01133     return ocerr;
01134 }
01135 
01150 OCerror
01151 oc_data_octype(OCobject link, OCobject datanode, OCtype* typep)
01152 {
01153     OCerror ocerr = OC_NOERR;
01154     OCdata* data;
01155     OCVERIFY(OC_Data,datanode);
01156     OCDEREF(OCdata*,data,datanode);
01157 
01158     OCASSERT(data->template != NULL);
01159     if(typep == NULL) ocerr = OC_EINVAL;
01160     else *typep = data->template->octype;
01161     return ocerr;
01162 }
01163 
01177 int
01178 oc_data_indexable(OCobject link, OCobject datanode)
01179 {
01180     OCdata* data;
01181     OCVERIFY(OC_Data,datanode);
01182     OCDEREF(OCdata*,data,datanode);
01183 
01184     return (fisset(data->datamode,OCDT_ARRAY)
01185         || fisset(data->datamode,OCDT_SEQUENCE)) ? 1 : 0;
01186 }
01187 
01201 int
01202 oc_data_indexed(OCobject link, OCobject datanode)
01203 {
01204     OCdata* data;
01205     OCVERIFY(OC_Data,datanode);
01206     OCDEREF(OCdata*,data,datanode);
01207 
01208     return (fisset(data->datamode,OCDT_ELEMENT)
01209         || fisset(data->datamode,OCDT_RECORD)) ? 1 : 0;
01210 }
01211 
01212 /**************************************************/
01213 
01245 OCerror
01246 oc_data_read(OCobject link, OCobject datanode,
01247                  size_t* start, size_t* edges,
01248              size_t memsize, void* memory)
01249 {
01250     OCstate* state;
01251     OCdata* data;
01252     OCnode* template;
01253     OCerror ocerr = OC_NOERR;
01254     size_t startpoint, count, rank;
01255 
01256     OCVERIFY(OC_State,link);
01257     OCDEREF(OCstate*,state,link);
01258     OCVERIFY(OC_Data,datanode);
01259     OCDEREF(OCdata*,data,datanode);
01260 
01261     /* Do argument validation */
01262 
01263     if(memory == NULL || memsize == 0)
01264     return OC_EINVAL;
01265 
01266     template = data->template;
01267     rank = template->array.rank;
01268     if(rank == 0) {
01269     startpoint = 0;
01270     count = 1;
01271     } else if(start == NULL || edges == NULL) {
01272         return OCTHROW(OC_EINVALCOORDS);
01273     } else {/* not scalar */
01274         size_t* sizes;
01275     /* Temporary validation code */
01276     size_t endpoint;
01277     /* get dimension sizes */
01278     sizes = template->array.sizes;
01279     /* compute total number of elements to read */
01280         count = octotaldimsize(rank,edges);
01281         /* Compute start point linearized position */
01282         startpoint = ocarrayoffset(rank,sizes,start);
01283         /* Compute end point linearized position */
01284         endpoint = ocedgeoffset(rank,sizes,edges);
01285     /* validate */
01286     OCASSERT(count ==(endpoint+1));
01287     }
01288     if(count > 0)
01289         ocerr = ocdata_read(state,data,startpoint,count,memory,memsize);
01290     if(ocerr == OC_EDATADDS)
01291     ocdataddsmsg(state,template->tree);
01292     return OCTHROW(ocerr);
01293 }
01296 /**************************************************/
01297 /* OCtype Management */
01298 
01315 size_t
01316 oc_typesize(OCtype etype)
01317 {
01318     return octypesize(etype);
01319 }
01320 
01334 const char*
01335 oc_typetostring(OCtype octype)
01336 {
01337     return octypetoddsstring(octype);
01338 }
01339 
01355 OCerror
01356 oc_typeprint(OCtype etype, void* value, size_t bufsize, char* buffer)
01357 {
01358     return octypeprint(etype,buffer,bufsize,value);
01359 }
01360 
01363 /**************************************************/
01364 /* The oc_logXXX procedures are defined in oclog.c */
01365 
01366 /**************************************************/
01367 /* Miscellaneous */
01368 
01381 const char*
01382 oc_errstring(OCerror err)
01383 {
01384     return ocerrstring(err);
01385 }
01386 
01400 const char*
01401 oc_clientparam_get(OCobject link, const char* param)
01402 {
01403     OCstate* state;
01404     OCVERIFYX(OC_State,link,NULL);
01405     OCDEREF(OCstate*,state,link);
01406 
01407     return ocparamlookup(state,param);
01408 }
01409 
01410 #ifdef OCIGNORE
01411 /* Delete client parameter
01412    return value:
01413     OC_NOERR => defined; deletion performed
01414     OC_EINVAL => not already defined
01415 */
01416 OCerror
01417 oc_clientparam_delete(OCobject link, const char* param)
01418 {
01419     OCstate* state;
01420     OCVERIFY(OC_State,link);
01421     OCDEREF(OCstate*,state,link);
01422 
01423     return ocparamdelete(state->clientparams,param);
01424 }
01425 
01426 /* Insert client parameter
01427    return value:
01428     OC_NOERR => not already define; insertion performed
01429     OC_EINVAL => already defined
01430 */
01431 OCerror
01432 oc_clientparam_insert(OCobject link, const char* param, const char* value)
01433 {
01434     OCstate* state;
01435     OCVERIFY(OC_State,link);
01436     OCDEREF(OCstate*,state,link);
01437 
01438     state->clientparams = dapparaminsert(state->clientparams,param,value);
01439     return OC_NOERR;
01440 }
01441 
01442 /* Replace client parameter
01443    return value:
01444     OC_NOERR => already define; replacement performed
01445     OC_EINVAL => not already defined
01446 */
01447 OCerror
01448 oc_clientparam_replace(OCobject link, const char* param, const char* value)
01449 {
01450     OCstate* state;
01451     OCVERIFY(OC_State,link);
01452     OCDEREF(OCstate*,state,link);
01453 
01454     return dapparamreplace(state->clientparams,param,value);
01455 }
01456 #endif
01457 
01458 /**************************************************/
01459 
01485 OCerror
01486 oc_svcerrordata(OCobject link, char** codep,
01487                                char** msgp, long* httpp)
01488 {
01489     OCstate* state;
01490     OCVERIFY(OC_State,link);
01491     OCDEREF(OCstate*,state,link);
01492     return ocsvcerrordata(state,codep,msgp,httpp);
01493 }
01494 
01497 /**************************************************/
01498 /* Experimental: this is useful for the netcdf
01499    DRNO project.
01500 */
01501 
01502 /* New 10/31/2009: return the size(in bytes)
01503    of the fetched datadds.
01504 */
01505 
01506 OCerror
01507 oc_raw_xdrsize(OCobject link, OCobject ddsroot, size_t* sizep)
01508 {
01509     OCnode* root;
01510     OCerror ocerr = OC_NOERR;
01511     OCVERIFY(OC_Node,ddsroot);
01512     OCDEREF(OCnode*,root,ddsroot);
01513 
01514     if(sizep == NULL) goto done;
01515     if(root->tree == NULL || root->tree->dxdclass != OCDATADDS)
01516     {OCTHROWCHK((ocerr=OC_EINVAL)); goto done;}
01517     if(sizep) *sizep = root->tree->data.datasize;
01518 
01519 done:
01520     return ocerr;
01521 }
01522 
01523 /* Resend a url as a head request to check the Last-Modified time */
01524 OCerror
01525 oc_update_lastmodified_data(OCobject link)
01526 {
01527     OCstate* state;
01528     OCVERIFY(OC_State,link);
01529     OCDEREF(OCstate*,state,link);
01530     return ocupdatelastmodifieddata(state);
01531 }
01532 
01533 long
01534 oc_get_lastmodified_data(OCobject link)
01535 {
01536     OCstate* state;
01537     OCVERIFY(OC_State,link);
01538     OCDEREF(OCstate*,state,link);
01539     return state->datalastmodified;
01540 }
01541 
01542 int
01543 oc_dumpnode(OCobject link, OCobject ddsroot)
01544 {
01545     OCnode* root;
01546     OCerror ocerr = OC_NOERR;
01547     OCVERIFY(OC_Node,ddsroot);
01548     OCDEREF(OCnode*,root,ddsroot);
01549     ocdumpnode(root);
01550     return ocerr;
01551 }
01552 
01553 /**************************************************/
01554 /* ocx.h interface */
01555 /* Following procedures are in API, but are not
01556    externally documented.
01557 */
01558 
01559 
01560 OCerror
01561 oc_dds_dd(OCobject link, OCobject ddsroot, int level)
01562 {
01563     OCstate* state;
01564     OCnode* root;
01565     OCVERIFY(OC_State,link);
01566     OCDEREF(OCstate*,state,link);
01567     OCVERIFY(OC_Node,ddsroot);
01568     OCDEREF(OCnode*,root,ddsroot);
01569 
01570     ocdd(state,root,1,level);
01571     return OC_NOERR;
01572 }
01573 
01574 OCerror
01575 oc_dds_ddnode(OCobject link, OCobject ddsroot)
01576 {
01577     OCnode* root;
01578     OCVERIFY(OC_Node,ddsroot);
01579     OCDEREF(OCnode*,root,ddsroot);
01580 
01581     ocdumpnode(root);
01582     return OC_NOERR;
01583 }
01584 
01585 OCerror
01586 oc_data_ddpath(OCobject link, OCobject datanode, char** resultp)
01587 {
01588     OCstate* state;
01589     OCdata* data;
01590     OCbytes* buffer;
01591 
01592     OCVERIFY(OC_State,link);
01593     OCDEREF(OCstate*,state,link);
01594     OCVERIFY(OC_Data,datanode);
01595     OCDEREF(OCdata*,data,datanode);
01596 
01597     buffer = ocbytesnew();
01598     ocdumpdatapath(state,data,buffer);
01599     if(resultp) *resultp = ocbytesdup(buffer);
01600     ocbytesfree(buffer);
01601     return OC_NOERR;
01602 }
01603 
01604 OCerror
01605 oc_data_ddtree(OCobject link, OCobject ddsroot)
01606 {
01607     OCstate* state;
01608     OCdata* data;
01609     OCbytes* buffer;
01610     OCVERIFY(OC_State,link);
01611     OCDEREF(OCstate*,state,link);
01612     OCVERIFY(OC_Data,ddsroot);
01613     OCDEREF(OCdata*,data,ddsroot);
01614 
01615     buffer = ocbytesnew();
01616     ocdumpdatatree(state,data,buffer,0);
01617     fprintf(stderr,"%s\n",ocbytescontents(buffer));
01618     ocbytesfree(buffer);
01619     return OC_NOERR;
01620 }
01621 
01622 OCDT
01623 oc_data_mode(OCobject link, OCobject datanode)
01624 {
01625     OCdata* data;
01626     OCVERIFY(OC_Data,datanode);
01627     OCDEREF(OCdata*,data,datanode);
01628 
01629     return data->datamode;
01630 }
01631 
01632 /* Free up a datanode that is no longer being used;
01633    Currently does nothing
01634 */
01635 OCerror
01636 oc_data_free(OCobject link, OCobject datanode)
01637 {
01638     return OC_NOERR;
01639 }
01640 
01641 /* Free up a ddsnode that is no longer being used;
01642    Currently does nothing
01643 */
01644 OCerror
01645 oc_dds_free(OCobject link, OCobject dds0)
01646 {
01647     return OC_NOERR;
01648 }
01649