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.

cmSerialize.c 45KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725
  1. #include "cmPrefix.h"
  2. #include "cmGlobal.h"
  3. #include "cmRpt.h"
  4. #include "cmErr.h"
  5. #include "cmCtx.h"
  6. #include "cmMem.h"
  7. #include "cmMallocDebug.h"
  8. #include "cmLinkedHeap.h"
  9. #include "cmSerialize.h"
  10. #define cmSrVersion (0)
  11. #ifdef cmBIG_ENDIAN
  12. #define _cmSrSwap16(v) (v)
  13. #define _cmSrSwap32(v) (v)
  14. #define _cmSrSwapFl (0)
  15. #else
  16. #define _cmSrSwap16(v) (v)
  17. #define _cmSrSwap32(v) (v)
  18. #define _cmSrSwapFl (1)
  19. #endif
  20. typedef struct
  21. {
  22. const char* label;
  23. unsigned typeId;
  24. unsigned byteCnt;
  25. bool swapFl;
  26. } _cmSrPrim_t;
  27. struct _cmSrStruct_str;
  28. // structure field desc record
  29. typedef struct _cmSrField_str
  30. {
  31. const _cmSrPrim_t* primPtr;
  32. struct _cmSrStruct_str* structPtr;
  33. bool arrayFl;
  34. struct _cmSrField_str* linkPtr;
  35. } _cmSrField_t;
  36. // structure description record
  37. typedef struct _cmSrStruct_str
  38. {
  39. unsigned typeId;
  40. _cmSrField_t* fieldList;
  41. struct _cmSrStruct_str* linkPtr;
  42. } _cmSrStruct_t;
  43. // state records track the format for read/write operations
  44. typedef struct _cmSrState_str
  45. {
  46. _cmSrStruct_t* structPtr; // this states current structure
  47. _cmSrField_t* fieldPtr; // this states current field
  48. struct _cmSrState_str* linkPtr; // prev state on stack
  49. unsigned arrayCnt; // array count for this struct array
  50. unsigned arrayIdx; // current array index for this struct array
  51. } _cmSrState_t;
  52. // data records are formed by each write operation
  53. typedef struct _cmSrData_str
  54. {
  55. unsigned typeId;
  56. unsigned eleCnt;
  57. unsigned byteCnt;
  58. void* dataPtr;
  59. bool arrayFl;
  60. bool swapFl;
  61. struct _cmSrData_str* linkPtr;
  62. } _cmSrData_t;
  63. typedef struct
  64. {
  65. cmErr_t err;
  66. cmLHeapH_t lhH;
  67. _cmSrStruct_t* structList;
  68. _cmSrState_t* wrStackPtr;
  69. _cmSrData_t* wrDataList;
  70. char* wrDataBufPtr;
  71. unsigned wrDataBufByteCnt;
  72. _cmSrState_t* rdStackPtr;
  73. const void* rdDataBufPtr;
  74. unsigned rdDataBufByteCnt;
  75. const char* rdCursorPtr;
  76. unsigned rdVersion;
  77. unsigned rdFlags;
  78. cmSrRC_t lastRC;
  79. } _cmSr_t;
  80. _cmSrPrim_t _cmSrPrimArray[] =
  81. {
  82. {"char", kCharSrId, sizeof(char), false },
  83. {"uchar", kUCharSrId, sizeof(char), false },
  84. {"short", kShortSrId, sizeof(short), true },
  85. {"ushort", kUShortSrId, sizeof(unsigned short), true },
  86. {"int", kIntSrId, sizeof(int), true },
  87. {"uint", kUIntSrId, sizeof(unsigned), true },
  88. {"long", kLongSrId, sizeof(long), true },
  89. {"ulong", kLongSrId, sizeof(unsigned long), true },
  90. {"float", kFloatSrId, sizeof(float), false },
  91. {"double", kDoubleSrId, sizeof(double), false },
  92. {"bool", kBoolSrId, sizeof(bool), sizeof(bool)>1 },
  93. {"<invalid>", kInvalidSrId, 0, false }
  94. };
  95. cmSrH_t cmSrNullHandle = { NULL };
  96. void _cmSrPrint( _cmSr_t* p, const char* fmt, ... )
  97. {
  98. va_list vl;
  99. va_start(vl,fmt);
  100. //p->rptFuncPtr(p->rptUserPtr,fmt,vl);
  101. cmRptVPrintf( p->err.rpt, fmt, vl );
  102. va_end(vl);
  103. }
  104. /*
  105. cmSrRC_t _cmSrErrorV( cmSrRC_t rc, _cmSr_t* p, const char* fmt, va_list vl )
  106. {
  107. const int bufCharCnt = 511;
  108. char buf[bufCharCnt+1];
  109. snprintf(buf,bufCharCnt,"Serializer Error code:%i ",rc);
  110. unsigned n = strlen(buf);
  111. vsnprintf(buf+n,bufCharCnt-n,fmt,vl);
  112. buf[bufCharCnt]=0;
  113. _cmSrPrint(p,"%s\n",buf);
  114. p->lastRC = rc;
  115. return rc;
  116. }
  117. */
  118. cmSrRC_t _cmSrError( cmSrRC_t rc, _cmSr_t* p, const char* fmt, ... )
  119. {
  120. va_list vl;
  121. va_start(vl,fmt);
  122. cmErrVMsg(&p->err,rc,fmt,vl);
  123. va_end(vl);
  124. return rc;
  125. }
  126. _cmSr_t* _cmSrHandleToPtr( cmSrH_t h )
  127. {
  128. assert( h.h != NULL );
  129. return (_cmSr_t*)h.h;
  130. }
  131. const _cmSrPrim_t* _cmSrIdToPrimPtr( unsigned primId )
  132. {
  133. unsigned i;
  134. for(i=0; _cmSrPrimArray[i].typeId != kInvalidSrId; ++i)
  135. if( _cmSrPrimArray[i].typeId == primId )
  136. return _cmSrPrimArray + i;
  137. return NULL;
  138. }
  139. _cmSrStruct_t* _cmSrIdToStructPtr( _cmSr_t* p, unsigned typeId )
  140. {
  141. _cmSrStruct_t* sp = p->structList;
  142. for(; sp != NULL; sp = sp->linkPtr )
  143. if( sp->typeId == typeId )
  144. return sp;
  145. return NULL;
  146. }
  147. void _cmSrClearStructList( _cmSr_t* p )
  148. {
  149. _cmSrStruct_t* csp = p->structList;
  150. while( csp != NULL )
  151. {
  152. _cmSrStruct_t* nsp = csp->linkPtr;
  153. _cmSrField_t* cfp = csp->fieldList;
  154. while( cfp != NULL )
  155. {
  156. _cmSrField_t* nfp = cfp->linkPtr;
  157. cmLHeapFree(p->lhH,cfp);
  158. cfp = nfp;
  159. }
  160. cmLHeapFree(p->lhH,csp);
  161. csp = nsp;
  162. }
  163. p->structList = NULL;
  164. }
  165. void _cmSrClearDataList( _cmSr_t* p )
  166. {
  167. _cmSrData_t* cdp = p->wrDataList;
  168. while( cdp != NULL )
  169. {
  170. _cmSrData_t* ndp = cdp->linkPtr;
  171. cmLHeapFree( p->lhH, cdp );
  172. cdp = ndp;
  173. }
  174. p->wrDataList = NULL;
  175. }
  176. cmSrRC_t _cmSrPopStateStack( _cmSr_t* p, _cmSrState_t** stackPtrPtr )
  177. {
  178. cmSrRC_t rc = kOkSrRC;
  179. _cmSrState_t* stackPtr = *stackPtrPtr;
  180. _cmSrState_t* sp = stackPtr;
  181. assert( sp != NULL );
  182. stackPtr = sp->linkPtr;
  183. if( sp->arrayCnt != cmInvalidCnt && sp->arrayIdx != sp->arrayCnt )
  184. rc = _cmSrError( kFormatViolationSrRC, p, "A type %i structure array field promised %i elements but only %i written.",sp->structPtr->typeId,sp->arrayCnt,sp->arrayIdx);
  185. cmLHeapFree(p->lhH,sp);
  186. *stackPtrPtr = stackPtr;
  187. return rc;
  188. }
  189. void _cmSrClearStateStack( _cmSr_t* p, _cmSrState_t** stackPtrPtr )
  190. {
  191. while( *stackPtrPtr != NULL )
  192. if( _cmSrPopStateStack( p, stackPtrPtr ) != kOkSrRC )
  193. break;
  194. }
  195. cmSrRC_t _cmSrFree( _cmSr_t* p )
  196. {
  197. cmSrRC_t rc = kOkSrRC;
  198. _cmSrClearDataList(p);
  199. _cmSrClearStateStack(p,&p->wrStackPtr);
  200. _cmSrClearStateStack(p,&p->rdStackPtr);
  201. cmMemPtrFree(&p->wrDataBufPtr);
  202. cmLHeapDestroy( &p->lhH );
  203. cmMemPtrFree(&p);
  204. return rc;
  205. }
  206. cmSrRC_t cmSrAlloc( cmSrH_t* hp, cmCtx_t* ctx )
  207. {
  208. cmSrRC_t rc = kOkSrRC;
  209. _cmSr_t* p = cmMemAllocZ( _cmSr_t, 1 );
  210. cmErrSetup(&p->err,&ctx->rpt,"Serializer");
  211. p->structList = NULL;
  212. p->lastRC = kOkSrRC;
  213. if( cmLHeapIsValid( p->lhH = cmLHeapCreate(1024,ctx)) == false )
  214. {
  215. rc = _cmSrError( kLHeapFailSrRC, p, "Linked heap initialization failed.");
  216. goto errLabel;
  217. }
  218. hp->h = p;
  219. errLabel:
  220. return rc;
  221. }
  222. cmSrRC_t cmSrFree( cmSrH_t* hp )
  223. {
  224. cmSrRC_t rc = kOkSrRC;
  225. _cmSr_t* p = NULL;
  226. if( hp == NULL )
  227. return kOkSrRC;
  228. if( cmSrIsValid(*hp) == false )
  229. return kOkSrRC;
  230. p = _cmSrHandleToPtr(*hp);
  231. if(( rc = _cmSrFree(p)) != kOkSrRC )
  232. goto errLabel;
  233. hp->h = NULL;
  234. errLabel:
  235. return rc;
  236. }
  237. bool cmSrIsValid( cmSrH_t h )
  238. { return h.h != NULL; }
  239. cmSrRC_t cmSrLastErrorCode( cmSrH_t h )
  240. {
  241. _cmSr_t* p = _cmSrHandleToPtr(h);
  242. return p->lastRC;
  243. }
  244. cmSrRC_t cmSrGetAndClearLastErrorCode( cmSrH_t h )
  245. {
  246. _cmSr_t* p = _cmSrHandleToPtr(h);
  247. cmSrRC_t rc = p->lastRC;
  248. p->lastRC = kOkSrRC;
  249. return rc;
  250. }
  251. cmSrRC_t cmSrFmtReset( cmSrH_t h )
  252. {
  253. _cmSr_t* p = _cmSrHandleToPtr(h);
  254. _cmSrClearStructList(p);
  255. p->lastRC = kOkSrRC;
  256. return cmSrWrReset(h);
  257. }
  258. cmSrRC_t cmSrFmtDefineStruct( cmSrH_t h, unsigned structTypeId )
  259. {
  260. cmSrRC_t rc = kOkSrRC;
  261. _cmSr_t* p = _cmSrHandleToPtr(h);
  262. _cmSrStruct_t* structPtr = NULL;
  263. assert( structTypeId >= kStructSrId );
  264. if( p->lastRC != kOkSrRC )
  265. return p->lastRC;
  266. if( structTypeId < kStructSrId )
  267. {
  268. rc = _cmSrError( kParamErrSrRC, p, "The structure type id %i is no greater than or equal to %i. (kStructSrId)",structTypeId,kStructSrId );
  269. goto errLabel;
  270. }
  271. if( _cmSrIdToStructPtr( p, structTypeId ) != NULL)
  272. {
  273. rc = _cmSrError( kParamErrSrRC, p, "The structure type id %i is already in use.",structTypeId );
  274. goto errLabel;
  275. }
  276. if(( structPtr = (_cmSrStruct_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrStruct_t))) == NULL )
  277. {
  278. rc = _cmSrError( kLHeapFailSrRC, p, "New structure allocate failed.");
  279. goto errLabel;
  280. }
  281. structPtr->typeId = structTypeId;
  282. structPtr->linkPtr = p->structList;
  283. p->structList = structPtr;
  284. errLabel:
  285. return rc;
  286. }
  287. cmSrRC_t _cmSrFmtField( cmSrH_t h, unsigned typeId, bool arrayFl )
  288. {
  289. cmSrRC_t rc = kOkSrRC;
  290. _cmSrStruct_t* structPtr = NULL;
  291. const _cmSrPrim_t* primPtr = NULL;
  292. _cmSrField_t* fieldPtr = NULL;
  293. _cmSrField_t* cfp = NULL;
  294. _cmSrField_t* pfp = NULL;
  295. _cmSr_t* p = _cmSrHandleToPtr(h);
  296. if( p->lastRC != kOkSrRC )
  297. return p->lastRC;
  298. if( typeId >= kStructSrId )
  299. {
  300. if(( structPtr = _cmSrIdToStructPtr( p, typeId )) == NULL )
  301. {
  302. rc = _cmSrError( kParamErrSrRC, p, "The structure associated with the type id %i could not be found.",typeId);
  303. goto errLabel;
  304. }
  305. }
  306. else
  307. {
  308. if( (typeId==kInvalidSrId) || ((primPtr = _cmSrIdToPrimPtr( typeId )) == NULL) )
  309. {
  310. rc = _cmSrError( kParamErrSrRC, p, "Type primitive type id %i is not valid.",typeId);
  311. goto errLabel;
  312. }
  313. }
  314. if(( fieldPtr = (_cmSrField_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrField_t))) == NULL )
  315. {
  316. rc = _cmSrError( kLHeapFailSrRC, p, "Field allocation failed for type %i.",typeId );
  317. goto errLabel;
  318. }
  319. fieldPtr->primPtr = primPtr;
  320. fieldPtr->structPtr = structPtr;
  321. fieldPtr->arrayFl = arrayFl;
  322. pfp = NULL;
  323. cfp = p->structList->fieldList;
  324. for(; cfp != NULL; cfp = cfp->linkPtr )
  325. pfp = cfp;
  326. if( pfp == NULL )
  327. p->structList->fieldList = fieldPtr;
  328. else
  329. pfp->linkPtr = fieldPtr;
  330. errLabel:
  331. return rc;
  332. }
  333. cmSrRC_t cmSrFmtStruct( cmSrH_t h, unsigned id ) { return _cmSrFmtField(h,id, false); }
  334. cmSrRC_t cmSrFmtChar( cmSrH_t h ) { return _cmSrFmtField(h,kCharSrId, false); }
  335. cmSrRC_t cmSrFmtUChar( cmSrH_t h ) { return _cmSrFmtField(h,kUCharSrId, false); }
  336. cmSrRC_t cmSrFmtShort( cmSrH_t h ) { return _cmSrFmtField(h,kShortSrId, false); }
  337. cmSrRC_t cmSrFmtUShort( cmSrH_t h ) { return _cmSrFmtField(h,kUShortSrId, false); }
  338. cmSrRC_t cmSrFmtLong( cmSrH_t h ) { return _cmSrFmtField(h,kLongSrId, false); }
  339. cmSrRC_t cmSrFmtULong( cmSrH_t h ) { return _cmSrFmtField(h,kULongSrId, false); }
  340. cmSrRC_t cmSrFmtInt( cmSrH_t h ) { return _cmSrFmtField(h,kIntSrId, false); }
  341. cmSrRC_t cmSrFmtUInt( cmSrH_t h ) { return _cmSrFmtField(h,kUIntSrId, false); }
  342. cmSrRC_t cmSrFmtFloat( cmSrH_t h ) { return _cmSrFmtField(h,kFloatSrId, false); }
  343. cmSrRC_t cmSrFmtDouble( cmSrH_t h ) { return _cmSrFmtField(h,kDoubleSrId, false); }
  344. cmSrRC_t cmSrFmtBool( cmSrH_t h ) { return _cmSrFmtField(h,kBoolSrId, false); }
  345. cmSrRC_t cmSrFmtStructV( cmSrH_t h, unsigned id ){ return _cmSrFmtField(h,id, true); }
  346. cmSrRC_t cmSrFmtCharV( cmSrH_t h ) { return _cmSrFmtField(h,kCharSrId, true); }
  347. cmSrRC_t cmSrFmtUCharV( cmSrH_t h ) { return _cmSrFmtField(h,kUCharSrId, true); }
  348. cmSrRC_t cmSrFmtShortV( cmSrH_t h ) { return _cmSrFmtField(h,kShortSrId, true); }
  349. cmSrRC_t cmSrFmtUShortV( cmSrH_t h ) { return _cmSrFmtField(h,kUShortSrId, true); }
  350. cmSrRC_t cmSrFmtLongV( cmSrH_t h ) { return _cmSrFmtField(h,kLongSrId, true); }
  351. cmSrRC_t cmSrFmtULongV( cmSrH_t h ) { return _cmSrFmtField(h,kULongSrId, true); }
  352. cmSrRC_t cmSrFmtIntV( cmSrH_t h ) { return _cmSrFmtField(h,kIntSrId, true); }
  353. cmSrRC_t cmSrFmtUIntV( cmSrH_t h ) { return _cmSrFmtField(h,kUIntSrId, true); }
  354. cmSrRC_t cmSrFmtFloatV( cmSrH_t h ) { return _cmSrFmtField(h,kFloatSrId, true); }
  355. cmSrRC_t cmSrFmtDoubleV( cmSrH_t h ) { return _cmSrFmtField(h,kDoubleSrId, true); }
  356. cmSrRC_t cmSrFmtBoolV( cmSrH_t h ) { return _cmSrFmtField(h,kBoolSrId, true); }
  357. cmSrRC_t cmSrDefFmt( cmSrH_t h, unsigned structTypeId, ... )
  358. {
  359. cmSrRC_t rc = kOkSrRC;
  360. va_list vl;
  361. va_start(vl,structTypeId);
  362. if((rc = cmSrFmtDefineStruct( h, structTypeId )) != kOkSrRC )
  363. goto errLabel;
  364. unsigned typeId = kCharSrId;
  365. while( typeId != kInvalidSrId )
  366. {
  367. typeId = va_arg(vl,unsigned);
  368. if( typeId == kInvalidSrId )
  369. break;
  370. bool arrayFl = cmIsFlag(typeId,kArraySrFl);
  371. typeId = cmClrFlag(typeId,kArraySrFl);
  372. if(( rc = _cmSrFmtField(h,typeId,arrayFl)) != kOkSrRC )
  373. goto errLabel;
  374. }
  375. errLabel:
  376. va_end(vl);
  377. return rc;
  378. }
  379. cmSrRC_t cmSrFmtPrint( cmSrH_t h )
  380. {
  381. _cmSr_t* p = _cmSrHandleToPtr(h);
  382. cmSrRC_t rc = kOkSrRC;
  383. const _cmSrStruct_t* sp = p->structList;
  384. for(; sp != NULL; sp = sp->linkPtr )
  385. {
  386. _cmSrPrint( p, "struct: %i", sp->typeId );
  387. unsigned indent = 2;
  388. const _cmSrField_t* fp = sp->fieldList;
  389. for(; fp != NULL; fp = fp->linkPtr )
  390. {
  391. unsigned i;
  392. char sp[ indent+1 ];
  393. sp[indent]=0;
  394. for(i=0; i<indent; ++i)
  395. sp[i] = ' ';
  396. if( fp->primPtr != NULL )
  397. _cmSrPrint( p, "%s prim: %i %s%s", sp, fp->primPtr->byteCnt, fp->primPtr->label, fp->arrayFl?"[]":"" );
  398. else
  399. {
  400. _cmSrPrint( p, "%s struct: %i %s", sp, fp->structPtr->typeId, fp->arrayFl?"[]":"" );
  401. indent += 2;
  402. }
  403. }
  404. }
  405. _cmSrPrint(p,"\n");
  406. return rc;
  407. }
  408. cmSrRC_t _cmSrPushStateStack( _cmSr_t* p, unsigned structTypeId, _cmSrState_t** stackPtrPtr )
  409. {
  410. cmSrRC_t rc = kOkSrRC;
  411. _cmSrStruct_t* refStructPtr;
  412. _cmSrState_t* stackPtr = *stackPtrPtr;
  413. // if this is the base structure then the wr stack will be empty
  414. if( stackPtr == NULL )
  415. refStructPtr = p->structList;
  416. else
  417. {
  418. // the wr stack contains members so this structure type should be the same as the current field type
  419. assert( stackPtr->fieldPtr != NULL );
  420. refStructPtr = stackPtr->fieldPtr->structPtr;
  421. }
  422. // no reference structure exists
  423. if( refStructPtr == NULL )
  424. {
  425. // if the write state stack is empty then the structList must also be empty
  426. if( stackPtr == NULL )
  427. {
  428. rc = _cmSrError( kFormatViolationSrRC, p, "Cannot write data without first providing the data format.");
  429. goto errLabel;
  430. }
  431. else
  432. {
  433. // the data format has been described but the current format field is not a structure
  434. assert( stackPtr->fieldPtr->primPtr != NULL );
  435. rc = _cmSrError( kFormatViolationSrRC, p, "Format violation. Expected primitive type:'%s'.", cmStringNullGuard(stackPtr->fieldPtr->primPtr->label ));
  436. goto errLabel;
  437. }
  438. }
  439. // if wrong type of structure
  440. if( refStructPtr->typeId != structTypeId )
  441. {
  442. rc = _cmSrError( kFormatViolationSrRC, p, "Format violation. Expected structure type:%i instead of structure type:%i.",refStructPtr->typeId,structTypeId );
  443. goto errLabel;
  444. }
  445. // allocate the new structure state
  446. _cmSrState_t* wsp = (_cmSrState_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrState_t));
  447. assert( wsp != NULL );
  448. // push the new structure state on the stack
  449. wsp->structPtr = refStructPtr;
  450. wsp->fieldPtr = NULL;
  451. wsp->linkPtr = stackPtr;
  452. wsp->arrayCnt = cmInvalidCnt;
  453. wsp->arrayIdx = cmInvalidIdx;
  454. stackPtr = wsp;
  455. *stackPtrPtr = stackPtr;
  456. errLabel:
  457. return rc;
  458. }
  459. cmSrRC_t cmSrWrReset( cmSrH_t h )
  460. {
  461. cmSrRC_t rc = kOkSrRC;
  462. _cmSr_t* p = _cmSrHandleToPtr(h);
  463. _cmSrClearStateStack(p,&p->wrStackPtr);
  464. p->wrStackPtr = NULL;
  465. _cmSrClearDataList(p);
  466. cmMemPtrFree(&p->wrDataBufPtr);
  467. p->wrDataBufByteCnt = 0;
  468. return rc;
  469. }
  470. cmSrRC_t _cmSrOnStruct( _cmSr_t* p, unsigned structTypeId, _cmSrState_t** stackPtrPtr )
  471. {
  472. cmSrRC_t rc = kOkSrRC;
  473. if( p->lastRC != kOkSrRC )
  474. return p->lastRC;
  475. if((rc = _cmSrPushStateStack(p,structTypeId,stackPtrPtr)) != kOkSrRC )
  476. goto errLabel;
  477. _cmSrState_t* stackPtr = *stackPtrPtr;
  478. // the base structure is never an array so it's linkPtr is NULL
  479. if( stackPtr->linkPtr != NULL )
  480. {
  481. stackPtr->linkPtr->arrayIdx += 1;
  482. if( stackPtr->linkPtr->arrayIdx > stackPtr->linkPtr->arrayCnt )
  483. {
  484. rc = _cmSrError( kFormatViolationSrRC, p, "The structure array is out of bounds (array count:%i).",stackPtr->linkPtr->arrayIdx );
  485. goto errLabel;
  486. }
  487. }
  488. *stackPtrPtr = stackPtr;
  489. errLabel:
  490. return rc;
  491. }
  492. cmSrRC_t cmSrWrStructBegin( cmSrH_t h, unsigned structTypeId )
  493. {
  494. _cmSr_t* p = _cmSrHandleToPtr(h);
  495. return _cmSrOnStruct( p, structTypeId, &p->wrStackPtr );
  496. }
  497. cmSrRC_t cmSrWrStructEnd( cmSrH_t h )
  498. {
  499. _cmSr_t* p = _cmSrHandleToPtr(h);
  500. assert( p->wrStackPtr != NULL );
  501. if( p->lastRC != kOkSrRC )
  502. return p->lastRC;
  503. return _cmSrPopStateStack(p, &p->wrStackPtr);
  504. }
  505. cmSrRC_t _cmSrWrField( cmSrH_t h, unsigned typeId, const void* dataPtr, unsigned eleCnt )
  506. {
  507. cmSrRC_t rc = kOkSrRC;
  508. _cmSr_t* p = _cmSrHandleToPtr(h);
  509. _cmSrField_t* refFieldPtr = NULL;
  510. unsigned refTypeId = cmInvalidId;
  511. unsigned dataByteCnt = 0;
  512. _cmSrData_t* dataRecdPtr = NULL;
  513. bool swapFl = false;
  514. if( p->lastRC != kOkSrRC )
  515. return p->lastRC;
  516. // verify the write stack exists
  517. if( p->wrStackPtr == NULL )
  518. {
  519. rc = _cmSrError( kFormatViolationSrRC, p, "The reference format is unexpectedly empty.");
  520. goto errLabel;
  521. }
  522. //
  523. // advance the current field
  524. //
  525. // if cur state fieldPtr is NULL then this is the first field in a structure
  526. if( p->wrStackPtr->fieldPtr == NULL )
  527. p->wrStackPtr->fieldPtr = p->wrStackPtr->structPtr->fieldList;
  528. else
  529. p->wrStackPtr->fieldPtr = p->wrStackPtr->fieldPtr->linkPtr;
  530. // verify that a reference field exists
  531. refFieldPtr = p->wrStackPtr->fieldPtr;
  532. if( refFieldPtr == NULL )
  533. {
  534. rc = _cmSrError( kFormatViolationSrRC, p, "The format reference structure has run out of fields.");
  535. goto errLabel;
  536. }
  537. // validate the array status of this field
  538. if( refFieldPtr->arrayFl==false && eleCnt>1 )
  539. {
  540. rc = _cmSrError( kFormatViolationSrRC, p, "The format reference indicates that this field is not an array however an array element count (%i) was given.",eleCnt);
  541. goto errLabel;
  542. }
  543. // get the reference type id
  544. refTypeId = refFieldPtr->primPtr == NULL ? refFieldPtr->structPtr->typeId : refFieldPtr->primPtr->typeId;
  545. // verify that the type being written matches the reference type
  546. if( refTypeId != typeId )
  547. {
  548. const char* refLbl = "struct";
  549. const char* cmtLbl = refLbl;
  550. if( refFieldPtr->primPtr != NULL )
  551. refLbl = refFieldPtr->primPtr->label;
  552. if( typeId < kStructSrId )
  553. cmtLbl = _cmSrIdToPrimPtr( typeId )->label;
  554. rc = _cmSrError( kFormatViolationSrRC, p, "Format violation: Exepected type %i (%s) but received %i (%s).", refTypeId,refLbl,typeId,cmtLbl);
  555. goto errLabel;
  556. }
  557. if( typeId < kStructSrId )
  558. {
  559. dataByteCnt += refFieldPtr->primPtr->byteCnt * eleCnt;
  560. swapFl = refFieldPtr->primPtr->swapFl && _cmSrSwapFl;
  561. }
  562. else
  563. {
  564. p->wrStackPtr->arrayCnt = eleCnt;
  565. p->wrStackPtr->arrayIdx = 0;
  566. }
  567. dataRecdPtr = (_cmSrData_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrData_t) + dataByteCnt );
  568. // iniit the new data recd
  569. dataRecdPtr->typeId = typeId;
  570. dataRecdPtr->eleCnt = eleCnt;
  571. dataRecdPtr->byteCnt = dataByteCnt;
  572. dataRecdPtr->arrayFl = refFieldPtr->arrayFl;
  573. dataRecdPtr->swapFl = swapFl;
  574. dataRecdPtr->linkPtr = NULL;
  575. dataRecdPtr->dataPtr = dataRecdPtr + 1;
  576. if( dataByteCnt > 0 )
  577. memcpy( dataRecdPtr->dataPtr, dataPtr, dataByteCnt );
  578. // link the new data recd to the end of the data chain
  579. _cmSrData_t* dp = p->wrDataList;
  580. for(; dp != NULL; dp = dp->linkPtr )
  581. if( dp->linkPtr == NULL )
  582. break;
  583. if( p->wrDataList == NULL )
  584. p->wrDataList = dataRecdPtr;
  585. else
  586. dp->linkPtr = dataRecdPtr;
  587. errLabel:
  588. return rc;
  589. }
  590. cmSrRC_t cmSrWrStruct( cmSrH_t h, unsigned structTypeId, unsigned eleCnt )
  591. { return _cmSrWrField(h,structTypeId,NULL,eleCnt); }
  592. cmSrRC_t cmSrWrChar( cmSrH_t h, char val )
  593. { return _cmSrWrField(h,kCharSrId,&val,1); }
  594. cmSrRC_t cmSrWrUChar( cmSrH_t h, unsigned char val )
  595. { return _cmSrWrField(h,kUCharSrId,&val,1); }
  596. cmSrRC_t cmSrWrShort( cmSrH_t h, short val )
  597. { return _cmSrWrField(h,kShortSrId,&val,1); }
  598. cmSrRC_t cmSrWrUShort( cmSrH_t h, unsigned short val )
  599. { return _cmSrWrField(h,kUShortSrId,&val,1); }
  600. cmSrRC_t cmSrWrLong( cmSrH_t h, long val )
  601. { return _cmSrWrField(h,kLongSrId,&val,1); }
  602. cmSrRC_t cmSrWrULong( cmSrH_t h, unsigned long val )
  603. { return _cmSrWrField(h,kULongSrId,&val,1); }
  604. cmSrRC_t cmSrWrInt( cmSrH_t h, int val )
  605. { return _cmSrWrField(h,kIntSrId,&val,1); }
  606. cmSrRC_t cmSrWrUInt( cmSrH_t h, unsigned val )
  607. { return _cmSrWrField(h,kUIntSrId,&val,1); }
  608. cmSrRC_t cmSrWrFloat( cmSrH_t h, float val )
  609. { return _cmSrWrField(h,kFloatSrId,&val,1); }
  610. cmSrRC_t cmSrWrDouble( cmSrH_t h, double val )
  611. { return _cmSrWrField(h,kDoubleSrId,&val,1); }
  612. cmSrRC_t cmSrWrBool( cmSrH_t h, bool val )
  613. { return _cmSrWrField(h,kBoolSrId,&val,1); }
  614. cmSrRC_t cmSrWrStr( cmSrH_t h, const char* val )
  615. {
  616. const char* ns = "";
  617. if( val == NULL )
  618. val = ns;
  619. return _cmSrWrField(h,kCharSrId,val,strlen(val)+1);
  620. }
  621. cmSrRC_t _cmSrWrArrayField( cmSrH_t h, unsigned typeId, const void* val, unsigned eleCnt )
  622. {
  623. if( val == NULL || eleCnt == 0 )
  624. {
  625. val = NULL;
  626. eleCnt = 0;
  627. }
  628. return _cmSrWrField(h,typeId,val,eleCnt);
  629. }
  630. cmSrRC_t cmSrWrCharV( cmSrH_t h, const char* val, unsigned eleCnt )
  631. { return _cmSrWrArrayField(h,kCharSrId,val,eleCnt); }
  632. cmSrRC_t cmSrWrUCharV( cmSrH_t h, const unsigned char* val, unsigned eleCnt )
  633. { return _cmSrWrArrayField(h,kUCharSrId,val,eleCnt); }
  634. cmSrRC_t cmSrWrShortV( cmSrH_t h, const short* val, unsigned eleCnt )
  635. { return _cmSrWrArrayField(h,kShortSrId,val,eleCnt); }
  636. cmSrRC_t cmSrWrUShortV( cmSrH_t h, const unsigned short* val, unsigned eleCnt )
  637. { return _cmSrWrArrayField(h,kUShortSrId,val,eleCnt); }
  638. cmSrRC_t cmSrWrLongV( cmSrH_t h, const long* val, unsigned eleCnt )
  639. { return _cmSrWrArrayField(h,kLongSrId,val,eleCnt); }
  640. cmSrRC_t cmSrWrULongV( cmSrH_t h, const unsigned long* val, unsigned eleCnt )
  641. { return _cmSrWrArrayField(h,kULongSrId,val,eleCnt); }
  642. cmSrRC_t cmSrWrIntV( cmSrH_t h, const int* val, unsigned eleCnt )
  643. { return _cmSrWrArrayField(h,kIntSrId,val,eleCnt); }
  644. cmSrRC_t cmSrWrUIntV( cmSrH_t h, const unsigned* val, unsigned eleCnt )
  645. { return _cmSrWrArrayField(h,kUIntSrId,val,eleCnt); }
  646. cmSrRC_t cmSrWrFloatV( cmSrH_t h, const float* val, unsigned eleCnt )
  647. { return _cmSrWrArrayField(h,kFloatSrId,val,eleCnt); }
  648. cmSrRC_t cmSrWrDoubleV( cmSrH_t h, const double* val, unsigned eleCnt )
  649. { return _cmSrWrArrayField(h,kDoubleSrId,val,eleCnt); }
  650. cmSrRC_t cmSrWrBoolV( cmSrH_t h, const bool* val, unsigned eleCnt )
  651. { return _cmSrWrArrayField(h,kBoolSrId,val,eleCnt); }
  652. void _cmSrCopyDataToBuf( void* dstPtr, const void* srcPtr, unsigned byteCnt, unsigned typeId, bool swapFl, unsigned eleCnt )
  653. {
  654. if( !swapFl )
  655. {
  656. memcpy(dstPtr,srcPtr,byteCnt);
  657. return;
  658. }
  659. switch( typeId )
  660. {
  661. case kShortSrId:
  662. case kUShortSrId:
  663. {
  664. unsigned i;
  665. const short* sp = (const short*)srcPtr;
  666. short* dp = (short*)dstPtr;
  667. for(i=0; i<eleCnt; ++i)
  668. dp[i] = _cmSrSwap16(sp[i]);
  669. }
  670. break;
  671. case kLongSrId:
  672. case kULongSrId:
  673. case kIntSrId:
  674. case kUIntSrId:
  675. {
  676. unsigned i;
  677. const long* sp = (const long*)srcPtr;
  678. long* dp = (long*)dstPtr;
  679. for(i=0; i<eleCnt; ++i)
  680. dp[i] = _cmSrSwap32(sp[i]);
  681. }
  682. break;
  683. default:
  684. assert(0);
  685. }
  686. }
  687. void* cmSrWrAllocBuf( cmSrH_t h, unsigned* bufByteCntPtr )
  688. {
  689. _cmSr_t* p = _cmSrHandleToPtr(h);
  690. _cmSrData_t* cdp = p->wrDataList;;
  691. assert( bufByteCntPtr != NULL );
  692. *bufByteCntPtr = 0;
  693. p->wrDataBufByteCnt = 2 * sizeof(unsigned); // header words
  694. if( p->lastRC != kOkSrRC )
  695. return NULL;
  696. // determine the data buf size
  697. for(; cdp!=NULL; cdp = cdp->linkPtr )
  698. {
  699. // include spcme for structure type id
  700. if( cdp->typeId >= kStructSrId )
  701. p->wrDataBufByteCnt += sizeof(unsigned);
  702. // include spcme for array element count
  703. if( cdp->arrayFl )
  704. p->wrDataBufByteCnt += sizeof(unsigned);
  705. // include spcme for cmtual data
  706. p->wrDataBufByteCnt += cdp->byteCnt;
  707. }
  708. // allocate the data buffer
  709. p->wrDataBufPtr = cmMemResizeZ( char, p->wrDataBufPtr, p->wrDataBufByteCnt );
  710. cdp = p->wrDataList;
  711. char* dp = p->wrDataBufPtr;
  712. char* ep = dp + p->wrDataBufByteCnt;
  713. // header version
  714. *(unsigned*)dp = _cmSrSwap32(cmSrVersion);
  715. dp += sizeof(unsigned);
  716. // header flags
  717. *(unsigned*)dp = _cmSrSwap32(0);
  718. dp += sizeof(unsigned);
  719. // fill the data buffer
  720. for(; cdp!=NULL; cdp=cdp->linkPtr)
  721. {
  722. // structure data records contain only the typeId and optionally an array count
  723. if( cdp->typeId >= kStructSrId )
  724. {
  725. *((unsigned*)dp) = _cmSrSwap32(cdp->typeId);
  726. dp += sizeof(unsigned);
  727. assert(dp <= ep);
  728. }
  729. // array data elements begin with a element count
  730. if( cdp->arrayFl )
  731. {
  732. *((unsigned*)dp) = _cmSrSwap32(cdp->eleCnt);
  733. dp += sizeof(unsigned);
  734. assert(dp <= ep);
  735. }
  736. // copy data into buf
  737. if( cdp->byteCnt > 0 )
  738. {
  739. assert( cdp->typeId < kStructSrId );
  740. _cmSrCopyDataToBuf(dp, cdp->dataPtr, cdp->byteCnt, cdp->typeId, cdp->swapFl, cdp->eleCnt );
  741. //memcpy( dp, cdp->dataPtr, cdp->byteCnt );
  742. dp += cdp->byteCnt;
  743. assert(dp <= ep);
  744. }
  745. }
  746. *bufByteCntPtr = p->wrDataBufByteCnt;
  747. _cmSrClearDataList(p);
  748. return p->wrDataBufPtr;
  749. }
  750. void* cmSrWrGetBuf( cmSrH_t h, unsigned* bufByteCntPtr )
  751. {
  752. _cmSr_t* p = _cmSrHandleToPtr(h);
  753. assert( bufByteCntPtr != NULL);
  754. *bufByteCntPtr = p->wrDataBufByteCnt;
  755. return p->wrDataBufPtr;
  756. }
  757. unsigned _cmSrProcUInt( _cmSr_t* p )
  758. {
  759. unsigned val = _cmSrSwap32(*(unsigned*)p->rdCursorPtr);
  760. *(unsigned*)p->rdCursorPtr = val;
  761. p->rdCursorPtr += sizeof(unsigned);
  762. return val;
  763. }
  764. cmSrRC_t _cmSrProcBuf( _cmSr_t* p, _cmSrStruct_t* structPtr )
  765. {
  766. cmSrRC_t rc = kOkSrRC;
  767. const _cmSrField_t* cfp = structPtr->fieldList;
  768. for(; cfp != NULL; cfp = cfp->linkPtr )
  769. {
  770. unsigned eleCnt = 1;
  771. // if this is a structure
  772. if( cfp->structPtr != NULL )
  773. {
  774. unsigned structTypeId = _cmSrProcUInt(p);
  775. if( structTypeId != cfp->structPtr->typeId )
  776. {
  777. rc = _cmSrError( kFormatViolationSrRC, p, "Expected type id:%i encountered type id:%i",cfp->structPtr->typeId,structTypeId);
  778. goto errLabel;
  779. }
  780. }
  781. // if this is an array
  782. if( cfp->arrayFl )
  783. eleCnt = _cmSrProcUInt(p);
  784. // if this is a primitive type
  785. if( cfp->primPtr != NULL )
  786. {
  787. unsigned dataByteCnt = eleCnt * cfp->primPtr->byteCnt;
  788. _cmSrCopyDataToBuf( (void*)p->rdCursorPtr, p->rdCursorPtr, dataByteCnt, cfp->primPtr->typeId, cfp->primPtr->swapFl & _cmSrSwapFl, eleCnt );
  789. p->rdCursorPtr += dataByteCnt;
  790. }
  791. else // this is a structure type
  792. {
  793. unsigned i;
  794. for(i=0; i<eleCnt; ++i)
  795. if((rc = _cmSrProcBuf(p,cfp->structPtr)) != kOkSrRC )
  796. goto errLabel;
  797. }
  798. }
  799. errLabel:
  800. return rc;
  801. }
  802. cmSrRC_t cmSrRdProcessBuffer( cmSrH_t h, void* buf, unsigned bufByteCnt )
  803. {
  804. cmSrRC_t rc = kOkSrRC;
  805. _cmSr_t* p = _cmSrHandleToPtr(h);
  806. p->rdDataBufPtr = buf;
  807. p->rdDataBufByteCnt = bufByteCnt;
  808. p->rdCursorPtr = buf;
  809. // process the header
  810. _cmSrProcUInt(p);
  811. _cmSrProcUInt(p);
  812. if((rc = _cmSrProcBuf(p,p->structList)) != kOkSrRC )
  813. goto errLabel;
  814. errLabel:
  815. return rc;
  816. }
  817. cmSrRC_t cmSrRdSetup( cmSrH_t h, const void* buf, unsigned bufByteCnt )
  818. {
  819. cmSrRC_t rc = kOkSrRC;
  820. _cmSr_t* p = _cmSrHandleToPtr(h);
  821. p->rdDataBufPtr = buf;
  822. p->rdDataBufByteCnt = bufByteCnt;
  823. p->rdCursorPtr = buf;
  824. _cmSrClearStateStack(p,&p->rdStackPtr);
  825. p->rdStackPtr = NULL;
  826. // buffer must at least contain a header
  827. assert( bufByteCnt >= 2 * sizeof(unsigned) );
  828. p->rdVersion = (*(unsigned*)p->rdCursorPtr);
  829. p->rdCursorPtr += sizeof(unsigned);
  830. p->rdFlags = (*(unsigned*)p->rdCursorPtr);
  831. p->rdCursorPtr += sizeof(unsigned);
  832. return rc;
  833. }
  834. cmSrRC_t cmSrRdStructBegin( cmSrH_t h, unsigned structTypeId )
  835. {
  836. _cmSr_t* p = _cmSrHandleToPtr(h);
  837. return _cmSrOnStruct( p, structTypeId, &p->rdStackPtr );
  838. }
  839. cmSrRC_t cmSrRdStructEnd( cmSrH_t h )
  840. {
  841. _cmSr_t* p = _cmSrHandleToPtr(h);
  842. assert( p->rdStackPtr != NULL );
  843. if( p->lastRC != kOkSrRC )
  844. return p->lastRC;
  845. return _cmSrPopStateStack(p,&p->rdStackPtr);
  846. }
  847. cmSrRC_t _cmSrRead( _cmSr_t* p, unsigned typeId, const void** dataPtrPtr, unsigned* dataByteCntPtr, unsigned* eleCntPtr )
  848. {
  849. cmSrRC_t rc = kOkSrRC;
  850. _cmSrField_t* refFieldPtr = NULL;
  851. unsigned refTypeId = cmInvalidId;
  852. unsigned eleCnt = 1;
  853. if( eleCntPtr != NULL )
  854. *eleCntPtr = 0;
  855. if( dataByteCntPtr != NULL )
  856. *dataByteCntPtr = 0;
  857. if( dataPtrPtr != NULL )
  858. *dataPtrPtr = NULL;
  859. if( p->lastRC != kOkSrRC )
  860. return p->lastRC;
  861. // verify the write stack exists - all fields exists inside structures so the stack must have at least one element
  862. if( p->rdStackPtr == NULL )
  863. {
  864. rc = _cmSrError( kFormatViolationSrRC, p, "The reference format is unexpectedly empty.");
  865. goto errLabel;
  866. }
  867. //
  868. // advance the current field
  869. //
  870. // if cur state fieldPtr is NULL then this is the first field in a structure
  871. if( p->rdStackPtr->fieldPtr == NULL )
  872. p->rdStackPtr->fieldPtr = p->rdStackPtr->structPtr->fieldList;
  873. else
  874. p->rdStackPtr->fieldPtr = p->rdStackPtr->fieldPtr->linkPtr;
  875. // verify that a reference field exists
  876. refFieldPtr = p->rdStackPtr->fieldPtr;
  877. if( refFieldPtr == NULL )
  878. {
  879. rc = _cmSrError( kFormatViolationSrRC, p, "The format reference structure has run out of fields.");
  880. goto errLabel;
  881. }
  882. // get the reference type id
  883. refTypeId = refFieldPtr->primPtr == NULL ? refFieldPtr->structPtr->typeId : refFieldPtr->primPtr->typeId;
  884. // verify that the type being written matches the reference type
  885. if( refTypeId != typeId )
  886. {
  887. const char* refLbl = "struct";
  888. const char* cmtLbl = refLbl;
  889. if( refFieldPtr->primPtr != NULL )
  890. refLbl = refFieldPtr->primPtr->label;
  891. if( typeId < kStructSrId )
  892. cmtLbl = _cmSrIdToPrimPtr( typeId )->label;
  893. rc = _cmSrError( kFormatViolationSrRC, p, "Format violation: Exepected type %i (%s) but received %i (%s).", refTypeId,refLbl,typeId,cmtLbl);
  894. goto errLabel;
  895. }
  896. // if this is a primitive type
  897. if( typeId < kStructSrId )
  898. {
  899. unsigned byteCnt = refFieldPtr->primPtr->byteCnt;
  900. if( refFieldPtr->arrayFl )
  901. {
  902. eleCnt = *(unsigned*)p->rdCursorPtr;
  903. byteCnt *= eleCnt;
  904. p->rdCursorPtr += sizeof(unsigned);
  905. if( eleCntPtr == NULL )
  906. {
  907. rc = _cmSrError( kFormatViolationSrRC, p, "A scalar read was performed where an array was expected. type:%s array count:%i.",refFieldPtr->primPtr->label,eleCnt);
  908. goto errLabel;
  909. }
  910. *eleCntPtr = eleCnt;
  911. }
  912. *dataPtrPtr = p->rdCursorPtr;
  913. *dataByteCntPtr = byteCnt;
  914. p->rdCursorPtr += byteCnt;
  915. }
  916. else // this is a structure type
  917. {
  918. unsigned structTypeId = structTypeId = *(unsigned*)p->rdCursorPtr;
  919. p->rdCursorPtr += sizeof(unsigned);
  920. if( refFieldPtr->arrayFl )
  921. {
  922. eleCnt = *(unsigned*)p->rdCursorPtr;
  923. p->rdCursorPtr += sizeof(unsigned);
  924. }
  925. p->rdStackPtr->arrayCnt = eleCnt;
  926. p->rdStackPtr->arrayIdx = 0;
  927. assert(eleCntPtr != NULL );
  928. *eleCntPtr = eleCnt;
  929. }
  930. errLabel:
  931. return rc;
  932. }
  933. cmSrRC_t cmSrReadStruct( cmSrH_t h, unsigned structTypeId, unsigned* arrayCnt )
  934. {
  935. _cmSr_t* p = _cmSrHandleToPtr(h);
  936. return _cmSrRead(p, structTypeId, NULL, NULL, arrayCnt );
  937. }
  938. cmSrRC_t _cmSrReadScalar( cmSrH_t h, unsigned typeId, void* valPtr, unsigned scalarByteCnt )
  939. {
  940. cmSrRC_t rc = kOkSrRC;
  941. _cmSr_t* p = _cmSrHandleToPtr(h);
  942. const void* dataPtr = NULL;
  943. unsigned dataByteCnt = 0;
  944. if((rc= _cmSrRead(p,typeId, &dataPtr, &dataByteCnt, NULL )) != kOkSrRC )
  945. return rc;
  946. memcpy(valPtr,dataPtr,dataByteCnt);
  947. return rc;
  948. }
  949. cmSrRC_t _cmSrReadV( cmSrH_t h, unsigned typeId, const void** valPtrPtr, unsigned scalarByteCnt, unsigned* eleCntPtr )
  950. {
  951. cmSrRC_t rc = kOkSrRC;
  952. _cmSr_t* p = _cmSrHandleToPtr(h);
  953. unsigned dataByteCnt = 0;
  954. if((rc= _cmSrRead(p,typeId, valPtrPtr, &dataByteCnt, eleCntPtr )) != kOkSrRC )
  955. return rc;
  956. assert( dataByteCnt == scalarByteCnt * (*eleCntPtr));
  957. return rc;
  958. }
  959. cmSrRC_t cmSrReadChar( cmSrH_t h, char* valPtr )
  960. { return _cmSrReadScalar( h, kCharSrId, valPtr, sizeof(char)); }
  961. cmSrRC_t cmSrReadUChar( cmSrH_t h, unsigned char* valPtr )
  962. { return _cmSrReadScalar( h, kUCharSrId, valPtr, sizeof(unsigned char)); }
  963. cmSrRC_t cmSrReadShort( cmSrH_t h, short* valPtr )
  964. { return _cmSrReadScalar( h, kShortSrId, valPtr, sizeof(short)); }
  965. cmSrRC_t cmSrReadUShort( cmSrH_t h, unsigned short* valPtr )
  966. { return _cmSrReadScalar( h, kUShortSrId, valPtr, sizeof(unsigned short)); }
  967. cmSrRC_t cmSrReadLong( cmSrH_t h, long* valPtr)
  968. { return _cmSrReadScalar( h, kLongSrId, valPtr, sizeof(long)); }
  969. cmSrRC_t cmSrReadULong( cmSrH_t h, unsigned long* valPtr )
  970. { return _cmSrReadScalar( h, kULongSrId, valPtr, sizeof(unsigned long)); }
  971. cmSrRC_t cmSrReadInt( cmSrH_t h, int* valPtr)
  972. { return _cmSrReadScalar( h, kIntSrId, valPtr, sizeof(int)); }
  973. cmSrRC_t cmSrReadUInt( cmSrH_t h, unsigned* valPtr )
  974. { return _cmSrReadScalar( h, kUIntSrId, valPtr, sizeof(unsigned int)); }
  975. cmSrRC_t cmSrReadFloat( cmSrH_t h, float* valPtr )
  976. { return _cmSrReadScalar( h, kFloatSrId, valPtr, sizeof(float)); }
  977. cmSrRC_t cmSrReadDouble( cmSrH_t h, double* valPtr )
  978. { return _cmSrReadScalar( h, kDoubleSrId, valPtr, sizeof(double)); }
  979. cmSrRC_t cmSrReadBool( cmSrH_t h, bool* valPtr )
  980. { return _cmSrReadScalar( h, kBoolSrId, valPtr, sizeof(bool)); }
  981. cmSrRC_t cmSrReadCharV( cmSrH_t h, char** valPtrPtr, unsigned* eleCntPtr )
  982. { return _cmSrReadV( h, kCharSrId, (const void**)valPtrPtr, sizeof(char), eleCntPtr); }
  983. cmSrRC_t cmSrReadUCharV( cmSrH_t h, unsigned char** valPtrPtr, unsigned* eleCntPtr )
  984. { return _cmSrReadV( h, kUCharSrId, (const void**)valPtrPtr, sizeof(unsigned char), eleCntPtr); }
  985. cmSrRC_t cmSrReadShortV( cmSrH_t h, short** valPtrPtr, unsigned* eleCntPtr )
  986. { return _cmSrReadV( h, kShortSrId, (const void**)valPtrPtr, sizeof(short), eleCntPtr); }
  987. cmSrRC_t cmSrReadUShortV( cmSrH_t h, unsigned short** valPtrPtr, unsigned* eleCntPtr )
  988. { return _cmSrReadV( h, kUShortSrId, (const void**)valPtrPtr, sizeof(unsigned short), eleCntPtr); }
  989. cmSrRC_t cmSrReadLongV( cmSrH_t h, long** valPtrPtr, unsigned* eleCntPtr )
  990. { return _cmSrReadV( h, kLongSrId, (const void**)valPtrPtr, sizeof(long), eleCntPtr); }
  991. cmSrRC_t cmSrReadULongV( cmSrH_t h, unsigned long** valPtrPtr, unsigned* eleCntPtr )
  992. { return _cmSrReadV( h, kULongSrId, (const void**)valPtrPtr, sizeof(unsigned long), eleCntPtr); }
  993. cmSrRC_t cmSrReadIntV( cmSrH_t h, int** valPtrPtr, unsigned* eleCntPtr )
  994. { return _cmSrReadV( h, kIntSrId, (const void**)valPtrPtr, sizeof(int), eleCntPtr); }
  995. cmSrRC_t cmSrReadUIntV( cmSrH_t h, unsigned** valPtrPtr, unsigned* eleCntPtr )
  996. { return _cmSrReadV( h, kUIntSrId, (const void**)valPtrPtr, sizeof(unsigned int), eleCntPtr); }
  997. cmSrRC_t cmSrReadFloatV( cmSrH_t h, float** valPtrPtr, unsigned* eleCntPtr )
  998. { return _cmSrReadV( h, kFloatSrId, (const void**)valPtrPtr, sizeof(float), eleCntPtr); }
  999. cmSrRC_t cmSrReadDoubleV( cmSrH_t h, double** valPtrPtr, unsigned* eleCntPtr )
  1000. { return _cmSrReadV( h, kDoubleSrId, (const void**)valPtrPtr, sizeof(double), eleCntPtr); }
  1001. cmSrRC_t cmSrReadBoolV( cmSrH_t h, bool** valPtrPtr, unsigned* eleCntPtr )
  1002. { return _cmSrReadV( h, kBoolSrId, (const void**)valPtrPtr, sizeof(bool), eleCntPtr); }
  1003. cmSrRC_t cmSrReadCharCV( cmSrH_t h, const char** valPtrPtr, unsigned* eleCntPtr )
  1004. { return _cmSrReadV( h, kCharSrId, (const void**)valPtrPtr, sizeof(char), eleCntPtr); }
  1005. cmSrRC_t cmSrReadUCharCV( cmSrH_t h, const unsigned char** valPtrPtr, unsigned* eleCntPtr )
  1006. { return _cmSrReadV( h, kUCharSrId, (const void**)valPtrPtr, sizeof(unsigned char), eleCntPtr); }
  1007. cmSrRC_t cmSrReadShortCV( cmSrH_t h, const short** valPtrPtr, unsigned* eleCntPtr )
  1008. { return _cmSrReadV( h, kShortSrId, (const void**)valPtrPtr, sizeof(short), eleCntPtr); }
  1009. cmSrRC_t cmSrReadUShortCV( cmSrH_t h, const unsigned short** valPtrPtr, unsigned* eleCntPtr )
  1010. { return _cmSrReadV( h, kUShortSrId, (const void**)valPtrPtr, sizeof(unsigned short), eleCntPtr); }
  1011. cmSrRC_t cmSrReadLongCV( cmSrH_t h, const long** valPtrPtr, unsigned* eleCntPtr )
  1012. { return _cmSrReadV( h, kLongSrId, (const void**)valPtrPtr, sizeof(long), eleCntPtr); }
  1013. cmSrRC_t cmSrReadULongCV( cmSrH_t h, const unsigned long** valPtrPtr, unsigned* eleCntPtr )
  1014. { return _cmSrReadV( h, kULongSrId, (const void**)valPtrPtr, sizeof(unsigned long), eleCntPtr); }
  1015. cmSrRC_t cmSrReadIntCV( cmSrH_t h, const int** valPtrPtr, unsigned* eleCntPtr )
  1016. { return _cmSrReadV( h, kIntSrId, (const void**)valPtrPtr, sizeof(int), eleCntPtr); }
  1017. cmSrRC_t cmSrReadUIntCV( cmSrH_t h, const unsigned** valPtrPtr, unsigned* eleCntPtr )
  1018. { return _cmSrReadV( h, kUIntSrId, (const void**)valPtrPtr, sizeof(unsigned int), eleCntPtr); }
  1019. cmSrRC_t cmSrReadFloatCV( cmSrH_t h, const float** valPtrPtr, unsigned* eleCntPtr )
  1020. { return _cmSrReadV( h, kFloatSrId, (const void**)valPtrPtr, sizeof(float), eleCntPtr); }
  1021. cmSrRC_t cmSrReadDoubleCV( cmSrH_t h, const double** valPtrPtr, unsigned* eleCntPtr )
  1022. { return _cmSrReadV( h, kDoubleSrId, (const void**)valPtrPtr, sizeof(double), eleCntPtr); }
  1023. cmSrRC_t cmSrReadBoolCV( cmSrH_t h, const bool** valPtrPtr, unsigned* eleCntPtr )
  1024. { return _cmSrReadV( h, kBoolSrId, (const void**)valPtrPtr, sizeof(bool), eleCntPtr); }
  1025. unsigned cmSrRdStruct( cmSrH_t h, unsigned structTypeId )
  1026. {
  1027. unsigned eleCnt;
  1028. return cmSrReadStruct(h,structTypeId,&eleCnt) == kOkSrRC ? eleCnt : cmInvalidCnt;
  1029. }
  1030. char cmSrRdChar( cmSrH_t h )
  1031. {
  1032. char val;
  1033. return cmSrReadChar(h,&val) == kOkSrRC ? val : 0;
  1034. }
  1035. unsigned char cmSrRdUChar( cmSrH_t h )
  1036. {
  1037. unsigned char val;
  1038. return cmSrReadUChar(h,&val) == kOkSrRC ? val : 0;
  1039. }
  1040. short cmSrRdShort( cmSrH_t h )
  1041. {
  1042. short val;
  1043. return cmSrReadShort(h,&val) == kOkSrRC ? val : 0;
  1044. }
  1045. unsigned short cmSrRdUShort( cmSrH_t h )
  1046. {
  1047. unsigned short val;
  1048. return cmSrReadUShort(h,&val) == kOkSrRC ? val : 0;
  1049. }
  1050. long cmSrRdLong( cmSrH_t h )
  1051. {
  1052. long val;
  1053. return cmSrReadLong(h,&val) == kOkSrRC ? val : 0;
  1054. }
  1055. unsigned long cmSrRdULong( cmSrH_t h )
  1056. {
  1057. unsigned long val;
  1058. return cmSrReadULong(h,&val) == kOkSrRC ? val : 0;
  1059. }
  1060. int cmSrRdInt( cmSrH_t h )
  1061. {
  1062. int val;
  1063. return cmSrReadInt(h,&val) == kOkSrRC ? val : 0;
  1064. }
  1065. unsigned int cmSrRdUInt( cmSrH_t h )
  1066. {
  1067. unsigned val;
  1068. return cmSrReadUInt(h,&val) == kOkSrRC ? val : 0;
  1069. }
  1070. float cmSrRdFloat( cmSrH_t h )
  1071. {
  1072. float val;
  1073. return cmSrReadFloat(h,&val) == kOkSrRC ? val : 0;
  1074. }
  1075. double cmSrRdDouble( cmSrH_t h )
  1076. {
  1077. double val;
  1078. return cmSrReadDouble(h,&val) == kOkSrRC ? val : 0;
  1079. }
  1080. bool cmSrRdBool( cmSrH_t h )
  1081. {
  1082. bool val;
  1083. return cmSrReadBool(h,&val) == kOkSrRC ? val : 0;
  1084. }
  1085. char* cmSrRdCharV( cmSrH_t h, unsigned* eleCntPtr)
  1086. {
  1087. char* valPtr;
  1088. return cmSrReadCharV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1089. }
  1090. unsigned char* cmSrRdUCharV( cmSrH_t h, unsigned* eleCntPtr)
  1091. {
  1092. unsigned char* valPtr;
  1093. return cmSrReadUCharV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1094. }
  1095. short* cmSrRdShortV( cmSrH_t h, unsigned* eleCntPtr)
  1096. {
  1097. short* valPtr;
  1098. return cmSrReadShortV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1099. }
  1100. unsigned short* cmSrRdUShortV( cmSrH_t h, unsigned* eleCntPtr)
  1101. {
  1102. unsigned short* valPtr;
  1103. return cmSrReadUShortV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1104. }
  1105. long* cmSrRdLongV( cmSrH_t h, unsigned* eleCntPtr)
  1106. {
  1107. long* valPtr;
  1108. return cmSrReadLongV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1109. }
  1110. unsigned long* cmSrRdULongV( cmSrH_t h, unsigned* eleCntPtr)
  1111. {
  1112. unsigned long* valPtr;
  1113. return cmSrReadULongV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1114. }
  1115. int* cmSrRdIntV( cmSrH_t h, unsigned* eleCntPtr)
  1116. {
  1117. int* valPtr;
  1118. return cmSrReadIntV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1119. }
  1120. unsigned int* cmSrRdUIntV( cmSrH_t h, unsigned* eleCntPtr)
  1121. {
  1122. unsigned* valPtr;
  1123. return cmSrReadUIntV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1124. }
  1125. float* cmSrRdFloatV( cmSrH_t h, unsigned* eleCntPtr)
  1126. {
  1127. float* valPtr;
  1128. return cmSrReadFloatV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1129. }
  1130. double* cmSrRdDoubleV( cmSrH_t h, unsigned* eleCntPtr)
  1131. {
  1132. double* valPtr;
  1133. return cmSrReadDoubleV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1134. }
  1135. bool* cmSrRdBoolV( cmSrH_t h, unsigned* eleCntPtr)
  1136. {
  1137. bool* valPtr;
  1138. return cmSrReadBoolV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1139. }
  1140. const char* cmSrRdCharCV( cmSrH_t h, unsigned* eleCntPtr)
  1141. {
  1142. const char* valPtr;
  1143. return cmSrReadCharCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1144. }
  1145. const unsigned char* cmSrRdUCharCV( cmSrH_t h, unsigned* eleCntPtr)
  1146. {
  1147. const unsigned char* valPtr;
  1148. return cmSrReadUCharCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1149. }
  1150. const short* cmSrRdShortCV( cmSrH_t h, unsigned* eleCntPtr)
  1151. {
  1152. const short* valPtr;
  1153. return cmSrReadShortCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1154. }
  1155. const unsigned short* cmSrRdUShortCV( cmSrH_t h, unsigned* eleCntPtr)
  1156. {
  1157. const unsigned short* valPtr;
  1158. return cmSrReadUShortCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1159. }
  1160. const long* cmSrRdLongCV( cmSrH_t h, unsigned* eleCntPtr)
  1161. {
  1162. const long* valPtr;
  1163. return cmSrReadLongCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1164. }
  1165. const unsigned long* cmSrRdULongCV( cmSrH_t h, unsigned* eleCntPtr)
  1166. {
  1167. const unsigned long* valPtr;
  1168. return cmSrReadULongCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1169. }
  1170. const int* cmSrRdIntCV( cmSrH_t h, unsigned* eleCntPtr)
  1171. {
  1172. const int* valPtr;
  1173. return cmSrReadIntCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1174. }
  1175. const unsigned int* cmSrRdUIntCV( cmSrH_t h, unsigned* eleCntPtr)
  1176. {
  1177. const unsigned* valPtr;
  1178. return cmSrReadUIntCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1179. }
  1180. const float* cmSrRdFloatCV( cmSrH_t h, unsigned* eleCntPtr)
  1181. {
  1182. const float* valPtr;
  1183. return cmSrReadFloatCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1184. }
  1185. const double* cmSrRdDoubleCV( cmSrH_t h, unsigned* eleCntPtr)
  1186. {
  1187. const double* valPtr;
  1188. return cmSrReadDoubleCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1189. }
  1190. const bool* cmSrRdBoolCV( cmSrH_t h, unsigned* eleCntPtr)
  1191. {
  1192. const bool* valPtr;
  1193. return cmSrReadBoolCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL;
  1194. }
  1195. //{ { label:cmSerialEx }
  1196. //(
  1197. // cmSrTest() is a serializer example function.
  1198. //)
  1199. //[
  1200. cmSrRC_t cmSrTest( cmCtx_t* ctx )
  1201. {
  1202. unsigned i,j,k;
  1203. cmSrRC_t rc = kOkSrRC;
  1204. cmSrH_t h;
  1205. unsigned bufByteCnt;
  1206. const void* bufPtr;
  1207. enum
  1208. {
  1209. kVectSrId = kStructSrId, // nested structure id
  1210. kVectArrSrId // outer structure id
  1211. };
  1212. // nested structure
  1213. typedef struct
  1214. {
  1215. float* data;
  1216. unsigned cnt;
  1217. } vect;
  1218. // outer structure
  1219. typedef struct
  1220. {
  1221. unsigned cnt;
  1222. vect* vectArray;
  1223. } vectArray;
  1224. float vd0[] = { 0, 1, 2, 3, 4};
  1225. float vd1[] = { 10, 11, 12 };
  1226. unsigned vn = 2;
  1227. vect v[] = { {vd0,5}, {vd1,3} };
  1228. vectArray va = { vn, v };
  1229. if(( rc = cmSrAlloc( &h, ctx )) != kOkSrRC )
  1230. goto errLabel;
  1231. // repeat format processes to test cmSrFormatReset()
  1232. for(k=0; k<2; ++k)
  1233. {
  1234. cmSrFmtReset(h);
  1235. // Define the format of nested structures first
  1236. //
  1237. // Long Form:
  1238. // cmSrFmtDefineStruct(h,kVectSrId);
  1239. // cmSrFmtFloatV(h );
  1240. // cmSrFmtUInt(h );
  1241. //
  1242. // Short Form:
  1243. cmSrDefFmt(h, kVectSrId, kFloatVSrId, kUIntSrId, kInvalidSrId );
  1244. // Define the format of the outer structure last
  1245. //
  1246. // Long Form:
  1247. // cmSrFmtDefineStruct(h,kVectArrSrId);
  1248. // cmSrFmtUInt(h );
  1249. // cmSrFmtStructV(h, kVectSrId );
  1250. //
  1251. // Short Form:
  1252. cmSrDefFmt(h, kVectArrSrId, kUIntSrId, kVectSrId | kArraySrFl, kInvalidSrId );
  1253. cmSrFmtPrint(h);
  1254. // repeat write process to test cmSrWrReset()
  1255. for(j=0; j<2; ++j)
  1256. {
  1257. cmSrWrReset(h);
  1258. cmSrWrStructBegin( h, kVectArrSrId );
  1259. cmSrWrUInt( h, vn );
  1260. cmSrWrStruct( h, kVectSrId, vn );
  1261. for(i=0; i<vn; ++i)
  1262. {
  1263. cmSrWrStructBegin( h, kVectSrId );
  1264. cmSrWrFloatV( h, va.vectArray[i].data, va.vectArray[i].cnt );
  1265. cmSrWrUInt( h, va.vectArray[i].cnt );
  1266. cmSrWrStructEnd(h);
  1267. }
  1268. cmSrWrStructEnd(h);
  1269. bufByteCnt = 0;
  1270. bufPtr = cmSrWrAllocBuf( h, &bufByteCnt );
  1271. }
  1272. // The serialized buffer has the following format:
  1273. // Words Bytes
  1274. // ----- ----- -----------------------------------------
  1275. // 1 4 [ uint (2) ]
  1276. // 2 8 [ id (11) ][ cnt (2) ]
  1277. // 6 24 [ cnt (5) ][0.0][1.0][2.0][3.0][4.0]
  1278. // 1 4 [ uint (5) ]
  1279. // 4 16 [ cnt (3) ][10.][11.][12.]
  1280. // 1 4 [ uint (3) ]
  1281. // ----- ----
  1282. // 14 60
  1283. //
  1284. unsigned n0,n1,n2,n3;
  1285. const float* fArr;
  1286. cmSrRdProcessBuffer(h, (void*)bufPtr, bufByteCnt );
  1287. cmSrRdSetup( h, bufPtr, bufByteCnt );
  1288. cmSrRdStructBegin( h, kVectArrSrId );
  1289. cmSrReadUInt( h, &n0 );
  1290. cmSrReadStruct( h, kVectSrId, &n1 );
  1291. for(i=0; i<n1; ++i)
  1292. {
  1293. cmSrRdStructBegin( h, kVectSrId );
  1294. cmSrReadFloatCV( h, &fArr, &n2 );
  1295. cmSrReadUInt( h, &n3 );
  1296. cmSrRdStructEnd( h );
  1297. }
  1298. cmSrRdSetup( h, bufPtr, bufByteCnt );
  1299. cmSrRdStructBegin( h, kVectArrSrId );
  1300. n0 = cmSrRdUInt( h );
  1301. n1 = cmSrRdStruct( h, kVectSrId );
  1302. for(i=0; i<n1; ++i)
  1303. {
  1304. cmSrRdStructBegin( h, kVectSrId );
  1305. fArr = cmSrRdFloatV( h, &n2 );
  1306. n3 = cmSrRdUInt( h );
  1307. cmSrRdStructEnd( h );
  1308. for(j=0; j<n2; ++j)
  1309. printf("%f ",fArr[j]);
  1310. printf("\n");
  1311. }
  1312. }
  1313. errLabel:
  1314. cmSrFree(&h);
  1315. return rc;
  1316. }
  1317. //]
  1318. //}