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

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