libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. //}