cmData.h/c: Initial working version in cmtest.

This commit is contained in:
kevin 2013-05-21 11:49:24 -07:00
parent ece2c83bf7
commit 37fffdf181
2 changed files with 1022 additions and 179 deletions

932
cmData.c

File diff suppressed because it is too large Load Diff

247
cmData.h
View File

@ -8,7 +8,9 @@ extern "C" {
enum enum
{ {
kOkDtRC = cmOkRC, kOkDtRC = cmOkRC,
kCvtErrDtRC kCvtErrDtRC,
kVarArgErrDtRC,
kEolDtRC
}; };
enum enum
@ -79,9 +81,8 @@ extern "C" {
cmDataFmtId_t tid; // data format id cmDataFmtId_t tid; // data format id
unsigned flags; // unsigned flags; //
struct cmData_str* parent; // this childs parent struct cmData_str* parent; // this childs parent
struct cmData_str* sibling; // this childs sibling struct cmData_str* sibling; // this childs left sibling
unsigned allocCnt; // allocated count unsigned cnt; // array ele count
unsigned cnt; // actual count
union union
{ {
@ -120,10 +121,60 @@ extern "C" {
typedef unsigned cmDtRC_t; typedef unsigned cmDtRC_t;
extern cmData_t cmDataNull;
bool cmDataIsValue( const cmData_t* p ); bool cmDataIsValue( const cmData_t* p );
bool cmDataIsPtr( const cmData_t* p ); bool cmDataIsPtr( const cmData_t* p );
bool cmDataIsStruct( const cmData_t* p ); bool cmDataIsStruct( const cmData_t* p );
/*
TODO:
0) Figure out a error handling scheme that does not rely on
a global errno. This is not useful in multi-thread environments.
It might be ok to go with an 'all errors are fatal' model
(except in the var-args functions).
Consider the use of a context object for use with functions
that can have runtime errors or need to allocate memory.
1) Implement the canConvert and willTruncate functions.
2) Make a set of cmDataAllocXXXPtr() functions which take
a flag indicating whether or not to dynamically allocate
the array space. This will allow dynamic allocattion to
occur at runtime. Make var args functions for list and
record objects which also take this flag.
Where ever a function may be implemented using
static/dynamic allocation this flag should be present.
(e.g. string allocation for pair labels)
This choice is common enough that it may be worth
suffixing function names with a capital letter to
be clear what the functions memory policy is.
3) Come up with a var-args format which allows a
hierchy of records to be defined in one line.
4) Implement the serialization functions.
5) Implement an ascii string/parse format for writing/reading.
6) Implement fast lookup of record fields.
7) Allow for user defined types. For example a 'matrix'
data type. This might be as simple as adding an extra 'user_tid'
field to cmData_t.
8) Implement type specific cmDataGetRecordValueXXX() functions.
9) Implement cmDataIsEqual(), cmDataIsLtE(), ...
*/
bool canConvertType( cmDataFmtId_t srcId, cmDataFmtId_t dstId );
bool willTruncate( cmDataFmtId_t srcId, cmDataFmtId_t dstId );
bool canConvertObj( const cmData_t* srcObj, cmData_t* dstObj );
bool willTruncateObj(const cmData_t* srcObj, cmData_t* dstObj );
// Get the value of an object without conversion. // Get the value of an object without conversion.
// The data type id must match the return type or the // The data type id must match the return type or the
@ -179,7 +230,8 @@ extern "C" {
double* cmDataGetDoublePtr( const cmData_t* p ); double* cmDataGetDoublePtr( const cmData_t* p );
// Set the value of an existing data object. // Set the value of an existing scalar data object.
cmData_t* cmDataSetNull( cmData_t* p );
cmData_t* cmDataSetChar( cmData_t* p, char v ); cmData_t* cmDataSetChar( cmData_t* p, char v );
cmData_t* cmDataSetUChar( cmData_t* p, unsigned char v ); cmData_t* cmDataSetUChar( cmData_t* p, unsigned char v );
cmData_t* cmDataSetShort( cmData_t* p, short v ); cmData_t* cmDataSetShort( cmData_t* p, short v );
@ -194,7 +246,8 @@ extern "C" {
cmData_t* cmDataSetConstStr( cmData_t* p, const cmChar_t* s ); cmData_t* cmDataSetConstStr( cmData_t* p, const cmChar_t* s );
// Set the value of an existing data object to an external array. // Set the value of an existing data object to an external array.
// The array is not copied. // 'vp' is assigned as the data space for the object and therefore must remain
// valid for the life of the object.
cmData_t* cmDataSetVoidPtr( cmData_t* p, void* vp, unsigned cnt ); cmData_t* cmDataSetVoidPtr( cmData_t* p, void* vp, unsigned cnt );
cmData_t* cmDataSetCharPtr( cmData_t* p, char* vp, unsigned cnt ); cmData_t* cmDataSetCharPtr( cmData_t* p, char* vp, unsigned cnt );
cmData_t* cmDataSetUCharPtr( cmData_t* p, unsigned char* vp, unsigned cnt ); cmData_t* cmDataSetUCharPtr( cmData_t* p, unsigned char* vp, unsigned cnt );
@ -208,7 +261,7 @@ extern "C" {
cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt ); cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt );
// Set the value of an existing array based data object. // Set the value of an existing array based data object.
// Allocate the internal array and copy the array into it. // Dynamically allocate the internal array and copy the array data into it.
cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ); cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s );
cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ); cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s );
cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt ); cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt );
@ -219,78 +272,112 @@ extern "C" {
cmData_t* cmDataSetIntAllocPtr( cmData_t* p, const int* vp, unsigned cnt ); cmData_t* cmDataSetIntAllocPtr( cmData_t* p, const int* vp, unsigned cnt );
cmData_t* cmDataSetUIntAllocPtr( cmData_t* p, const unsigned int* vp, unsigned cnt ); cmData_t* cmDataSetUIntAllocPtr( cmData_t* p, const unsigned int* vp, unsigned cnt );
cmData_t* cmDataSetLongAllocPtr( cmData_t* p, const long* vp, unsigned cnt ); cmData_t* cmDataSetLongAllocPtr( cmData_t* p, const long* vp, unsigned cnt );
cmData_t* cmDataSetULongAllocPtr( cmData_t* p, const unsigned long* vp, unsigned cnt ); cmData_t* cmDataSetULongAllocPtr( cmData_t* p, const unsigned long* vp, unsigned cnt );
cmData_t* cmDataSetFloatAllocPtr( cmData_t* p, const float* vp, unsigned cnt ); cmData_t* cmDataSetFloatAllocPtr( cmData_t* p, const float* vp, unsigned cnt );
cmData_t* cmDataSetDoubleAllocPtr( cmData_t* p, const double* vp, unsigned cnt ); cmData_t* cmDataSetDoubleAllocPtr( cmData_t* p, const double* vp, unsigned cnt );
// Dynamically allocate a data object and set it's value. // Dynamically allocate a data object and set it's value.
cmData_t* cmDataAllocChar( char v ); cmData_t* cmDataAllocNull( cmData_t* parent );
cmData_t* cmDataAllocUChar( unsigned char v ); cmData_t* cmDataAllocChar( cmData_t* parent, char v );
cmData_t* cmDataAllocShort( short v ); cmData_t* cmDataAllocUChar( cmData_t* parent, unsigned char v );
cmData_t* cmDataAllocUShort( unsigned short v ); cmData_t* cmDataAllocShort( cmData_t* parent, short v );
cmData_t* cmDataAllocInt( int v ); cmData_t* cmDataAllocUShort( cmData_t* parent, unsigned short v );
cmData_t* cmDataAllocUInt( unsigned int v ); cmData_t* cmDataAllocInt( cmData_t* parent, int v );
cmData_t* cmDataAllocLong( long v ); cmData_t* cmDataAllocUInt( cmData_t* parent, unsigned int v );
cmData_t* cmDataAllocULong( unsigned long v ); cmData_t* cmDataAllocLong( cmData_t* parent, long v );
cmData_t* cmDataAllocFloat( float v ); cmData_t* cmDataAllocULong( cmData_t* parent, unsigned long v );
cmData_t* cmDataAllocDouble( double v ); cmData_t* cmDataAllocFloat( cmData_t* parent, float v );
cmData_t* cmDataAllocStr( cmChar_t* str ); cmData_t* cmDataAllocDouble( cmData_t* parent, double v );
cmData_t* cmDataAllocConstStr( const cmChar_t* str );
// Dynamically allocate a data object and set its array value to an external // Dynamically allocate a data object and set its array value to an external
// array. The data is not copied. // array. v[cnt] is assigned as the internal data space for the object and
cmData_t* cmDataAllocVoidPtr( const void* v, unsigned cnt ); // therefore must remain valid for the life of the object.
cmData_t* cmDataAllocCharPtr( const char* v, unsigned cnt ); // See the cmDataXXXAlocPtr() for equivalent functions which dynamically
cmData_t* cmDataAllocUCharPtr( const unsigned char* v, unsigned cnt ); // allocate the intenal data space.
cmData_t* cmDataAllocShortPtr( const short* v, unsigned cnt ); cmData_t* cmDataAllocStr( cmData_t* parent, cmChar_t* str );
cmData_t* cmDataAllocUShortPtr( const unsigned short* v, unsigned cnt ); cmData_t* cmDataAllocConstStr( cmData_t* parent, const cmChar_t* str );
cmData_t* cmDataAllocIntPtr( const int* v, unsigned cnt ); cmData_t* cmDataAllocCharPtr( cmData_t* parent, char* v, unsigned cnt );
cmData_t* cmDataAllocUIntPtr( const unsigned int* v, unsigned cnt ); cmData_t* cmDataAllocUCharPtr( cmData_t* parent, unsigned char* v, unsigned cnt );
cmData_t* cmDataAllocLongPtr( const long* v, unsigned cnt ); cmData_t* cmDataAllocShortPtr( cmData_t* parent, short* v, unsigned cnt );
cmData_t* cmDataAllocULongPtr( const unsigned long* v, unsigned cnt ); cmData_t* cmDataAllocUShortPtr( cmData_t* parent, unsigned short* v, unsigned cnt );
cmData_t* cmDataAllocFloatPtr( const float* v, unsigned cnt ); cmData_t* cmDataAllocIntPtr( cmData_t* parent, int* v, unsigned cnt );
cmData_t* cmDataAllocDoublePtr( const double* v, unsigned cnt ); cmData_t* cmDataAllocUIntPtr( cmData_t* parent, unsigned int* v, unsigned cnt );
cmData_t* cmDataAllocLongPtr( cmData_t* parent, long* v, unsigned cnt );
cmData_t* cmDataAllocULongPtr( cmData_t* parent, unsigned long* v, unsigned cnt );
cmData_t* cmDataAllocFloatPtr( cmData_t* parent, float* v, unsigned cnt );
cmData_t* cmDataAllocDoublePtr( cmData_t* parent, double* v, unsigned cnt );
cmData_t* cmDataAllocVoidPtr( cmData_t* parent, void* v, unsigned cnt );
// Dynamically allocate a data object and its array value. // Dynamically allocate a data object and its array value.
// v[cnt] is copied into the allocated array. // These functions dynamically allocate the internal array data space
cmData_t* cmDataVoidAllocPtr( const void* v, unsigned cnt ); // and copy v[cnt] into it.
cmData_t* cmDataCharAllocPtr( const char* v, unsigned cnt ); cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str );
cmData_t* cmDataUCharAllocPtr( const unsigned char* v, unsigned cnt ); cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str );
cmData_t* cmDataShortAllocPtr( const short* v, unsigned cnt ); cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt );
cmData_t* cmDataUShortAllocPtr( const unsigned short* v, unsigned cnt ); cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt );
cmData_t* cmDataIntAllocPtr( const int* v, unsigned cnt ); cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt );
cmData_t* cmDataUIntAllocPtr( const unsigned int* v, unsigned cnt ); cmData_t* cmDataUShortAllocPtr( cmData_t* parent, const unsigned short* v, unsigned cnt );
cmData_t* cmDataLongAllocPtr( const long* v, unsigned cnt ); cmData_t* cmDataIntAllocPtr( cmData_t* parent, const int* v, unsigned cnt );
cmData_t* cmDataULongAllocPtr( const unsigned long* v, unsigned cnt ); cmData_t* cmDataUIntAllocPtr( cmData_t* parent, const unsigned int* v, unsigned cnt );
cmData_t* cmDataFloatAllocPtr( const float* v, unsigned cnt ); cmData_t* cmDataLongAllocPtr( cmData_t* parent, const long* v, unsigned cnt );
cmData_t* cmDataDoubleAllocPtr( const double* v, unsigned cnt ); cmData_t* cmDataULongAllocPtr( cmData_t* parent, const unsigned long* v, unsigned cnt );
cmData_t* cmDataFloatAllocPtr( cmData_t* parent, const float* v, unsigned cnt );
cmData_t* cmDataDoubleAllocPtr( cmData_t* parent, const double* v, unsigned cnt );
cmData_t* cmDataVoidAllocPtr( cmData_t* parent, const void* v, unsigned cnt );
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Structure related functions // Structure related functions
// //
// Release an object and any resources held by it.
// Note the this function does not unlink the object
// from it's parent. Use cmDataUnlinkAndFree()
// to remove a object from it's parent list prior
// to releasing it.
void cmDataFree( cmData_t* p );
// Unlink 'p' from its parents and siblings. // Unlink 'p' from its parents and siblings.
// Asserts if parent is not a structure. // Asserts if parent is not a structure.
// Returns 'p'. // Returns 'p'.
cmData_t* cmDataUnlink( cmData_t* p ); cmData_t* cmDataUnlink( cmData_t* p );
// Wrapper function to cmDataUnlink() and cmDataFree().
void cmDataUnlinkAndFree( cmData_t* p );
// Replace the 'dst' node with the 'src' node and
// return 'src'. This operation does not duplicate
// 'src' it simply links in 'src' at the location of
// 'dst' and then unlinks and free's 'dst'.
cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src );
// Return the count of child nodes.
// 1. Array nodes have one child per array element.
// 2. List nodes have one child pair.
// 3. Pair nodes have two children.
// 4. Leaf nodes have 0 children.
unsigned cmDataChildCount( const cmData_t* p ); unsigned cmDataChildCount( const cmData_t* p );
// Returns the ith child of 'p'.
// Returns NULL if p has no children or index is invalid. // Returns NULL if p has no children or index is invalid.
cmData_t* cmDataChild( cmData_t* p, unsigned index ); cmData_t* cmDataChild( cmData_t* p, unsigned index );
// Prepend 'p' to 'parents' child list. // Prepend 'p' to 'parents' child list.
// The source node 'p' is not duplicated it is simply linked in.
// Returns 'p'.
cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p ); cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p );
// Append 'p' to the end of 'parent' child list. // Append 'p' to the end of 'parent' child list.
// The source node 'p' is not duplicated it is simply linked in.
// Returns 'p'.
cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p ); cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p );
// Insert 'p' at index. Index must be in the range: // Insert 'p' at index. Index must be in the range:
// 0 to cmDataChildCount(parent). // 0 to cmDataChildCount(parent).
cmData_t* cmDataInsertChild( cmData_t* parent, cmData_t* p, unsigned index ); // The source node 'p' is not duplicated it is simply linked in.
// Returns 'p'.
cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p );
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -299,31 +386,43 @@ extern "C" {
// Get the key/value of a pair // Get the key/value of a pair
cmData_t* cmDataPairKey( cmData_t* p ); cmData_t* cmDataPairKey( cmData_t* p );
unsigned cmDataPairKeyId( cmData_t* p );
const cmChar_t* cmDataPairKeyLabel( cmData_t* p );
cmData_t* cmDataPairValue( cmData_t* p ); cmData_t* cmDataPairValue( cmData_t* p );
// Set the key or value of an existing pair node. // Set the value of an existing pair node.
// 'value' is not duplicated it is simply linked in place of the
// previous pair value node. The previous pair value node is
// unlinked and freed.
// Returns 'p'.
cmData_t* cmDataPairSetValue( cmData_t* p, cmData_t* value ); cmData_t* cmDataPairSetValue( cmData_t* p, cmData_t* value );
cmData_t* cmDataPairAllocValue( cmData_t* p, const cmData_t* value );
// Set the key of an existing pair node.
//
// Returns 'p'.
cmData_t* cmDataPairSetKey( cmData_t* p, cmData_t* key ); cmData_t* cmDataPairSetKey( cmData_t* p, cmData_t* key );
cmData_t* cmDataPairSetKeyId( cmData_t* p, unsigned id ); cmData_t* cmDataPairSetKeyId( cmData_t* p, unsigned id );
// The data space for the 'label' string is dynamically allocated.
cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label ); cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label );
cmData_t* cmDataPairAllocKey( cmData_t* p, const cmData_t* key );
cmData_t* cmDataMakePair( cmData_t* parent, cmData_t* p, cmData_t* key, cmData_t* value );
// Dynamically allocate a pair node // Dynamically allocate a pair node
cmData_t* cmDataAllocPair( cmData_t* parent, const cmData_t* key, const cmData_t* value ); cmData_t* cmDataAllocPair( cmData_t* parent, const cmData_t* key, const cmData_t* value );
cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value ); cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value );
cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t label, cmData_t* value ); // The data space for the 'label' string is dynamically allocated.
cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value );
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// List related functions // List related functions
// //
// Return the count of ele's in the list. // Return the count of ele's in the list.
cmData_t* cmDataListCount( const cmData_t* p ); unsigned cmDataListCount( const cmData_t* p );
// Return the ith element in the list. // Return the ith element in the list.
cmData_t* cmDataListEle( const cmData_t* p, unsigned index ); cmData_t* cmDataListEle( cmData_t* p, unsigned index );
cmData_t* cmDataListMake( cmData_t* parent, cmData_t* p ); cmData_t* cmDataListMake( cmData_t* parent, cmData_t* p );
cmData_t* cmDataListAlloc( cmData_t* parent); cmData_t* cmDataListAlloc( cmData_t* parent);
@ -332,22 +431,22 @@ extern "C" {
// Var-args fmt: // Var-args fmt:
// <typeId> <value> {<cnt>} // <typeId> <value> {<cnt>}
// scalar types: <value> is literal,<cnt> is not included // scalar types: <value> is literal,<cnt> is not included
// null has no <value> or <cnt>
// ptr types: <value> is pointer,<cnt> is element count // ptr types: <value> is pointer,<cnt> is element count
// struct types: <value> is cmData_t, <cnt> is not included // struct types: <value> is cmData_t, <cnt> is not included
// Indicate the end of argument list by setting <typeId> to kInvalidDtId.
// The memory for array based data types is dynamically allocated.
cmData_t* cmDataListAllocV(cmData_t* parent, va_list vl ); cmData_t* cmDataListAllocV(cmData_t* parent, va_list vl );
cmData_t* cmDataListAllocA(cmData_t* parent, ... ); cmData_t* cmDataListAllocA(cmData_t* parent, ... );
// Returns a ptr to 'ele'.
cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele ); cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele );
cmData_t* cmDataListAppendEleN(cmData_t* p, cmData_t* ele[], unsigned n );
cmDtRC_t cmDataListAppendV( cmData_t* p, va_list vl ); cmDtRC_t cmDataListAppendV( cmData_t* p, va_list vl );
cmDtRC_t cmDataListAppend( cmData_t* p, ... ); cmDtRC_t cmDataListAppend( cmData_t* p, ... );
// Return 'p'.
cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele ); cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele );
cmData_t* cmDataListInsertEleN(cmData_t* p, cmData_t* ele[], unsigned n ); cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n );
cmDtRC_t cmDataListInsertV( cmData_t* p, va_list vl );
cmDtRC_t cmDataListInsert( cmData_t* p, unsigned index, ... );
cmData_t* cmDataListUnlink( cmData_t* p, unsigned index ); cmData_t* cmDataListUnlink( cmData_t* p, unsigned index );
cmData_t* cmDataListFree( cmData_t* p, unsigned index ); cmData_t* cmDataListFree( cmData_t* p, unsigned index );
@ -357,26 +456,42 @@ extern "C" {
// //
// Return count of pairs. // Return count of pairs.
cmData_t* cmDataRecdCount( const cmData_t* p ); unsigned cmDataRecdCount( const cmData_t* p );
// Return the ith pair. // Return the ith pair.
cmData_t* cmDataRecdEle( const cmData_t* p, unsigned index ); cmData_t* cmDataRecdEle( cmData_t* p, unsigned index );
// Return the ith value. // Return the ith value.
cmData_t* cmDataRecdValue( const cmData_t* p, unsigned index ); cmData_t* cmDataRecdValueFromIndex( cmData_t* p, unsigned index );
cmData_t* cmDataRecdValueFromId( cmData_t* p, unsigned id );
cmData_t* cmDataRecdValueFromLabel( cmData_t* p, const cmChar_t* label );
// Return the ith key // Return the ith key
cmData_t* cmDataRecdKey( const cmData_t* p, unsigned index ); cmData_t* cmDataRecdKey( cmData_t* p, unsigned index );
unsigned cmDataRecdKeyId( const cmData_t* p, unsigned index ); unsigned cmDataRecdKeyId( cmData_t* p, unsigned index );
const cmChar_t* cmDataRecdKeyLabel( const cmData_t* p, unsigned index ); const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index );
cmData_t* cmRecdMake( cmData_t* p ); cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p );
cmData_t* cmRecdAlloc(); cmData_t* cmRecdAlloc( cmData_t* parent );
cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair );
// Var-args fmt:
// <label|id> <typeId> <value> {<cnt>}
// scalar types: <value> is literal,<cnt> is not included
// null has no <value> or <cnt>
// ptr types: <value> is pointer,<cnt> is element count
// struct types: <value> is cmData_t, <cnt> is not included
// Indicate the end of argument list by setting <typeId> to kInvalidDtId.
// The memory for array based data types is dynamically allocated.
cmData_t* cmDataRecdAllocLabelV( cmData_t* parent, va_list vl );
cmData_t* cmDataRecdAllocLabelA( cmData_t* parent, ... );
cmData_t* cmDataRecdAllocIdV( cmData_t* parent, va_list vl );
cmData_t* cmDataRecdAllocIdA( cmData_t* parent, ... );
void cmDataFree( cmData_t* p );
unsigned cmDataSerializeByteCount( const cmData_t* p ); unsigned cmDataSerializeByteCount( const cmData_t* p );