xchange v1.0
Structured data exchange for C/C++
|
A collection of commonly used functions for generic structured data exchange. More...
Macros | |
#define | __XCHANGE_INTERNAL_API__ |
Use internal definitions. | |
Functions | |
void | xClearField (XField *f) |
void | xClearStruct (XStructure *s) |
char * | xCopyIDToken (const char *id) |
XField * | xCopyOfField (const XField *f) |
XStructure * | xCopyOfStruct (const XStructure *s) |
int | xCountFields (const XStructure *s) |
XField * | xCreate1DField (const char *name, XType type, int count, const void *values) |
XField * | xCreateBooleanField (const char *name, boolean value) |
XField * | xCreateDoubleField (const char *name, double value) |
XField * | xCreateField (const char *name, XType type, int ndim, const int *sizes, const void *value) |
XField * | xCreateIntField (const char *name, int value) |
XField * | xCreateLongField (const char *name, long long value) |
XField * | xCreateMixed1DField (const char *name, int size, XField *array) |
XField * | xCreateMixedArrayField (const char *name, int ndim, const int *sizes, XField *array) |
XField * | xCreateScalarField (const char *name, XType type, const void *value) |
XField * | xCreateStringField (const char *name, const char *value) |
XStructure * | xCreateStruct () |
long | xDeepCountFields (const XStructure *s) |
void | xDestroyField (XField *f) |
void | xDestroyStruct (XStructure *s) |
char * | xGetAggregateID (const char *table, const char *key) |
double | xGetAsDouble (const XField *f) |
double | xGetAsDoubleAtIndex (const XField *f, int idx) |
long | xGetAsLong (const XField *f, long defaultValue) |
long | xGetAsLongAtIndex (const XField *f, int idx, long defaultValue) |
void * | xGetElementAtIndex (const XField *f, int idx) |
XField * | xGetField (const XStructure *s, const char *id) |
int | xGetFieldCount (const XField *f) |
char * | xGetStringAtIndex (const XField *f, int idx) |
char * | xGetStringValue (const XField *f) |
XStructure * | xGetSubstruct (const XStructure *s, const char *id) |
int | xInsertField (XStructure *s, XField *f) |
boolean | xIsFieldValid (const XField *f) |
char * | xLastSeparator (const char *id) |
int | xMatchNextID (const char *token, const char *id) |
char * | xNextIDToken (const char *id) |
int | xReduceDims (int *ndim, int *sizes) |
int | xReduceField (XField *f) |
int | xReduceStruct (XStructure *s) |
XField * | xRemoveField (XStructure *s, const char *name) |
int | xReverseFieldOrder (XStructure *s, boolean recursive) |
XField * | xSetField (XStructure *s, XField *f) |
XField * | xSetSubstruct (XStructure *s, const char *name, XStructure *substruct) |
int | xSetSubtype (XField *f, const char *type) |
int | xSortFields (XStructure *s, int(*cmp)(const XField **f1, const XField **f2), boolean recursive) |
int | xSortFieldsByName (XStructure *s, boolean recursive) |
int | xSplitID (char *id, char **pKey) |
A collection of commonly used functions for generic structured data exchange.
void xClearField | ( | XField * | f | ) |
Clears an X structure field, freeing up all referfenced resources. However, the field itself is kept, but its contents are reset.
f | Pointer to the field to be cleared. |
References XField::name, XField::subtype, XField::type, XField::value, X_FIELD, X_STRUCT, xClearField(), xClearStruct(), and xGetFieldCount().
void xClearStruct | ( | XStructure * | s | ) |
Destroys the contents of an X structure, leaving the structure empty.
s | Pointer to the structure to be cleared. |
References XStructure::firstField, XField::next, and xDestroyField().
char * xCopyIDToken | ( | const char * | id | ) |
Returns a copy of the next next component in a compound ID. Leading ID separators are ignored.
id | Aggregate X ID. |
References x_error(), X_NULL, X_SEP, X_SEP_LENGTH, and xNextIDToken().
Returns a deep copy of the supplied field. The returned copy is a standalone field, unlinked to another to avoid corrupting any structure in which the original field may reside in. Note, that this only works with vanilla xchange structures with native storage fields. For example, SMA-X structures store data in serialized forms, and therefore it needs its own implementation for making deep copies of fields!
f | Pointer to the original field or NULL. |
References XField::isSerialized, XField::name, XField::next, XField::type, XField::value, x_error(), X_RAW, X_STRING, X_STRUCT, x_trace_null(), xCopyOfStruct(), xDestroyField(), xElementSizeOf(), xGetFieldCount(), and xStringCopyOf().
XStructure * xCopyOfStruct | ( | const XStructure * | s | ) |
Returns a deep copy of the supplied structure. Note that this only works with vanilla xchange structures with native storage fields. For example, SMA-X structures store data in serialized forms, and therefore it needs its own implementation for making deep copies of structs!
s | Pointer to the original structure or NULL. |
References XStructure::firstField, XField::next, XField::type, XField::value, x_error(), X_STRUCT, x_trace_null(), xCopyOfField(), xCreateStruct(), xDestroyStruct(), and xGetFieldCount().
int xCountFields | ( | const XStructure * | s | ) |
Returns the number of fields contained inside the structure. It is not recursive.
s | Pointer to the structure to investigate |
References XStructure::firstField, and XField::next.
Creates a generic field for a 1D array of a given name and native data. The structure will hold a copy of the value that is pointed at.
name | Field name (it may not contain a separator X_SEP) |
type | Storage type, e.g. X_INT. |
count | Number of elements in array |
values | Pointer to an array of native values. |
References x_trace_null(), and xCreateField().
Creates a field holding a single boolean value value.
name | Field name (it may not contain a separator X_SEP) |
value | Associated value |
References X_BOOLEAN, x_trace_null(), and xCreateScalarField().
XField * xCreateDoubleField | ( | const char * | name, |
double | value | ||
) |
Creates a field holding a single double-precision value value.
name | Field name (it may not contain a separator X_SEP) |
value | Associated value |
References X_DOUBLE, x_trace_null(), and xCreateScalarField().
XField * xCreateField | ( | const char * | name, |
XType | type, | ||
int | ndim, | ||
const int * | sizes, | ||
const void * | value | ||
) |
Creates a generic field of a given name and type and dimensions using a copy of the specified native data, unless type is X_STRUCT in which case the value is referenced directly inside the field.
name | Field name (it may not contain a separator X_SEP) |
type | Storage type, e.g. X_INT. |
ndim | Number of dimensionas (1:20). If ndim < 1, it will be reinterpreted as ndim=1, size[0]=1; |
sizes | Array of sizes along each dimensions, with at least ndim elements, or NULL with ndim<1. |
value | Pointer to the native data location in memory, or NULL to leave unassigned for now. |
References XField::name, XField::ndim, XField::sizes, XField::type, XField::value, x_error(), X_MAX_DIMS, X_RAW, X_STRING, X_STRUCT, x_trace_null(), xDestroyField(), xElementSizeOf(), xGetElementCount(), xLastSeparator(), and xStringCopyOf().
XField * xCreateIntField | ( | const char * | name, |
int | value | ||
) |
Creates a field holding a single ineger value value.
name | Field name (it may not contain a separator X_SEP) |
value | Associated value |
References X_INT, x_trace_null(), and xCreateScalarField().
XField * xCreateLongField | ( | const char * | name, |
long long | value | ||
) |
Creates a field holding a single ineger value value.
name | Field name (it may not contain a separator X_SEP) |
value | Associated value |
References X_LONG, x_trace_null(), and xCreateScalarField().
Creates a field containing a 1D array of heterogeneous fields. Each element of the array may have a different type and/or size.
name | The name of the array field |
size | The number of heterogeneous fields in the array. |
array | The XField array of rows containing varying types and dimensions within them. |
References X_MAX_DIMS, and xCreateMixedArrayField().
Creates a field containing an array of heterogeneous fields. Each element of the array may have a different type and/or size.
name | The name of the array field |
ndim | The dimensionality of the heterogeneous components |
sizes | The individual sizes along each dimension |
array | The XField array of elements containing varying types and dimensions within them. |
References XField::name, X_FIELD, x_trace_null(), xCreateField(), xGetElementCount(), and xStringCopyOf().
Creates a generic scalar field of a given name and native value. The structure will hold a copy of the value that is pointed at.
name | Field name (it may not contain a separator X_SEP) |
type | Storage type, e.g. X_INT. |
value | Pointer to the native data location in memory. |
References x_trace_null(), and xCreateField().
XField * xCreateStringField | ( | const char * | name, |
const char * | value | ||
) |
Creates a field holding a single string value. The field will hold a copy of the supplied value, so the caller may destroy the string safely after the call.
name | Field name (it may not contain a separator X_SEP) |
value | Associated value (it may be NULL). The string will be copied, not referenced. |
References X_STRING, x_trace_null(), and xCreateScalarField().
XStructure * xCreateStruct | ( | ) |
Creates a new empty XStructure.
long xDeepCountFields | ( | const XStructure * | s | ) |
Counts the number of fields in a structure, including the field count for all embedded substructures also recursively.
s | Pointer to a structure |
References XStructure::firstField, XField::name, XField::next, XField::type, XField::value, x_error(), X_STRUCT, x_trace(), xDeepCountFields(), and xGetFieldCount().
void xDestroyField | ( | XField * | f | ) |
Destroys an X structure field, freeing up all referenced resources, and destroying the field itself.
f | Pointer to the field to be destroyed. |
References xClearField().
void xDestroyStruct | ( | XStructure * | s | ) |
Destroys an X structure, freeing up resources used by name and value.
s | Pointer to the structure to be destroyed. |
References xClearStruct().
char * xGetAggregateID | ( | const char * | table, |
const char * | key | ||
) |
Returns the aggregated (hierarchical) <table>:<key> ID. The caller is responsible for calling free() on the returned string after use.
table | SMA-X hastable name |
key | The lower-level id to concatenate. |
References x_error(), X_SEP, X_SEP_LENGTH, and xStringCopyOf().
double xGetAsDouble | ( | const XField * | f | ) |
Return a double-precision floating point value associated to the field, or else NAN if the field cannot be represented as a decimal value. This call will use widening conversions as necessary to convert between numerical types (e.g. short
to double
), while for string values will attempt to parse a decomal value.
If the field is an array, the first element is converted and returned.
f | Pointer to field |
errno
will be set to a non-zero value indicating the type of error.References x_trace_null(), and xGetAsDoubleAtIndex().
double xGetAsDoubleAtIndex | ( | const XField * | f, |
int | idx | ||
) |
Return a double-precision floating point value associated to the field, or else NAN if the element cannot be represented as a decimal value. This call will use widening conversions as necessary to convert between numerical types (e.g. short
to double
), while for string values will attempt to parse a decomal value.
f | Pointer to field |
idx | Array index (zero-based) of the element of interest. |
errno
will be set to a non-zero value indicating the type of error.References XField::isSerialized, NAN, XField::type, XField::value, X_BOOLEAN, X_BYTE, X_DOUBLE, x_error(), X_FLOAT, X_INT, X_LONG, X_RAW, X_SHORT, X_STRING, x_trace_null(), xElementSizeOf(), xGetElementAtIndex(), and xIsCharSequence().
long xGetAsLong | ( | const XField * | f, |
long | defaultValue | ||
) |
Return a signed integer value associated to the field, or else the specified default value if the field cannot be represented as an integer. This call will use both widening and narrowing conversions, and rounding, as necessary to convert between numerical types (e.g. float
to long
), while for string values will attempt to parse an integer value.
If the field is an array, the first element is converted and returned.
f | Pointer to a field. |
defaultValue | The value to return if the structure contains no field with the specified ID, or if it cannot be represented as an integer though narrowing or widening conversions, rounding, or through parsing. |
errno
will be set to a non-zero value indicating the type of error.References x_trace(), and xGetAsLongAtIndex().
long xGetAsLongAtIndex | ( | const XField * | f, |
int | idx, | ||
long | defaultValue | ||
) |
Return a signed integer value associated to the value at the specified array index in the field, or else the specified default value if the element cannot be represented as an integer. This call will use both widening and narrowing conversions, and rounding, as necessary to convert between numerical types (e.g. float
to long
), while for string values will attempt to parse an integer value.
f | Pointer to a field. |
idx | Array index (zero-based) of the element of interest. |
defaultValue | The value to return if the structure contains no field with the specified ID, or if it cannot be represented as an integer though narrowing or widening conversions, rounding, or through parsing. |
errno
will be set to a non-zero value indicating the type of error.References XField::isSerialized, NAN, XField::type, XField::value, X_BOOLEAN, X_BYTE, X_DOUBLE, x_error(), X_FLOAT, X_INT, X_LONG, X_RAW, X_SHORT, X_STRING, x_trace(), xElementSizeOf(), xGetElementAtIndex(), and xIsCharSequence().
void * xGetElementAtIndex | ( | const XField * | f, |
int | idx | ||
) |
Returns a pointer to the array element at the specified index.
f | Pointer to a field |
idx | the array index of the requested element |
References XField::type, XField::value, x_error(), x_trace_null(), xElementSizeOf(), and xGetFieldCount().
XField * xGetField | ( | const XStructure * | s, |
const char * | id | ||
) |
Return the reference to the field by the specified name, or NULL if no such field exists.
s | Structure from which to retrieve a given field. |
id | Name or aggregate ID of the field to retrieve |
References XStructure::firstField, XField::name, XField::next, XField::type, XField::value, x_error(), X_STRUCT, X_SUCCESS, xGetField(), xMatchNextID(), and xNextIDToken().
int xGetFieldCount | ( | const XField * | f | ) |
Returns the total number of primitive elements in a field.
f | The field |
References XField::ndim, XField::sizes, x_error(), and xGetElementCount().
char * xGetStringAtIndex | ( | const XField * | f, |
int | idx | ||
) |
Returns a reference to the string value at the specified array index in the field, or else NULL if the element is not string typed, or if the index is out of bounds. Only fields containing X_STRING or X_RAW type values, or fixed-sized character sequences (XCHARS(n) type), can will return a pointer reference to the value. Or, if the field is in serialized form, then the pointer to the serialized value is returned. For fixed-length character sequences the string pointed at may not be null-terminated.
f | Pointer to field |
idx | Array index (zero-based) of the element of interest. |
errno
will be set to a non-zero value indicating the type of error.References XField::isSerialized, XField::type, XField::value, x_error(), X_RAW, X_STRING, x_trace_null(), xGetElementAtIndex(), and xIsCharSequence().
char * xGetStringValue | ( | const XField * | f | ) |
Returns a reference to the string value stored in the field, or else NULL if the element is not string typed. Only fields containing X_STRING or X_RAW type values, or fixed-sized character sequences (XCHARS(n) type), can will return a pointer reference to the value. Or, if the field is in serialized form, then the pointer to the serialized value is returned.For fixed-length character sequences the string pointed at may not be null-terminated.
If the field is an array, the first element is returned.
f | Pointer to field |
errno
will be set to a non-zero value indicating the type of error.References x_trace_null(), and xGetStringAtIndex().
XStructure * xGetSubstruct | ( | const XStructure * | s, |
const char * | id | ||
) |
Returns a substructure by the specified name, or NULL if no such sub-structure exists.
s | Structure from which to retrieve a given sub-structure. |
id | Name or aggregate ID of the substructure to retrieve |
References XField::type, XField::value, x_error(), X_STRUCT, and xGetField().
int xInsertField | ( | XStructure * | s, |
XField * | f | ||
) |
(expert) Inserts a field into the structure at its head position. That is, the specified field will become the first field in the structure. And, unlike xSetField(), this function does not check for (nor remove) previously present fields by the same name. Thus, it is left up to the caller to ensure that there are no duplicate field names added to the structure.
A note of caution: There is no safeguard against adding the same field to more than one structure, which will result in a corruption of the affected structures, since both structures would link to the field, but the field links to only one specific successive element. Therefore, the user is responsible to ensure that fields are assigned to structures uniquely, and if necessary remove the field from one structure before assigning it to another.
s | Structure to which to add the field |
f | Field to be added. |
References XStructure::firstField, XField::name, XField::next, x_error(), X_NAME_INVALID, X_NULL, X_STRUCT_INVALID, X_SUCCESS, and xLastSeparator().
Checks if a given field has valid data.
f | Pointer to the field to check. |
References FALSE, XField::name, XField::ndim, XField::sizes, TRUE, XField::type, XField::value, X_STRUCT, xElementSizeOf(), and xLastSeparator().
char * xLastSeparator | ( | const char * | id | ) |
Returns the string pointer to the begining of the last separator in the ID.
id | Compound SMA-X ID. |
References x_error(), X_SEP, and X_SEP_LENGTH.
int xMatchNextID | ( | const char * | token, |
const char * | id | ||
) |
Checks if the next component in a compound id matches a given token.
token | Full token to check for |
id | Compount X ID. |
References x_error(), X_FAILURE, X_GROUP_INVALID, X_NAME_INVALID, X_NULL, X_SEP, X_SEP_LENGTH, and X_SUCCESS.
char * xNextIDToken | ( | const char * | id | ) |
Returns a pointer to the beginning of the next component in a compound ID. Leading ID separators are ignored.
id | Aggregate X ID. |
References X_SEP, and X_SEP_LENGTH.
int xReduceDims | ( | int * | ndim, |
int * | sizes | ||
) |
Reduces the dimensions by eliminating axes that contain a singular elements. Thus a size of {1, 3, 1, 5} will reduce to {3, 5} containing the same number of elements, in fewer dimensions. If any of the dimensions are zero then it reduces to { 0 }.
[in,out] | ndim | Pointer to the dimensions (will be updated in situ) |
[in,out] | sizes | Array of sizes along the dimensions (will be updated in situ) |
References x_error(), X_SIZE_INVALID, and X_SUCCESS.
int xReduceField | ( | XField * | f | ) |
Reduces a field by eliminating extraneous dimensions, and/or wrapping recursively.
f | Pointer to a field |
References XField::ndim, XField::sizes, XField::type, XField::value, x_error(), X_FIELD, X_NULL, X_STRUCT, X_SUCCESS, xGetFieldCount(), xReduceDims(), and xReduceStruct().
int xReduceStruct | ( | XStructure * | s | ) |
Recursively eliminates unneccessary embedding of singular structures inside a structure and reduces the dimensions of array fields with xReduceDims(), recursively. It will also eliminate the unnecessary wrapping of a singular array into a single XField.
s | Pointer to a structure. |
References XStructure::firstField, XField::next, XStructure::parent, XField::type, XField::value, x_error(), X_STRUCT, X_STRUCT_INVALID, X_SUCCESS, xGetFieldCount(), xReduceField(), and xReduceStruct().
XField * xRemoveField | ( | XStructure * | s, |
const char * | name | ||
) |
Removes as field from the structure, returning it if found.
s | Pointer to structure |
name | Name of field to remove |
References XStructure::firstField, XField::name, XField::next, XStructure::parent, XField::type, XField::value, x_error(), X_STRUCT, and xGetFieldCount().
int xReverseFieldOrder | ( | XStructure * | s, |
boolean | recursive | ||
) |
Reverse the order of fields in a structure.
s | The structure, whose field order to reverse. |
recursive | Whether to apply the reversal to all ebmbedded substructures also |
References XStructure::firstField, XField::next, TRUE, XField::type, XField::value, x_error(), X_NULL, X_STRUCT, X_SUCCESS, xGetFieldCount(), and xReverseFieldOrder().
XField * xSetField | ( | XStructure * | s, |
XField * | f | ||
) |
Adds or replaces a field in the structure with the specified field value, returning the previous value for the same field. It is up to the caller whether or not the old value should be destoyed or kept. Note though that you should check first to see if the replaced field is the same as the new one before attempting to destroy...
The field's name may not contain a compound ID. To add fields to embedded sub-structures, you may want to use xGetSubstruct() first to add the field directly to the relevant embedded component.
A note of caution: There is no safeguard against adding the same field to more than one structure, which will result in a corruption of the affected structures, since both structures would link to the field, but the field links to only one specific successive element. Therefore, the user is responsible to ensure that fields are assigned to structures uniquely, and if necessary remove the field from one structure before assigning it to another.
s | Structure to which to add the field |
f | Field to be added. |
References XStructure::firstField, XField::name, XField::next, and x_error().
XField * xSetSubstruct | ( | XStructure * | s, |
const char * | name, | ||
XStructure * | substruct | ||
) |
Inserts a structure within a parent structure, returning the old field that may have existed under the requested name before.
The name may not contain a compound ID. To add the structure to embedded sub-structures, you may want to use xGetSubstruct() first to add the new structure directly to the relevant embedded component.
s | Pointer to the parent structure |
name | Name of the sub-structure |
substruct | Pointer to the sub-structure. It is added directly as a reference, without making a copy. |
return The prior field stored under the same name or NULL. If there is an error then NULL is returned and errno is set to indicate the nature of the issue. (a message is also printed to stderr if xDebug is enabled.)
References XStructure::parent, x_error(), X_STRUCT, x_trace_null(), xCreateScalarField(), and xSetField().
int xSetSubtype | ( | XField * | f, |
const char * | type | ||
) |
Sets the optional subtype for a field's content to a copy of the specified string value. The subtype can be used to add any application specific information on how the specified value should be used. For example it may indicate a mime type or an encoding. It is entirely up to the user as to what meaning the subtype has for their application.
f | Pointer to a field |
type | The new subtype to be assigned to the field. A copy of the value is used rather than the reference, so that the string that was supplied can be safely discarded at any point after the call. |
References XField::subtype, x_error(), X_NULL, X_SUCCESS, and xStringCopyOf().
int xSortFields | ( | XStructure * | s, |
int(*)(const XField **f1, const XField **f2) | cmp, | ||
boolean | recursive | ||
) |
Sort the fields in a structure using a specific comparator function.
s | The structure, whose fields to sort |
cmp | The comparator function. It takes two pointers to XField locations as arguments. |
recursive | Whether to apply the sorting to all ebmbedded substructures also |
References XStructure::firstField, XField::next, TRUE, XField::type, XField::value, x_error(), X_FAILURE, X_NULL, X_STRUCT, X_SUCCESS, xGetFieldCount(), and xSortFields().
int xSortFieldsByName | ( | XStructure * | s, |
boolean | recursive | ||
) |
Sorts the fields of a structure by field name, in ascending alphabetical order.
s | The structure, whose fields to sort |
recursive | Whether to apply the sorting to all ebmbedded substructures also |
References X_SUCCESS, and xSortFields().
int xSplitID | ( | char * | id, |
char ** | pKey | ||
) |
Splits the id into two strings (sharing the same input buffer): (1) the id of the embedding structure, and (2) the embedded field name. The original input id is string terminated after the table name. And the pointer to the key part that follows after the last separator is returned in the second (optional argument).
[in,out] | id | String containing an aggregate ID, which will be terminated after the last substructure. |
[out] | pKey | Returned pointer to the second component after the separator within the same buffer. This is not an independent pointer. Use xStringCopyOf() if you need an idependent string on which free() can be called! The returned value pointed to may be NULL if the ID could not be split. The argument may also be null, in which case the input string is just terminated at the stem, without returning the second part. |
References x_error(), X_NAME_INVALID, X_NULL, X_SEP_LENGTH, X_SUCCESS, and xLastSeparator().