1)synchronize with original oc2 2) add some convenience functions

This commit is contained in:
Dennis Heimbigner 2013-01-29 21:22:05 +00:00
parent c20baac22b
commit 460ac331e0
2 changed files with 178 additions and 15 deletions

113
oc2/oc.c
View File

@ -451,6 +451,7 @@ of a node that itself is a container (Dataset, Structure, Sequence, or Grid)
\retval OC_NOERR The procedure executed normally.
\retval OC_EINDEX The index was greater than the number of fields.
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
\retval OC_EBADTYPE The dds node is not a container node.
*/
OCerror
@ -483,6 +484,7 @@ Alias for oc_dds_ithfield.
\retval OC_NOERR The procedure executed normally.
\retval OC_EINDEX The index was greater than the number of fields.
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
\retval OC_EBADTYPE The dds node is not a container node.
*/
OCerror
@ -530,6 +532,54 @@ oc_dds_gridmap(OCobject link, OCobject grid, size_t index, OCobject* mapnodep)
return oc_dds_ithfield(link,grid,index+1,mapnodep);
}
/*!
Obtain a dds node by name from a dds structure or dataset node.
\param[in] link The link through which the server is accessed.
\param[in] ddsnode The container node of interest.
\param[in] name The name of the field to return.
\param[out] fieldnodep A pointer into which the name'th field node is stored.
\retval OC_NOERR The procedure executed normally.
\retval OC_EINDEX No field with the given name was found.
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
*/
OCerror
oc_dds_fieldbyname(OCobject link, OCobject ddsnode, const char* name, OCobject* fieldp)
{
OCerror err = OC_NOERR;
OCnode* node;
OCVERIFY(OC_Node,ddsnode);
OCDEREF(OCnode*,node,ddsnode);
size_t count,i;
if(!iscontainer(node->octype))
return OC_EBADTYPE;
/* Search the fields to find a name match */
err = oc_dds_nsubnodes(link,ddsnode,&count);
if(err != OC_NOERR) return err;
for(i=0;i<count;i++) {
int match;
OCobject field;
char* fieldname = NULL;
err = oc_dds_ithfield(link,ddsnode,i,&field);
if(err != OC_NOERR) return err;
// Get the field's name
err = oc_dds_name(link,field,&fieldname);
if(err != OC_NOERR) return err;
match = strcmp(name,fieldname);
if(fieldname != NULL) free(fieldname);
if(match == 0) {
if(fieldp) *fieldp = field;
return OC_NOERR;
}
}
return OC_EINDEX; /* name was not found */
}
/*!
Obtain the dimension nodes (of octype OC_Dimension)
associated with the node of interest.
@ -830,6 +880,8 @@ oc_merge_das(OCobject link, OCobject dasroot, OCobject ddsroot)
/*!
Obtain the datanode root associated with a DataDDS tree.
Do not confuse this with oc_data_root.
This procedure, given the DDS tree root, gets the data tree root.
\param[in] link The link through which the server is accessed.
\param[in] ddsroot The DataDDS tree root.
@ -840,7 +892,7 @@ Obtain the datanode root associated with a DataDDS tree.
*/
OCerror
oc_data_getroot(OCobject link, OCobject ddsroot, OCobject* datarootp)
oc_dds_getdataroot(OCobject link, OCobject ddsroot, OCobject* datarootp)
{
OCerror ocerr = OC_NOERR;
OCstate* state;
@ -871,6 +923,7 @@ of a data node instance that itself is a container instance.
\retval OC_NOERR The procedure executed normally.
\retval OC_EINDEX The index was greater than the number of fields.
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
\retval OC_EBADTYPE The data node is not a container node.
*/
OCerror
@ -892,6 +945,62 @@ oc_data_ithfield(OCobject link, OCobject datanode, size_t index, OCobject* field
return ocerr;
}
/*!
Obtain a data node by name from a container data node.
\param[in] link The link through which the server is accessed.
\param[in] datanode The container data node instance of interest.
\param[in] name The name of the field instance to return.
\param[out] fieldp A pointer into which the i'th field instance is stored.
\retval OC_NOERR The procedure executed normally.
\retval OC_EINDEX No field with the given name was found.
\retval OC_EINVAL One of the arguments (link, etc.) was invalid.
\retval OC_EBADTYPE The data node is not a container node.
*/
OCerror
oc_data_fieldbyname(OCobject link, OCobject datanode, const char* name, OCobject* fieldp)
{
OCerror err = OC_NOERR;
OCstate* state;
OCdata* data;
OCVERIFY(OC_State,link);
OCDEREF(OCstate*,state,link);
OCVERIFY(OC_Data,datanode);
OCDEREF(OCdata*,data,datanode);
size_t count,i;
OCobject ddsnode;
/* Get the dds node for this datanode */
err = oc_data_ddsnode(link,datanode,&ddsnode);
if(err != OC_NOERR) return err;
/* Search the fields to find a name match */
err = oc_dds_nsubnodes(link,ddsnode,&count);
if(err != OC_NOERR) return err;
for(i=0;i<count;i++) {
int match;
OCobject field;
char* fieldname = NULL;
err = oc_dds_ithfield(link,ddsnode,i,&field);
if(err != OC_NOERR) return err;
// Get the field's name
err = oc_dds_name(link,field,&fieldname);
if(err != OC_NOERR) return err;
match = strcmp(name,fieldname);
if(fieldname != NULL) free(fieldname);
if(match == 0) {
/* Get the ith datasubnode */
err = oc_data_ithfield(link,datanode,i,&field);
if(err != OC_NOERR) return err;
if(fieldp) *fieldp = field;
return OC_NOERR;
}
}
return OC_EINDEX; /* name was not found */
}
/*!
Obtain the data instance corresponding to the array field
of a Grid container instance.
@ -968,6 +1077,8 @@ oc_data_container(OCobject link, OCobject datanode, OCobject* containerp)
/*!
Obtain the data instance corresponding to the root of the tree
of which the specified instance object is a part.
Do not confuse this with oc_dds_getdataroot.
This procedure, given any node in a data tree, get the root of that tree.
\param[in] link The link through which the server is accessed.
\param[in] datanode The data instance of interest

View File

@ -245,10 +245,27 @@ extern OCerror oc_dds_container(OClink,OCddsnode,OCddsnode*);
if there is no such node; return OC_EBADTYPE if node is not
a container
*/
extern OCerror oc_dds_ithfield(OClink, OCddsnode, size_t index, OCddsnode* dimids);
extern OCerror oc_dds_ithfield(OClink, OCddsnode, size_t index, OCddsnode* ithfieldp);
/* Alias for oc_dds_ithfield */
extern OCerror oc_dds_ithsubnode(OClink, OCddsnode, size_t index, OCddsnode* dimids);
extern OCerror oc_dds_ithsubnode(OClink, OCddsnode, size_t, OCddsnode*);
/* Convenience functions that are just combinations of ithfield with other functions */
/* Return the grid array dds node from the specified grid node*/
extern OCerror oc_dds_gridarray(OClink, OCddsnode grid, OCddsnode* arrayp);
/* Return the i'th grid map dds node from the specified grid dds node.
NOTE: Map indices start at ZERO.
*/
extern OCerror oc_dds_gridmap(OClink, OCddsnode grid, size_t index, OCddsnode* mapp);
/* Retrieve a dds node by name from a dds structure or dataset node.
return OC_EBADTYPE if node is not a container,
return OC_EINDEX if no field by the given name is found.
*/
extern OCerror oc_dds_fieldbyname(OClink, OCddsnode, const char* name, OCddsnode* fieldp);
/* Return the dimension nodes, if any, associated with a given DDS node */
/* Caller must allocate and free the vector for dimids */
@ -305,29 +322,64 @@ extern OCerror oc_dds_free(OClink, OCddsnode);
/**************************************************/
/* Data Procedures */
/* Get the root data of datadds */
extern OCerror oc_data_getroot(OClink, OCddsnode treeroot, OCdatanode* rootp);
/* Given the DDS tree root, get the root data of datadds */
extern OCerror oc_dds_getdataroot(OClink, OCddsnode treeroot, OCdatanode* rootp);
/* Return an data for the i'th field of the specified container data */
/* Alias for oc_dds_getdataroot */
#define oc_data_getroot oc_dds_getdataroot
/* Return the data of the container for the specified data.
If it does not exist, then return NULL.
In effect this procedure allows one to walk up the datatree one level.
*/
extern OCerror oc_data_container(OClink, OCdatanode data, OCdatanode* containerp);
/* Return the root node of the data tree that contains the specified data node.
In effect this procedure allows one to walk to the root of the datatree
containing the specified datanode.
*/
extern OCerror oc_data_root(OClink, OCdatanode data, OCdatanode* rootp);
/*
There are multiple ways to walk down a level in a data tree
depending on what kind of node we are currently visiting.
The possibilities are:
1. current node is the data for a structure or dataset node:
=> oc_data_ithfield -- get the data node corresponding
to the ith field of the structure
2. current node is the data for a grid node:
=> oc_data_gridarray -- get the data node for the grid array
=> oc_data_gridmap -- get the data node for the ith grid map
3. current node is the data for an array of structures
=> oc_data_ithelement -- get the data node corresponding to
the i'th structure in the array
If the structure is scalar, then the indices
are ignored.
4. current node is the data for a sequence
=> oc_data_ithrecord -- get the data node corresponding to
the i'th record in the sequence
Note that the above only apply to compound objects. Once
you have the data node for an atomic types object (dimensioned
or scalar), you can read its contents using oc_data_read
or oc_data_readscalar.
*/
/* Return the data node for the i'th field of the specified container data */
extern OCerror oc_data_ithfield(OClink, OCdatanode container, size_t index,
OCdatanode* fieldp);
/* Retrieve the data node by name from a container data node */
extern OCerror oc_dat_fieldbyname(OClink, OCdatanode, const char* name, OCdatanode* fieldp);
/* Return the grid array data for the specified grid data */
extern OCerror oc_data_gridarray(OClink, OCdatanode grid, OCdatanode* arrayp);
/* Return the i'th grid map data for the specified grid data.
Map indices start at zero.
NOTE: Map indices start at ZERO.
*/
extern OCerror oc_data_gridmap(OClink, OCdatanode grid, size_t index, OCdatanode* mapp);
/* Return the data of the container for the specified data.
If it does not exist, then return OCNULL.
*/
extern OCerror oc_data_container(OClink, OCdatanode data, OCdatanode* containerp);
/* Return the data of the root for the specified data. */
extern OCerror oc_data_root(OClink, OCdatanode data, OCdatanode* rootp);
/* Return the data of a dimensioned Structure corresponding
to the element specified by the indices.
*/