libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmData.h 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #ifndef cmData_h
  4. #define cmData_h
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. //( { file_desc:"Generic, introspective, data structure." }
  9. /*
  10. TODO:
  11. 0) Figure out an error handling scheme that does not rely on
  12. a global errno. This is not useful in multi-thread environments.
  13. It might be ok to go with an 'all errors are fatal' model
  14. (except in the var-args functions).
  15. Consider the use of a context object for use with functions
  16. that can have runtime errors or need to allocate memory.
  17. 1) Implement the canConvert and willTruncate functions.
  18. 2) Make a set of cmDataAllocXXXPtr() functions which take
  19. a flag indicating whether or not to dynamically allocate
  20. the array space. This will allow dynamic allocattion to
  21. occur at runtime. Make var args functions for list and
  22. record objects which also take this flag.
  23. Whereever a function may be implemented using
  24. static/dynamic allocation this flag should be present.
  25. (e.g. string allocation for pair labels)
  26. This choice is common enough that it may be worth
  27. suffixing function names with a capital letter to
  28. be clear what the functions memory policy is.
  29. 3) Come up with a var-args format which allows a
  30. hierchy of records to be defined in one line.
  31. 4) Implement the serialization functions.
  32. 5) Implement an ascii string/parse format for writing/reading.
  33. 6) Implement fast lookup of record fields.
  34. 7) Allow for user defined types. For example a 'matrix'
  35. data type. This might be as simple as adding an extra 'user_tid'
  36. field to cmData_t.
  37. 8) Implement type specific cmDataGetRecordValueXXX() functions.
  38. 9) Implement cmDataIsEqual(), cmDataIsLtE(), ...
  39. */
  40. enum
  41. {
  42. kOkDtRC = cmOkRC,
  43. kAssertErrDtRC,
  44. kConstErrDtRC,
  45. kCvtErrDtRC,
  46. kInvalidContDtRC,
  47. kInvalidTypeDtRC,
  48. kMissingFieldDtRC,
  49. kLexFailDtRC,
  50. kParseStackFailDtRC,
  51. kSyntaxErrDtRC,
  52. kEolDtRC
  53. };
  54. typedef unsigned cmDtRC_t;
  55. typedef enum
  56. {
  57. kInvalidTypeDtId,// 0
  58. kNullDtId, // 1 the data object exists but it has no data
  59. kBoolDtId, // 2
  60. kUCharDtId, // 3
  61. kCharDtId, // 4
  62. kUShortDtId, // 5
  63. kShortDtId, // 6
  64. kUIntDtId, // 7
  65. kIntDtId, // 8
  66. kULongDtId, // 9
  67. kLongDtId, // 10
  68. kFloatDtId, // 11
  69. kDoubleDtId, // 12
  70. kStrDtId, // 13 zero terminated string
  71. kBlobDtId, // 14 application defined raw memory object
  72. kStructDtId, // 15 node is a pair,list, or recd
  73. } cmDataTypeId_t;
  74. typedef enum
  75. {
  76. kInvalidCntDtId = kInvalidTypeDtId,
  77. kScalarDtId = 0x00100000,
  78. kArrayDtId = 0x00200000,
  79. kPairDtId = 0x00400000,
  80. kListDtId = 0x00800000,
  81. kRecordDtId = 0x01000000,
  82. kContainerDtMask = 0x01f00000,
  83. } cmDataContainerId_t;
  84. enum
  85. {
  86. kNoFlagsDtFl = 0x00,
  87. kOptArgDtFl = 0x02000000,
  88. // Indicate that the memory used by the data object
  89. // was dynamically allocated and should be released
  90. // by cmDataFree().
  91. kFreeObjDtFl = 0x04000000,
  92. // Indicate that the memory used by strings, blobs
  93. // and arrays should be freed by cmDataFree().
  94. kFreeValueDtFl = 0x08000000,
  95. // Indicate that the value of the object cannot be changed.
  96. // (but the object could be reassigned as a new type).
  97. kConstValueDtFl = 0x10000000,
  98. // Indicate that the type of the object cannot be changed.
  99. // (but the value may be changed).
  100. kConstObjDtFl = 0x20000000,
  101. // Indicate that the array or string should not be
  102. // internally reallocated but rather the source pointer
  103. // should be taken as the new value of the object.
  104. kNoCopyDtFl = 0x40000000,
  105. kFlagsDtMask = 0x7e000000
  106. };
  107. // The kInvalidDtXXX constants are used to indicate an error when returned
  108. // from the cmDtXXX() functions below.
  109. #define kInvalidDtFloat FLT_MAX
  110. #define kInvalidDtDouble DBL_MAX
  111. enum
  112. {
  113. kInvalidDtChar = 0xff,
  114. kInvalidDtShort = 0xffff,
  115. kInvalidDtInt = 0xffffffff,
  116. kInvalidDtLong = kInvalidDtInt,
  117. kInvalidDtBool = kInvalidDtInt
  118. };
  119. typedef struct cmData_str
  120. {
  121. cmDataTypeId_t tid; // data format id
  122. cmDataContainerId_t cid; // container id
  123. unsigned flags; //
  124. struct cmData_str* parent; // this childs parent
  125. struct cmData_str* sibling; // this childs left sibling
  126. unsigned cnt; // byte cnt for strings/blobs and ele count for arrays
  127. union
  128. {
  129. bool b;
  130. char c;
  131. unsigned char uc;
  132. short s;
  133. unsigned short us;
  134. int i;
  135. unsigned int ui;
  136. long l;
  137. unsigned long ul;
  138. float f;
  139. double d;
  140. cmChar_t* z;
  141. void* vp;
  142. struct cmData_str* child; // first child (list,record,pair)
  143. } u;
  144. } cmData_t;
  145. extern cmData_t cmDataNull;
  146. const cmChar_t* cmDataTypeToLabel( cmDataTypeId_t tid );
  147. cmDataTypeId_t cmDataLabelToType( const cmChar_t* typeLabelStr );
  148. // Returns 1 for kStrDtId.
  149. // Returns cmInvalidCnt if tid is not recognized.
  150. unsigned dmDataByteWidth( cmDataTypeId_t tid );
  151. const cmChar_t* cmDataContainerIdToLabel( cmDataContainerId_t tid );
  152. cmDataContainerId_t cmDataLabelToContainerId( const cmChar_t* contLabelStr );
  153. bool cmDataIsConstObj( const cmData_t* d );
  154. void cmDataEnableConstObj( cmData_t* d, bool enaFl );
  155. bool cmDataIsConstValue( const cmData_t* d );
  156. void cmDataEnableConstValue( cmData_t* d, bool enaFl );
  157. bool cmDataIsFreeValue( const cmData_t* d );
  158. void cmDataEnableFreeValue( cmData_t* d, bool enaFl );
  159. // Returns true if this is a scalar or array node.
  160. bool cmDataIsLeaf( const cmData_t* d);
  161. // Return true if this is NOT a scalar or array node.
  162. bool cmDataIsStruct( const cmData_t* d );
  163. //----------------------------------------------------------------------------
  164. // Scalar related functions
  165. //
  166. // Dynamically allocate a scalar object and set it's value.
  167. // The 'flags' argument may include kConstValueDtFl and kConstObjDtFl.
  168. // The string and blob constructors may also use the
  169. // kNoCopyDtFl and the kFreeValueDtFl.
  170. // Generic:
  171. // 'byteCnt' is ignored for all types other than strings and blobs.
  172. cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref );
  173. // Type specific
  174. cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref );
  175. cmDtRC_t cmDataNewBool( cmData_t* parent, unsigned flags, bool v, cmData_t** ref );
  176. cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref );
  177. cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref );
  178. cmDtRC_t cmDataNewShort( cmData_t* parent, unsigned flags, short v, cmData_t** ref );
  179. cmDtRC_t cmDataNewUShort( cmData_t* parent, unsigned flags, unsigned short v, cmData_t** ref );
  180. cmDtRC_t cmDataNewInt( cmData_t* parent, unsigned flags, int v, cmData_t** ref );
  181. cmDtRC_t cmDataNewUInt( cmData_t* parent, unsigned flags, unsigned int v, cmData_t** ref );
  182. cmDtRC_t cmDataNewLong( cmData_t* parent, unsigned flags, long v, cmData_t** ref );
  183. cmDtRC_t cmDataNewULong( cmData_t* parent, unsigned flags, unsigned long v, cmData_t** ref );
  184. cmDtRC_t cmDataNewFloat( cmData_t* parent, unsigned flags, float v, cmData_t** ref );
  185. cmDtRC_t cmDataNewDouble( cmData_t* parent, unsigned flags, double v, cmData_t** ref );
  186. cmDtRC_t cmDataNewStr( cmData_t* parent, unsigned flags, cmChar_t* str, cmData_t** ref );
  187. cmDtRC_t cmDataNewConstStr( cmData_t* parent, unsigned flags, const cmChar_t* str, cmData_t** ref );
  188. cmDtRC_t cmDataNewStrN( cmData_t* parent, unsigned flags, cmChar_t* str, unsigned charCnt, cmData_t** ref );
  189. cmDtRC_t cmDataNewConstStrN(cmData_t* parent, unsigned flags, const cmChar_t* str, unsigned charCnt, cmData_t** ref );
  190. cmDtRC_t cmDataNewBlob( cmData_t* parent, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref );
  191. cmDtRC_t cmDataNewConstBlob(cmData_t* parent, unsigned flags, const void* vp, unsigned byteCnt, cmData_t** ref );
  192. // Set the value and type of an existing scalar object.
  193. // These functions begin by releasing any resources held by *p
  194. // prior to resetting the type and value of the object.
  195. // The 'flags' argument to cmDataSetStr() and cmDataSetConstStr()
  196. // may use the kNoCopyDtFl and the kFreeValueDtFl
  197. cmDtRC_t cmDataSetScalarValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned byteCnt, unsigned flags );
  198. cmDtRC_t cmDataSetNull( cmData_t* p );
  199. cmDtRC_t cmDataSetBool( cmData_t* p, bool v );
  200. cmDtRC_t cmDataSetChar( cmData_t* p, char v );
  201. cmDtRC_t cmDataSetUChar( cmData_t* p, unsigned char v );
  202. cmDtRC_t cmDataSetShort( cmData_t* p, short v );
  203. cmDtRC_t cmDataSetUShort( cmData_t* p, unsigned short v );
  204. cmDtRC_t cmDataSetInt( cmData_t* p, int v );
  205. cmDtRC_t cmDataSetUInt( cmData_t* p, unsigned int v );
  206. cmDtRC_t cmDataSetLong( cmData_t* p, long v );
  207. cmDtRC_t cmDataSetULong( cmData_t* p, unsigned long v );
  208. cmDtRC_t cmDataSetFloat( cmData_t* p, float v );
  209. cmDtRC_t cmDataSetDouble( cmData_t* p, double v );
  210. cmDtRC_t cmDataSetStr( cmData_t* p, unsigned flags, cmChar_t* s );
  211. cmDtRC_t cmDataSetConstStr( cmData_t* p, unsigned flags, const cmChar_t* s );
  212. cmDtRC_t cmDataSetStrN( cmData_t* p, unsigned flags, cmChar_t* s, unsigned charCnt );
  213. cmDtRC_t cmDataSetConstStrN( cmData_t* p, unsigned flags, const cmChar_t* s, unsigned charCnt );
  214. cmDtRC_t cmDataSetBlob( cmData_t* p, unsigned flags, void* v, unsigned byteCnt );
  215. cmDtRC_t cmDataSetConstBlob( cmData_t* p, unsigned flags, const void* v, unsigned byteCnt );
  216. // Get the value of an object. No conversion is applied the
  217. // type must match exactly or an error is generated.
  218. cmDtRC_t cmDataBool( const cmData_t* p, bool* v );
  219. cmDtRC_t cmDataChar( const cmData_t* p, char* v );
  220. cmDtRC_t cmDataUChar( const cmData_t* p, unsigned char* v );
  221. cmDtRC_t cmDataShort( const cmData_t* p, short* v );
  222. cmDtRC_t cmDataUShort( const cmData_t* p, unsigned short* v );
  223. cmDtRC_t cmDataInt( const cmData_t* p, int* v );
  224. cmDtRC_t cmDataUInt( const cmData_t* p, unsigned int* v );
  225. cmDtRC_t cmDataLong( const cmData_t* p, long* v );
  226. cmDtRC_t cmDataULong( const cmData_t* p, unsigned long* v );
  227. cmDtRC_t cmDataFloat( const cmData_t* p, float* v );
  228. cmDtRC_t cmDataDouble( const cmData_t* p, double* v );
  229. cmDtRC_t cmDataStr( const cmData_t* p, cmChar_t** v );
  230. cmDtRC_t cmDataConstStr( const cmData_t* p, const cmChar_t** v );
  231. cmDtRC_t cmDataBlob( const cmData_t* p, void** v, unsigned* byteCntRef );
  232. cmDtRC_t cmDataConstBlob( const cmData_t* p, const void** v, unsigned* byteCntRef );
  233. // Functions in this group which return pointers will return NULL
  234. // on error. The other function indicate an error by returning
  235. // kInvalidDtXXX depending on their type.
  236. // Note that there is no guarantee, except as determined by the
  237. // application, that one of the kInvalidDtXXX is not in fact a legal return value.
  238. // These function are simple wrappers around calls to cmDataXXX() and
  239. // therefore do NOT do any type conversion.
  240. bool cmDtBool( const cmData_t* p );
  241. char cmDtChar( const cmData_t* p );
  242. unsigned char cmDtUChar( const cmData_t* p );
  243. short cmDtShort( const cmData_t* p );
  244. unsigned short cmDtUShort( const cmData_t* p );
  245. int cmDtInt( const cmData_t* p );
  246. unsigned cmDtUInt( const cmData_t* p );
  247. long cmDtLong( const cmData_t* p );
  248. unsigned long cmDtULong( const cmData_t* p );
  249. float cmDtFloat( const cmData_t* p );
  250. double cmDtDouble( const cmData_t* p );
  251. char* cmDtStr( const cmData_t* p );
  252. const char* cmDtConstStr( const cmData_t* p );
  253. void* cmDtBlob( const cmData_t* p, unsigned* byteCntRef );
  254. const void* cmDtConstBlob( const cmData_t* p, unsigned* byteCntRef );
  255. // Get the value of an object with conversion.
  256. cmDtRC_t cmDataGetBool( const cmData_t* p, bool* v );
  257. cmDtRC_t cmDataGetChar( const cmData_t* p, char* v );
  258. cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* v );
  259. cmDtRC_t cmDataGetShort( const cmData_t* p, short* v );
  260. cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* v );
  261. cmDtRC_t cmDataGetInt( const cmData_t* p, int* v );
  262. cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* v );
  263. cmDtRC_t cmDataGetLong( const cmData_t* p, long* v );
  264. cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* v );
  265. cmDtRC_t cmDataGetFloat( const cmData_t* p, float* v );
  266. cmDtRC_t cmDataGetDouble( const cmData_t* p, double* v );
  267. // Functions in this group which return pointers will return NULL
  268. // on error. The other function indicate an error by returning
  269. // kInvalidDtXXX depending on their type.
  270. // Note that there is no guarantee, except as determined by the
  271. // application that one of the kInvalidDtXXX is not in fact a legal return value.
  272. // These function are simple wrappers around calls to cmDataGetXXX() and
  273. // therefore do type conversion.
  274. bool cmDtGetBool( const cmData_t* p );
  275. char cmDtGetChar( const cmData_t* p );
  276. unsigned char cmDtGetUChar( const cmData_t* p );
  277. short cmDtGetShort( const cmData_t* p );
  278. unsigned short cmDtGetUShort( const cmData_t* p );
  279. int cmDtGetInt( const cmData_t* p );
  280. unsigned cmDtGetUInt( const cmData_t* p );
  281. long cmDtGetLong( const cmData_t* p );
  282. unsigned long cmDtGetULong( const cmData_t* p );
  283. float cmDtGetFloat( const cmData_t* p );
  284. double cmDtGetDouble( const cmData_t* p );
  285. //----------------------------------------------------------------------------
  286. // Array related functions
  287. //
  288. // Notes:
  289. // 1) string arrays are arrays of string pointers.
  290. // 2) blob arrays (array of void pointers) are not supported because
  291. // there is no direct way to determine the length of each blob
  292. // and therefore they cannot be internally duplicated - a special scheme
  293. // could be devised (length goes in first 4 bytes) to make this
  294. // work but we will defer that until the need arises.
  295. //
  296. // Dynamically allocate a new array data object.
  297. //
  298. // eleCnt referes to the number of elements in the array pointed
  299. // to by 'vp'. The number of bytes pointed to by 'vp' is then
  300. // cmDataByteWidth(tid)*eleCnt.
  301. //
  302. // If no flags are set then the array pointed to by 'vp' is reallocated
  303. // and kDataFreeDtFl is set.
  304. //
  305. // If kFreeValueDtFl is set then the object will take responsibility for
  306. // releasing the memory pointed to by 'vp' when the object is destroyed
  307. // or the array is reassigned.
  308. //
  309. // If kNoCopyDtFl is set then 'vp' becomes the internal array
  310. // value (vp[cnt]) is NOT reallocated). In this case the client is
  311. // responsibile for eventually releasing the associated memory - when
  312. // the data object is no longer valid.
  313. cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref );
  314. cmDtRC_t cmDataNewBoolArray( cmData_t* parent, bool* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  315. cmDtRC_t cmDataNewCharArray( cmData_t* parent, char* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  316. cmDtRC_t cmDataNewUCharArray( cmData_t* parent, unsigned char* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  317. cmDtRC_t cmDataNewShortArray( cmData_t* parent, short* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  318. cmDtRC_t cmDataNewUShortArray( cmData_t* parent, unsigned short* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  319. cmDtRC_t cmDataNewIntArray( cmData_t* parent, int* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  320. cmDtRC_t cmDataNewUIntArray( cmData_t* parent, unsigned int* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  321. cmDtRC_t cmDataNewLongArray( cmData_t* parent, long* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  322. cmDtRC_t cmDataNewULongArray( cmData_t* parent, unsigned long* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  323. cmDtRC_t cmDataNewFloatArray( cmData_t* parent, float* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  324. cmDtRC_t cmDataNewDoubleArray( cmData_t* parent, double* v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  325. cmDtRC_t cmDataNewStrArray( cmData_t* parent, cmChar_t** v, unsigned eleCnt, unsigned flags, cmData_t** ref );
  326. cmDtRC_t cmDataNewConstStrArray( cmData_t* parent, const cmChar_t** v,unsigned eleCnt, unsigned flags, cmData_t** ref );
  327. // Set the value and type of an existing scalar object.
  328. //
  329. // These functions begin by releasing any resources held by *p
  330. // prior to resetting the type and value of the object.
  331. // The 'flags' argument may include kConstValueDtFl, kConstObjDtFl,
  332. // kNoCopyDtFl and the kFreeValueDtFl.
  333. // Generic set array functions. 'vp' is assumed to point to an array
  334. // of the type defined by 'tid'.
  335. cmDtRC_t cmDataSetArrayValue( cmData_t* dt, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags );
  336. // Type sepctific set array functions.
  337. cmDtRC_t cmDataSetBoolArray( cmData_t* d, bool* v, unsigned eleCnt, unsigned flags );
  338. cmDtRC_t cmDataSetCharArray( cmData_t* d, char* v, unsigned eleCnt, unsigned flags );
  339. cmDtRC_t cmDataSetUCharArray( cmData_t* d, unsigned char* v, unsigned eleCnt, unsigned flags );
  340. cmDtRC_t cmDataSetShortArray( cmData_t* d, short* v, unsigned eleCnt, unsigned flags );
  341. cmDtRC_t cmDataSetUShortArray( cmData_t* d, unsigned short* v, unsigned eleCnt, unsigned flags );
  342. cmDtRC_t cmDataSetIntArray( cmData_t* d, int* v, unsigned eleCnt, unsigned flags );
  343. cmDtRC_t cmDataSetUIntArray( cmData_t* d, unsigned int* v, unsigned eleCnt, unsigned flags );
  344. cmDtRC_t cmDataSetLongArray( cmData_t* d, long* v, unsigned eleCnt, unsigned flags );
  345. cmDtRC_t cmDataSetULongArray( cmData_t* d, unsigned long* v, unsigned eleCnt, unsigned flags );
  346. cmDtRC_t cmDataSetFloatArray( cmData_t* d, float* v, unsigned eleCnt, unsigned flags );
  347. cmDtRC_t cmDataSetDoubleArray( cmData_t* d, double* v, unsigned eleCnt, unsigned flags );
  348. cmDtRC_t cmDataSetStrArray( cmData_t* d, cmChar_t** v, unsigned eleCnt, unsigned flags );
  349. cmDtRC_t cmDataSetConstStrArray(cmData_t* d,const cmChar_t** v,unsigned eleCnt, unsigned flags );
  350. // Return the count of elements in a n array.
  351. unsigned cmDataArrayEleCount( const cmData_t* d );
  352. // Get a pointer to the base of an array.
  353. // The type must match exactly or an error is generated.
  354. // Use cmDataEleCount() to determine the number of elements in the array.
  355. cmDtRC_t cmDataBoolArray( const cmData_t* d, bool** v );
  356. cmDtRC_t cmDataCharArray( const cmData_t* d, char** v );
  357. cmDtRC_t cmDataUCharArray( const cmData_t* d, unsigned char** v );
  358. cmDtRC_t cmDataShortArray( const cmData_t* d, short** v );
  359. cmDtRC_t cmDataUShortArray( const cmData_t* d, unsigned short** v );
  360. cmDtRC_t cmDataIntArray( const cmData_t* d, int** v );
  361. cmDtRC_t cmDataUIntArray( const cmData_t* d, unsigned int** v );
  362. cmDtRC_t cmDataLongArray( const cmData_t* d, long** v );
  363. cmDtRC_t cmDataULongArray( const cmData_t* d, unsigned long** v );
  364. cmDtRC_t cmDataFloatArray( const cmData_t* d, float** v );
  365. cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v );
  366. // This group of functions is a wrapper around calls to the same named
  367. // cmDataXXXArray() functions above. On error they return NULL.
  368. bool* cmDtBoolArray( const cmData_t* d );
  369. char* cmDtCharArray( const cmData_t* d );
  370. unsigned char* cmDtUCharArray( const cmData_t* d );
  371. short* cmDtShortArray( const cmData_t* d );
  372. unsigned short* cmDtUShortArray( const cmData_t* d );
  373. int* cmDtIntArray( const cmData_t* d );
  374. unsigned* cmDtUIntArray( const cmData_t* d );
  375. long* cmDtLongArray( const cmData_t* d );
  376. unsigned long* cmDtULongArray( const cmData_t* d );
  377. float* cmDtFloatArray( const cmData_t* d );
  378. double* cmDtDoubleArray( const cmData_t* d );
  379. //----------------------------------------------------------------------------
  380. // Structure related functions
  381. //
  382. // Release an object and any resources held by it.
  383. // Note the this function does not unlink the object
  384. // from it's parent. Use cmDataUnlinkAndFree()
  385. // to remove a object from it's parent list prior
  386. // to releasing it.
  387. void cmDataFree( cmData_t* p );
  388. // Unlink 'p' from its parents and siblings.
  389. // Asserts if parent is not a structure.
  390. // Returns 'p'.
  391. cmData_t* cmDataUnlink( cmData_t* p );
  392. // Wrapper function to cmDataUnlink() and cmDataFree().
  393. void cmDataUnlinkAndFree( cmData_t* p );
  394. // Replace the 'dst' node with the 'src' node and
  395. // return 'src'. This operation does not duplicate
  396. // 'src' it simply links in 'src' at the location of
  397. // 'dst' and then unlinks and free's 'dst'.
  398. cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src );
  399. // Return the count of child nodes.
  400. // Scalars and arrays have no children.
  401. // Pairs have 2 children.
  402. // Lists have one child per element.
  403. // Records have one child per pair.
  404. unsigned cmDataChildCount( const cmData_t* p );
  405. // Returns the ith child of 'p'.
  406. // Returns NULL if p has no children or index is invalid.
  407. cmData_t* cmDataChild( cmData_t* p, unsigned index );
  408. // Prepend 'p' to 'parents' child list.
  409. // The source node 'p' is not duplicated it is simply linked in.
  410. // 'p' is automatically unlinked prior to being prepended.
  411. // Returns 'p'.
  412. cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p );
  413. // Append 'p' to the end of 'parent' child list.
  414. // The source node 'p' is not duplicated it is simply linked in.
  415. // 'p' is automatically unlinked prior to being appended.
  416. // Returns 'p'.
  417. cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p );
  418. // Insert 'p' at index. Index must be in the range:
  419. // 0 to cmDataChildCount(parent).
  420. // The source node 'p' is not duplicated it is simply linked in.
  421. // 'p' is automatically unlinked prior to being inserted.
  422. // Returns 'p'.
  423. cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p );
  424. //----------------------------------------------------------------------------
  425. // Pair related functions
  426. //
  427. // Get the key/value of a pair
  428. cmData_t* cmDataPairKey( cmData_t* p );
  429. unsigned cmDataPairKeyId( cmData_t* p );
  430. const cmChar_t* cmDataPairKeyLabel( cmData_t* p );
  431. cmData_t* cmDataPairValue( cmData_t* p );
  432. // Set the value of an existing pair node.
  433. // 'value' is not duplicated it is simply linked in place of the
  434. // previous pair value node. The previous pair value node is
  435. // unlinked and freed.
  436. // Returns 'p'.
  437. cmData_t* cmDataPairSetValue( cmData_t* p, cmData_t* value );
  438. // Set the key of an existing pair node.
  439. // The previous key is unlinked and freed.
  440. cmData_t* cmDataPairSetKey( cmData_t* p, cmData_t* key );
  441. cmData_t* cmDataPairSetKeyId( cmData_t* p, unsigned id );
  442. // The data space for the 'label' string is dynamically allocated.
  443. cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label );
  444. // Create a pair value by assigning a key and value to 'p'.
  445. // 'p' is unlinked and freed prior to the key value assignment.
  446. // 'key' and 'value' are simply linked in they are not duplicated or reallocated.
  447. cmData_t* cmDataPairMake( cmData_t* parent, cmData_t* p, cmData_t* key, cmData_t* value );
  448. // Dynamically allocate a pair node. Both the key and value nodes are reallocated.
  449. cmRC_t cmDataPairAlloc( cmData_t* parent, const cmData_t* key, const cmData_t* value, cmData_t** ref );
  450. // Dynamically allocate the id but link (w/o realloc) the value.
  451. cmRC_t cmDataPairAllocId( cmData_t* parent, unsigned keyId, cmData_t* value, cmData_t** ref );
  452. // Dynamically allocate the label but link (w/o realloc) the value.
  453. cmRC_t cmDataPairAllocLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value, cmData_t** ref);
  454. cmRC_t cmDataPairAllocLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value, cmData_t** ref );
  455. //----------------------------------------------------------------------------
  456. // List related functions
  457. //
  458. // Return the count of ele's in the list.
  459. unsigned cmDataListCount( const cmData_t* p );
  460. // Return the ith element in the list.
  461. cmData_t* cmDataListEle( cmData_t* p, unsigned index );
  462. //
  463. cmData_t* cmDataListMake( cmData_t* parent, cmData_t* p );
  464. cmData_t* cmDataListAlloc( cmData_t* parent);
  465. // Dynamically allocate a new list object and fill it with values
  466. // using a variable argument list.
  467. //
  468. // 1) Var-args fmt:
  469. // <typeId> {<value>} {<cnt>}
  470. //
  471. // 2) <typeId> is formed by OR-ing one of the container type flags with a
  472. // data type id. (e.g. kArrayDtId | kIntDtId). Note that if no
  473. // container is given then the type is assumed to be scalar.
  474. //
  475. // scalar types: <value> is literal, <cnt> should not be included
  476. // null scalar object should not include <value> or <cnt>
  477. // array types: <value> is pointer,<cnt> is element count
  478. // struct types: <value> is cmData_t pointer, <cnt> should not be included.
  479. // The struct object is appended to the child list of parent.
  480. //
  481. // 3) Indicate the end of argument list by setting <typeId> to kInvalidDtId.
  482. // 4) Scalar and array objects will be dynamically allocated.
  483. // 5) Data attribute flags (kXXXDtFl) make also be OR-ed into the <typeId>.
  484. // 6) Data attribute flags will only be used with scalar and array object and
  485. // will be ignored for all other object types.
  486. cmRC_t cmDataListAllocV( cmData_t* parent, cmErr_t* err, cmRC_t errRC, cmData_t** ref, va_list vl );
  487. cmRC_t cmDataListAllocA( cmData_t* parent, cmErr_t* err, cmRC_t errRC, cmData_t** ref, ... );
  488. // Returns a ptr to 'ele'.
  489. cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele );
  490. cmDtRC_t cmDataListAppendV( cmData_t* p, cmErr_t* err, cmRC_t errRC, va_list vl );
  491. cmDtRC_t cmDataListAppend( cmData_t* p, cmErr_t* err, cmRC_t errRC, ... );
  492. // Return 'p'.
  493. cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele );
  494. cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n );
  495. //----------------------------------------------------------------------------
  496. // Record related functions
  497. //
  498. // Return count of pairs.
  499. unsigned cmDataRecdCount( const cmData_t* p );
  500. // Return the ith pair.
  501. cmData_t* cmDataRecdEle( cmData_t* p, unsigned index );
  502. // Return the ith value.
  503. cmData_t* cmDataRecdValueFromIndex( cmData_t* p, unsigned index );
  504. cmData_t* cmDataRecdValueFromId( cmData_t* p, unsigned id );
  505. cmData_t* cmDataRecdValueFromLabel( cmData_t* p, const cmChar_t* label );
  506. // Return the ith key or NULL if it does not exist.
  507. cmData_t* cmDataRecdKey( cmData_t* p, unsigned index );
  508. // Returns cmInvalidId if the ith key does not exist or is not an integer.
  509. unsigned cmDataRecdKeyId( cmData_t* p, unsigned index );
  510. // Return NULL if the ith key does not exist or is not a string.
  511. const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index );
  512. cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p );
  513. cmData_t* cmDataRecdAlloc( cmData_t* parent );
  514. // Append a pair node by linking the pair node 'pair' to the record node 'p'.
  515. // 'pair' is simply linked to 'p' via cmDataAppendChild() no
  516. // reallocation or duplicattion takes place.
  517. cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair );
  518. // Dynamically allocate a new record object and fill it with values
  519. // using a variable argument list.
  520. //
  521. // 1) Var-args format:
  522. // <label|id> <value>
  523. //
  524. // The <label|id> arg. gives the record pair label and the <value>
  525. // argument list gives the pair value.
  526. //
  527. // 2) The <value> argument has the same syntax as the cmDataListAllocLabelV()
  528. // call.
  529. // 3) The cmDataRecdAllocLabelV() arg. list should be terminated with NULL.
  530. // The cmDataRecdAllocIdV() arg. list should be terminated with 'kInvalidDtId'.
  531. cmDtRC_t cmDataRecdAllocLabelV( cmData_t* parent, cmErr_t* err, cmRC_t errRC, cmData_t** ref, va_list vl );
  532. cmDtRC_t cmDataRecdAllocLabelA( cmData_t* parent, cmErr_t* err, cmRC_t errRC, cmData_t** ref, ... );
  533. cmDtRC_t cmDataRecdAllocIdV( cmData_t* parent, cmErr_t* err, cmRC_t errRC, cmData_t** ref, va_list vl );
  534. cmDtRC_t cmDataRecdAllocIdA( cmData_t* parent, cmErr_t* err, cmRC_t errRC, cmData_t** ref, ... );
  535. // Extract the data in a record to C variables.
  536. // Var-args format:
  537. // (label | id) <cid> <typeId> <ptr> {cnt_ptr}
  538. // The var-args list must be NULL terminated.
  539. // The <'id' | 'label'> identify a pair.
  540. // The <cid> indicates the type of the target container.
  541. // The <typeId> indicates the C type of 'pointer'.
  542. // If <cid> is kArrayDtId then the <cnt_ptr} must be include to receive the
  543. // count of elements in the array.
  544. // The actual field type must be convertable into this pointer type or the
  545. // function will fail.
  546. // 'err' is an application supplied error object to be used if a required
  547. // field is missing. 'errRC' is the client result code to be passed with
  548. // the error report. See cmErrMsg(). Both 'err' and 'errRC' are optional.
  549. // Set kOptArgDtFl on 'typeId' to indicate that a field is optional.
  550. // <label|id> (<typeId> | kOptArgDtFl) <pointer>
  551. cmDtRC_t cmDataRecdParseLabelV(cmData_t* p, cmErr_t* err, unsigned errRC, va_list vl );
  552. cmDtRC_t cmDataRecdParseLabel( cmData_t* p, cmErr_t* err, unsigned errRC, ... );
  553. cmDtRC_t cmDataRecdParseIdV( cmData_t* p, cmErr_t* err, unsigned errRC, va_list vl );
  554. cmDtRC_t cmDataRecdParseId( cmData_t* p, cmErr_t* err, unsigned errRC, ... );
  555. //----------------------------------------------------------------------------
  556. // Serialization related functions
  557. //
  558. unsigned cmDataSerializeByteCount( const cmData_t* p );
  559. cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt );
  560. cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp );
  561. //----------------------------------------------------------------------------
  562. // Text to Data related functions
  563. //
  564. typedef cmHandle_t cmDataParserH_t;
  565. extern cmDataParserH_t cmDataParserNullHandle;
  566. cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp );
  567. cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp );
  568. bool cmDataParserIsValid( cmDataParserH_t h );
  569. // Parse a text representation into a 'record' type.
  570. // Note that the text is wrapped with implied curly braces
  571. // (e.g. "{ text }"). The contents of the text should therefore
  572. // fit the record syntax (e.g. the first token should be a
  573. // 'pair' label.
  574. cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp );
  575. //-----------------------------------------------------------------------------
  576. void cmDataPrint( const cmData_t* p, cmRpt_t* rpt );
  577. void cmDataTest( cmCtx_t* ctx );
  578. //)
  579. #ifdef __cplusplus
  580. }
  581. #endif
  582. #endif