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.

cmData.c 82KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852
  1. #include "cmGlobal.h"
  2. #include "cmRpt.h"
  3. #include "cmErr.h"
  4. #include "cmCtx.h"
  5. #include "cmMem.h"
  6. #include "cmMallocDebug.h"
  7. #include "cmLinkedHeap.h"
  8. #include "cmData.h"
  9. #include "cmLex.h"
  10. #include "cmText.h"
  11. #include "cmStack.h"
  12. typedef struct
  13. {
  14. cmDataTypeId_t typeId;
  15. unsigned byteWidth;
  16. const cmChar_t* label;
  17. } cmDtTypeInfo_t;
  18. typedef struct
  19. {
  20. cmDataContainerId_t id;
  21. const cmChar_t* label;
  22. } cmDtCntInfo_t;
  23. cmDtTypeInfo_t _cmDtTypeInfoArray[] =
  24. {
  25. { kNullDtId, 0, "null" },
  26. { kUCharDtId, sizeof(unsigned char), "uchar" },
  27. { kCharDtId, sizeof(char), "char" },
  28. { kUShortDtId, sizeof(unsigned short), "ushort" },
  29. { kShortDtId, sizeof(short), "short" },
  30. { kUIntDtId, sizeof(unsigned int), "uint" },
  31. { kIntDtId, sizeof(int), "int" },
  32. { kULongDtId, sizeof(unsigned long), "ulong" },
  33. { kLongDtId, sizeof(long), "long" },
  34. { kFloatDtId, sizeof(float), "float" },
  35. { kDoubleDtId, sizeof(double), "double" },
  36. { kStrDtId, sizeof(char*), "string" },
  37. { kBlobDtId, sizeof(void*), "blob" },
  38. { kInvalidTypeDtId, 0, "<invalid-type>" },
  39. };
  40. cmDtCntInfo_t _cmDtCntInfoArray[] =
  41. {
  42. { kScalarDtId, "scalar" },
  43. { kArrayDtId, "array" },
  44. { kListDtId, "list" },
  45. { kPairDtId, "pair" },
  46. { kRecordDtId, "record"},
  47. { kInvalidCntDtId,"<invalid-container>"}
  48. };
  49. cmData_t cmDataNull = { kInvalidTypeDtId,kInvalidCntDtId,0,NULL,NULL,0 };
  50. cmDtRC_t _cmDtErrMsgV( const cmData_t* d, cmDtRC_t rc, const cmChar_t* fmt, va_list vl )
  51. {
  52. // REPLACE this with a global cmRpt call.
  53. vprintf(fmt,vl);
  54. return rc;
  55. }
  56. cmDtRC_t _cmDtErrMsg( const cmData_t* d, cmDtRC_t rc, const cmChar_t* fmt, ... )
  57. {
  58. va_list vl;
  59. va_start(vl,fmt);
  60. rc = _cmDtErrMsgV(d,rc,fmt,vl);
  61. va_end(vl);
  62. return rc;
  63. }
  64. const cmChar_t* cmDataTypeToLabel( cmDataTypeId_t tid )
  65. {
  66. unsigned i;
  67. for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i)
  68. if( _cmDtTypeInfoArray[i].typeId == tid )
  69. return _cmDtTypeInfoArray[i].label;
  70. return NULL;
  71. }
  72. cmDataTypeId_t cmDataLabelToType( const cmChar_t* typeLabelStr )
  73. {
  74. unsigned i;
  75. for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i)
  76. if( strcmp(_cmDtTypeInfoArray[i].label,typeLabelStr) == 0 )
  77. return _cmDtTypeInfoArray[i].typeId;
  78. return kInvalidTypeDtId;
  79. }
  80. unsigned cmDataByteWidth( cmDataTypeId_t tid )
  81. {
  82. unsigned i;
  83. for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i)
  84. if( _cmDtTypeInfoArray[i].typeId == tid )
  85. return _cmDtTypeInfoArray[i].byteWidth;
  86. return cmInvalidCnt;
  87. }
  88. const cmChar_t* cmDataContainerIdToLabel( cmDataContainerId_t tid )
  89. {
  90. unsigned i;
  91. for(i=0; _cmDtCntInfoArray[i].id!=kInvalidCntDtId; ++i)
  92. if( _cmDtCntInfoArray[i].id == tid )
  93. return _cmDtCntInfoArray[i].label;
  94. return NULL;
  95. }
  96. cmDataContainerId_t cmDataLabelToContainerId( const cmChar_t* contLabelStr )
  97. {
  98. unsigned i;
  99. for(i=0; _cmDtCntInfoArray[i].id!=kInvalidCntDtId; ++i)
  100. if( strcmp(_cmDtCntInfoArray[i].label,contLabelStr) == 0 )
  101. return _cmDtCntInfoArray[i].id;
  102. return kInvalidCntDtId;
  103. }
  104. bool _cmDataIsDataOwner( const cmData_t* d )
  105. { return cmIsFlag(d->flags,kFreeValueDtFl) && (d->cid==kArrayDtId || d->tid==kStrDtId || d->tid==kBlobDtId); }
  106. cmDtRC_t _cmDataFreeData( cmData_t* d )
  107. {
  108. if( _cmDataIsDataOwner(d) )
  109. {
  110. // A object marked with kFreeValueDtFl should never also be 'const.
  111. // (??? is this true ???? )
  112. assert( cmIsNotFlag(d->flags,kConstValueDtFl) );
  113. cmMemPtrFree(&d->u.vp);
  114. }
  115. d->flags = cmClrFlag(d->flags,kFreeValueDtFl | kConstValueDtFl );
  116. d->tid = kNullDtId; // objects without data are always of type 'null'.
  117. d->cnt = 0;
  118. memset(&d->u,0,sizeof(d->u));
  119. return kOkDtRC;
  120. }
  121. void _cmDataFree( cmData_t* p )
  122. {
  123. if( p == NULL )
  124. return;
  125. if( cmDataIsStruct(p) )
  126. {
  127. cmData_t* cp = p->u.child;
  128. for(; cp!=NULL; cp=cp->sibling)
  129. _cmDataFree(cp);
  130. }
  131. _cmDataFreeData(p);
  132. if( cmIsFlag(p->flags,kFreeObjDtFl) )
  133. cmMemFree(p);
  134. }
  135. // Dynamically allocate a new data object.
  136. cmData_t* _cmDataNew(cmData_t* parent, cmDataContainerId_t cid, cmDataTypeId_t tid)
  137. {
  138. cmData_t* d = cmMemAllocZ(cmData_t,1);
  139. d->tid = tid; // objects without data are of type 'null'.
  140. d->cid = cid;
  141. d->flags = kFreeObjDtFl;
  142. d->parent = parent;
  143. d->cnt = 0;
  144. if( parent != NULL )
  145. cmDataAppendChild(parent,d);
  146. return d;
  147. }
  148. bool cmDataIsConstObj( const cmData_t* d )
  149. { return cmIsFlag(d->flags,kConstObjDtFl); }
  150. void cmDataEnableConstObj( cmData_t* d, bool enaFl )
  151. { d->flags = cmEnaFlag(d->flags,kConstObjDtFl,enaFl); }
  152. bool cmDataIsConstValue( const cmData_t* d )
  153. { return cmIsFlag(d->flags,kConstValueDtFl); }
  154. void cmDataEnableConstValue( cmData_t* d, bool enaFl )
  155. { d->flags = cmEnaFlag(d->flags,kConstValueDtFl,enaFl); }
  156. bool cmDataIsFreeValue( const cmData_t* d )
  157. { return cmIsFlag(d->flags,kFreeValueDtFl); }
  158. void cmDataEnableFreeValue( cmData_t* d, bool enaFl )
  159. { d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,enaFl); }
  160. bool cmDataIsLeaf( const cmData_t* d)
  161. { return d->cid == kScalarDtId || d->cid == kArrayDtId; }
  162. bool cmDataIsStruct( const cmData_t* d )
  163. { return !cmDataIsLeaf(d); }
  164. cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref )
  165. {
  166. cmDtRC_t rc;
  167. if( ref != NULL )
  168. *ref = NULL;
  169. // create a scalar null object
  170. cmData_t* d = _cmDataNew(parent,kScalarDtId,kNullDtId);
  171. if( tid!=kStrDtId && tid!=kBlobDtId )
  172. {
  173. // When used with scalars kFreeValueDtFl and kNoCopyDtFl only
  174. // has meaning for strings and blobs - so clear these flags for other types.
  175. flags = cmClrFlag(flags,kFreeValueDtFl | kNoCopyDtFl);
  176. // if this is not a blob or string then the byteCnt is reset
  177. byteCnt = cmDataByteWidth(tid);
  178. }
  179. // assign the value
  180. if((rc = cmDataSetScalarValue(d,tid,vp,byteCnt,flags)) != kOkDtRC )
  181. return rc;
  182. // set the const flags for the new object
  183. d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl));
  184. if( ref != NULL )
  185. *ref = d;
  186. return rc;
  187. }
  188. cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref )
  189. { *ref = _cmDataNew(parent, kScalarDtId, kNullDtId); return kOkDtRC; }
  190. cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref )
  191. { return cmDataNewScalar(parent,kCharDtId,flags,&v,0,ref); }
  192. cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref )
  193. { return cmDataNewScalar(parent,kUCharDtId,flags,&v,0,ref); }
  194. cmDtRC_t cmDataNewShort( cmData_t* parent, unsigned flags, short v, cmData_t** ref )
  195. { return cmDataNewScalar(parent,kShortDtId,flags,&v,0,ref); }
  196. cmDtRC_t cmDataNewUShort( cmData_t* parent, unsigned flags, unsigned short v, cmData_t** ref )
  197. { return cmDataNewScalar(parent,kUShortDtId,flags,&v,0,ref); }
  198. cmDtRC_t cmDataNewInt( cmData_t* parent, unsigned flags, int v, cmData_t** ref )
  199. { return cmDataNewScalar(parent,kIntDtId,flags,&v,0,ref); }
  200. cmDtRC_t cmDataNewUInt( cmData_t* parent, unsigned flags, unsigned int v, cmData_t** ref )
  201. { return cmDataNewScalar(parent,kUIntDtId,flags,&v,0,ref); }
  202. cmDtRC_t cmDataNewLong( cmData_t* parent, unsigned flags, long v, cmData_t** ref )
  203. { return cmDataNewScalar(parent,kLongDtId,flags,&v,0,ref); }
  204. cmDtRC_t cmDataNewULong( cmData_t* parent, unsigned flags, unsigned long v, cmData_t** ref )
  205. { return cmDataNewScalar(parent,kULongDtId,flags,&v,0,ref); }
  206. cmDtRC_t cmDataNewFloat( cmData_t* parent, unsigned flags, float v, cmData_t** ref )
  207. { return cmDataNewScalar(parent,kFloatDtId,flags,&v,0,ref); }
  208. cmDtRC_t cmDataNewDouble( cmData_t* parent, unsigned flags, double v, cmData_t** ref )
  209. { return cmDataNewScalar(parent,kDoubleDtId,flags,&v,0,ref); }
  210. cmDtRC_t cmDataNewStr( cmData_t* parent, unsigned flags, cmChar_t* v, cmData_t** ref )
  211. { return cmDataNewScalar(parent,kStrDtId,flags,v,strlen(v)+1,ref); }
  212. cmDtRC_t cmDataNewConstStr( cmData_t* parent, unsigned flags, const cmChar_t* v, cmData_t** ref )
  213. { return cmDataNewScalar(parent,kStrDtId,flags | kConstValueDtFl, (void*)v,strlen(v)+1,ref); }
  214. cmDtRC_t cmDataNewStrN( cmData_t* parent, unsigned flags, cmChar_t* v, unsigned charCnt, cmData_t** ref )
  215. { return cmDataNewScalar(parent,kStrDtId,flags,v,charCnt+1,ref); }
  216. cmDtRC_t cmDataNewConstStrN( cmData_t* parent, unsigned flags, const cmChar_t* v, unsigned charCnt, cmData_t** ref )
  217. { return cmDataNewScalar(parent,kStrDtId,flags | kConstValueDtFl, (void*)v,charCnt+1,ref); }
  218. cmDtRC_t cmDataNewBlob( cmData_t* parent, unsigned flags, void* v, unsigned byteCnt, cmData_t** ref )
  219. { return cmDataNewScalar(parent,kBlobDtId,flags,v,byteCnt,ref); }
  220. cmDtRC_t cmDataNewConstBlob( cmData_t* parent, unsigned flags, const void* v, unsigned byteCnt, cmData_t** ref )
  221. { return cmDataNewScalar(parent,kBlobDtId,flags | kConstValueDtFl, (void*)v,byteCnt,ref); }
  222. cmDtRC_t cmDataSetScalarValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned byteCnt, unsigned flags )
  223. {
  224. cmDtRC_t rc;
  225. // if the type of the object is changing
  226. if( d->tid != tid || d->cid != kScalarDtId )
  227. {
  228. // verify that it is legal to change the type of the object
  229. if( cmIsFlag(d->flags,kConstObjDtFl) )
  230. return _cmDtErrMsg(d,kConstErrDtRC,"Const object violation.");
  231. // convert this to a scalar null object.
  232. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  233. return rc;
  234. }
  235. // verify that it is legal to change the value of this object
  236. if( cmIsFlag(d->flags,kConstValueDtFl) )
  237. return _cmDtErrMsg(d,kConstErrDtRC,"Const value violation.");
  238. switch( tid )
  239. {
  240. case kInvalidTypeDtId:
  241. return _cmDtErrMsg(d,kAssertErrDtRC,"Invalid data type.");
  242. case kNullDtId: // 'd' is already NULL.
  243. break;
  244. case kUCharDtId: d->u.uc = *(unsigned char*)vp; break;
  245. case kCharDtId: d->u.c = *(char*)vp; break;
  246. case kUShortDtId: d->u.us = *(unsigned short*)vp; break;
  247. case kShortDtId: d->u.s = *(short*)vp; break;
  248. case kUIntDtId: d->u.ui = *(unsigned int*)vp; break;
  249. case kIntDtId: d->u.i = *(int*)vp; break;
  250. case kULongDtId: d->u.ul = *(unsigned long*)vp; break;
  251. case kLongDtId: d->u.l = *(long*)vp; break;
  252. case kFloatDtId: d->u.f = *(float*)vp; break;
  253. case kDoubleDtId: d->u.d = *(double*)vp; break;
  254. case kStrDtId:
  255. case kBlobDtId:
  256. {
  257. cmChar_t* blankStr = "";
  258. // strings must have a byteCnt of at least one
  259. assert( tid==kBlobDtId || (tid==kStrDtId && byteCnt>0) );
  260. // if a NULL source string is encountered then make it a 0 length string
  261. if( d->tid==kStrDtId && vp==NULL )
  262. vp = blankStr;
  263. // if an empty blob was passed in then be sure it's src ptr is NULL and byteCnt==0
  264. if( d->tid==kBlobDtId && (vp==NULL || byteCnt==0) )
  265. {
  266. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  267. return rc;
  268. byteCnt = 0;
  269. d->u.z = NULL;
  270. break;
  271. }
  272. // if the incoming string/blob should be internally duplicated
  273. if( cmIsNotFlag(flags,kNoCopyDtFl) )
  274. {
  275. // allocate internal space to store the incoming data
  276. if( (d->tid==kBlobDtId || d->tid == kStrDtId) && cmIsFlag(d->flags,kFreeValueDtFl) )
  277. d->u.z = cmMemResize(char,d->u.z,byteCnt);
  278. else
  279. d->u.z = cmMemAlloc(char,byteCnt);
  280. // store the source string/blob into the internal memory buffer
  281. memcpy(d->u.z,vp,byteCnt);
  282. // by default the system now takes responsibility for freeing this buffer
  283. d->flags |= kFreeValueDtFl;
  284. }
  285. else // the incoming string/blob pointer is simply being assigned w/o duplication
  286. {
  287. // free the objects previous value ...
  288. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  289. return rc;
  290. // and assign the new value (without reallocating the string)
  291. d->u.z = vp;
  292. d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,cmIsFlag(flags,kFreeValueDtFl));
  293. d->flags |= kNoCopyDtFl;
  294. }
  295. }
  296. break;
  297. default:
  298. break;
  299. }
  300. // we can't set this above because the string type relies
  301. // on knowing the previous type of the object
  302. d->cid = kScalarDtId;
  303. d->tid = tid;
  304. d->cnt = byteCnt;
  305. return rc;
  306. }
  307. cmDtRC_t cmDataSetNull( cmData_t* d )
  308. { return cmDataSetScalarValue(d, kNullDtId, NULL, 0, kNoFlagsDtFl ); }
  309. cmDtRC_t cmDataSetChar( cmData_t* d, char v )
  310. { return cmDataSetScalarValue(d, kCharDtId, &v, 0, kNoFlagsDtFl ); }
  311. cmDtRC_t cmDataSetUChar( cmData_t* d, unsigned char v )
  312. { return cmDataSetScalarValue(d, kUCharDtId, &v, 0, kNoFlagsDtFl ); }
  313. cmDtRC_t cmDataSetShort( cmData_t* d, short v )
  314. { return cmDataSetScalarValue(d, kShortDtId, &v, 0, kNoFlagsDtFl ); }
  315. cmDtRC_t cmDataSetUShort( cmData_t* d, unsigned short v )
  316. { return cmDataSetScalarValue(d, kUShortDtId, &v, 0, kNoFlagsDtFl ); }
  317. cmDtRC_t cmDataSetInt( cmData_t* d, int v )
  318. { return cmDataSetScalarValue(d, kIntDtId, &v, 0, kNoFlagsDtFl ); }
  319. cmDtRC_t cmDataSetUInt( cmData_t* d, unsigned int v )
  320. { return cmDataSetScalarValue(d, kUIntDtId, &v, 0, kNoFlagsDtFl ); }
  321. cmDtRC_t cmDataSetLong( cmData_t* d, long v )
  322. { return cmDataSetScalarValue(d, kLongDtId, &v, 0, kNoFlagsDtFl ); }
  323. cmDtRC_t cmDataSetULong( cmData_t* d, unsigned long v )
  324. { return cmDataSetScalarValue(d, kULongDtId, &v, 0, kNoFlagsDtFl ); }
  325. cmDtRC_t cmDataSetFloat( cmData_t* d, float v )
  326. { return cmDataSetScalarValue(d, kFloatDtId, &v, 0, kNoFlagsDtFl ); }
  327. cmDtRC_t cmDataSetDouble( cmData_t* d, double v )
  328. { return cmDataSetScalarValue(d, kDoubleDtId, &v, 0, kNoFlagsDtFl ); }
  329. cmDtRC_t cmDataSetStr( cmData_t* d, unsigned flags, cmChar_t* v )
  330. { return cmDataSetScalarValue(d, kStrDtId, v, v==NULL ? 1 : strlen(v)+1, flags ); }
  331. cmDtRC_t cmDataSetConstStr( cmData_t* d, unsigned flags, const cmChar_t* v )
  332. { return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : strlen(v)+1, flags |= kConstValueDtFl ); }
  333. cmDtRC_t cmDataSetStrN( cmData_t* d, unsigned flags, cmChar_t* v, unsigned charCnt )
  334. { return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : charCnt+1, flags); }
  335. cmDtRC_t cmDataSetConstStrN( cmData_t* d, unsigned flags, const cmChar_t* v, unsigned charCnt )
  336. { return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : charCnt+1, flags |= kConstValueDtFl); }
  337. cmDtRC_t cmDataSetBlob( cmData_t* d, unsigned flags, void* v, unsigned byteCnt )
  338. { return cmDataSetScalarValue(d, kBlobDtId, v, byteCnt, flags); }
  339. cmDtRC_t cmDataSetConstBlob( cmData_t* d, unsigned flags, const void* v, unsigned byteCnt )
  340. { return cmDataSetScalarValue(d, kBlobDtId, (void*)v, byteCnt, flags |= kConstValueDtFl); }
  341. cmDtRC_t cmDataChar( const cmData_t* d, char* v )
  342. {
  343. if( d->tid != kCharDtId )
  344. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:char but encountered type:%s.",cmDataTypeToLabel(d->tid));
  345. *v = d->u.c;
  346. return kOkDtRC;
  347. }
  348. cmDtRC_t cmDataUChar( const cmData_t* d, unsigned char* v )
  349. {
  350. if( d->tid != kUCharDtId )
  351. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:uchar but encountered type:%s.",cmDataTypeToLabel(d->tid));
  352. *v = d->u.uc;
  353. return kOkDtRC;
  354. }
  355. cmDtRC_t cmDataShort( const cmData_t* d, short* v )
  356. {
  357. if( d->tid != kShortDtId )
  358. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:short but encountered type:%s.",cmDataTypeToLabel(d->tid));
  359. *v = d->u.s;
  360. return kOkDtRC;
  361. }
  362. cmDtRC_t cmDataUShort( const cmData_t* d, unsigned short* v )
  363. {
  364. if( d->tid != kUShortDtId )
  365. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:ushort but encountered type:%s.",cmDataTypeToLabel(d->tid));
  366. *v = d->u.us;
  367. return kOkDtRC;
  368. }
  369. cmDtRC_t cmDataInt( const cmData_t* d, int* v )
  370. {
  371. if( d->tid != kIntDtId )
  372. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:int but encountered type:%s.",cmDataTypeToLabel(d->tid));
  373. *v = d->u.i;
  374. return kOkDtRC;
  375. }
  376. cmDtRC_t cmDataUInt( const cmData_t* d, unsigned int* v )
  377. {
  378. if( d->tid != kUIntDtId )
  379. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:uint but encountered type:%s.",cmDataTypeToLabel(d->tid));
  380. *v = d->u.ui;
  381. return kOkDtRC;
  382. }
  383. cmDtRC_t cmDataLong( const cmData_t* d, long* v )
  384. {
  385. if( d->tid != kLongDtId )
  386. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:long but encountered type:%s.",cmDataTypeToLabel(d->tid));
  387. *v = d->u.l;
  388. return kOkDtRC;
  389. }
  390. cmDtRC_t cmDataULong( const cmData_t* d, unsigned long* v )
  391. {
  392. if( d->tid != kULongDtId )
  393. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:ulong but encountered type:%s.",cmDataTypeToLabel(d->tid));
  394. *v = d->u.ul;
  395. return kOkDtRC;
  396. }
  397. cmDtRC_t cmDataFloat( const cmData_t* d, float* v )
  398. {
  399. if( d->tid != kFloatDtId )
  400. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:float but encountered type:%s.",cmDataTypeToLabel(d->tid));
  401. *v = d->u.f;
  402. return kOkDtRC;
  403. }
  404. cmDtRC_t cmDataDouble( const cmData_t* d, double* v )
  405. {
  406. if( d->tid != kDoubleDtId )
  407. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:double but encountered type:%s.",cmDataTypeToLabel(d->tid));
  408. *v = d->u.d;
  409. return kOkDtRC;
  410. }
  411. cmDtRC_t cmDataStr( const cmData_t* d, cmChar_t** v )
  412. {
  413. if( d->tid != kStrDtId )
  414. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  415. if( cmIsFlag(d->flags,kConstValueDtFl) )
  416. return _cmDtErrMsg(d,kConstErrDtRC,"A const string cannot return as a non-const string.");
  417. *v = d->u.z;
  418. return kOkDtRC;
  419. }
  420. cmDtRC_t cmDataConstStr( const cmData_t* d, const cmChar_t** v )
  421. {
  422. if( d->tid != kStrDtId )
  423. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  424. *v = d->u.z;
  425. return kOkDtRC;
  426. }
  427. cmDtRC_t cmDataBlob( const cmData_t* d, cmChar_t** v, unsigned* byteCntRef )
  428. {
  429. if( v != NULL )
  430. *v = NULL;
  431. if( byteCntRef != NULL )
  432. *byteCntRef = 0;
  433. if( d->tid != kBlobDtId )
  434. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  435. if( v != NULL )
  436. *v = d->u.z;
  437. if( byteCntRef != NULL )
  438. *byteCntRef = d->cnt;
  439. return kOkDtRC;
  440. }
  441. cmDtRC_t cmDataConstBlob( const cmData_t* d, const cmChar_t** v, unsigned* byteCntRef )
  442. {
  443. if( v != NULL )
  444. *v = NULL;
  445. if( byteCntRef != NULL )
  446. *byteCntRef = 0;
  447. if( d->tid != kBlobDtId )
  448. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  449. if( v != NULL )
  450. *v = d->u.z;
  451. if( byteCntRef != NULL )
  452. *byteCntRef = d->cnt;
  453. return kOkDtRC;
  454. }
  455. cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* vp )
  456. {
  457. if( p->cid != kScalarDtId )
  458. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  459. switch( p->tid )
  460. {
  461. case kUCharDtId: *vp = p->u.uc; break;
  462. case kCharDtId: *vp = (unsigned char)p->u.c; break;
  463. case kUShortDtId: *vp = (unsigned char)p->u.us; break;
  464. case kShortDtId: *vp = (unsigned char)p->u.s; break;
  465. case kUIntDtId: *vp = (unsigned char)p->u.ui; break;
  466. case kIntDtId: *vp = (unsigned char)p->u.i; break;
  467. case kULongDtId: *vp = (unsigned char)p->u.ul; break;
  468. case kLongDtId: *vp = (unsigned char)p->u.l; break;
  469. case kFloatDtId: *vp = (unsigned char)p->u.f; break;
  470. case kDoubleDtId: *vp = (unsigned char)p->u.d; break;
  471. default:
  472. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'uchar'.",cmDataTypeToLabel(p->tid));
  473. }
  474. return kOkDtRC;
  475. }
  476. cmDtRC_t cmDataGetChar( const cmData_t* p, char* vp )
  477. {
  478. if( p->cid != kScalarDtId )
  479. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  480. switch( p->tid )
  481. {
  482. case kUCharDtId: *vp = (char)p->u.uc; break;
  483. case kCharDtId: *vp = p->u.c; break;
  484. case kUShortDtId: *vp = (char)p->u.us; break;
  485. case kShortDtId: *vp = (char)p->u.s; break;
  486. case kUIntDtId: *vp = (char)p->u.ui; break;
  487. case kIntDtId: *vp = (char)p->u.i; break;
  488. case kULongDtId: *vp = (char)p->u.ul; break;
  489. case kLongDtId: *vp = (char)p->u.l; break;
  490. case kFloatDtId: *vp = (char)p->u.f; break;
  491. case kDoubleDtId: *vp = (char)p->u.d; break;
  492. default:
  493. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'char'.",cmDataTypeToLabel(p->tid));
  494. }
  495. return kOkDtRC;
  496. }
  497. cmDtRC_t cmDataGetShort( const cmData_t* p, short* vp )
  498. {
  499. if( p->cid != kScalarDtId )
  500. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  501. switch( p->tid )
  502. {
  503. case kUCharDtId: *vp = (short)p->u.uc; break;
  504. case kCharDtId: *vp = (short)p->u.c; break;
  505. case kUShortDtId: *vp = (short)p->u.us; break;
  506. case kShortDtId: *vp = p->u.s; break;
  507. case kUIntDtId: *vp = (short)p->u.ui; break;
  508. case kIntDtId: *vp = (short)p->u.i; break;
  509. case kULongDtId: *vp = (short)p->u.ul; break;
  510. case kLongDtId: *vp = (short)p->u.l; break;
  511. case kFloatDtId: *vp = (short)p->u.f; break;
  512. case kDoubleDtId: *vp = (short)p->u.d; break;
  513. default:
  514. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'short'.",cmDataTypeToLabel(p->tid));
  515. }
  516. return kOkDtRC;
  517. }
  518. cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* vp )
  519. {
  520. if( p->cid != kScalarDtId )
  521. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  522. switch( p->tid )
  523. {
  524. case kUCharDtId: *vp = (unsigned short)p->u.uc; break;
  525. case kCharDtId: *vp = (unsigned short)p->u.c; break;
  526. case kUShortDtId: *vp = p->u.us; break;
  527. case kShortDtId: *vp = (unsigned short)p->u.s; break;
  528. case kUIntDtId: *vp = (unsigned short)p->u.ui; break;
  529. case kIntDtId: *vp = (unsigned short)p->u.i; break;
  530. case kULongDtId: *vp = (unsigned short)p->u.ul; break;
  531. case kLongDtId: *vp = (unsigned short)p->u.l; break;
  532. case kFloatDtId: *vp = (unsigned short)p->u.f; break;
  533. case kDoubleDtId: *vp = (unsigned short)p->u.d; break;
  534. default:
  535. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'ushort'.",cmDataTypeToLabel(p->tid));
  536. }
  537. return kOkDtRC;
  538. }
  539. cmDtRC_t cmDataGetInt( const cmData_t* p, int* vp )
  540. {
  541. if( p->cid != kScalarDtId )
  542. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  543. switch( p->tid )
  544. {
  545. case kUCharDtId: *vp = (int)p->u.uc; break;
  546. case kCharDtId: *vp = (int)p->u.c; break;
  547. case kUShortDtId: *vp = (int)p->u.us; break;
  548. case kShortDtId: *vp = (int)p->u.s; break;
  549. case kUIntDtId: *vp = (int)p->u.ui; break;
  550. case kIntDtId: *vp = p->u.i; break;
  551. case kULongDtId: *vp = (int)p->u.ul; break;
  552. case kLongDtId: *vp = (int)p->u.l; break;
  553. case kFloatDtId: *vp = (int)p->u.f; break;
  554. case kDoubleDtId: *vp = (int)p->u.d; break;
  555. default:
  556. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'int'.",cmDataTypeToLabel(p->tid));
  557. }
  558. return kOkDtRC;
  559. }
  560. cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* vp )
  561. {
  562. if( p->cid != kScalarDtId )
  563. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  564. switch( p->tid )
  565. {
  566. case kUCharDtId: *vp = (unsigned int)p->u.uc; break;
  567. case kCharDtId: *vp = (unsigned int)p->u.c; break;
  568. case kUShortDtId: *vp = (unsigned int)p->u.us; break;
  569. case kShortDtId: *vp = (unsigned int)p->u.s; break;
  570. case kUIntDtId: *vp = p->u.ui; break;
  571. case kIntDtId: *vp = (unsigned int)p->u.i; break;
  572. case kULongDtId: *vp = (unsigned int)p->u.ul; break;
  573. case kLongDtId: *vp = (unsigned int)p->u.l; break;
  574. case kFloatDtId: *vp = (unsigned int)p->u.f; break;
  575. case kDoubleDtId: *vp = (unsigned int)p->u.d; break;
  576. default:
  577. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'uint'.",cmDataTypeToLabel(p->tid));
  578. }
  579. return kOkDtRC;
  580. }
  581. cmDtRC_t cmDataGetLong( const cmData_t* p, long* vp )
  582. {
  583. if( p->cid != kScalarDtId )
  584. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  585. switch( p->tid )
  586. {
  587. case kUCharDtId: *vp = (long)p->u.uc; break;
  588. case kCharDtId: *vp = (long)p->u.c; break;
  589. case kUShortDtId: *vp = (long)p->u.us; break;
  590. case kShortDtId: *vp = (long)p->u.s; break;
  591. case kUIntDtId: *vp = (long)p->u.ui; break;
  592. case kIntDtId: *vp = (long)p->u.i; break;
  593. case kULongDtId: *vp = (long)p->u.ul; break;
  594. case kLongDtId: *vp = p->u.l; break;
  595. case kFloatDtId: *vp = (long)p->u.f; break;
  596. case kDoubleDtId: *vp = (long)p->u.d; break;
  597. default:
  598. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'long'.",cmDataTypeToLabel(p->tid));
  599. }
  600. return kOkDtRC;
  601. }
  602. cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* vp )
  603. {
  604. if( p->cid != kScalarDtId )
  605. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  606. switch( p->tid )
  607. {
  608. case kUCharDtId: *vp = (unsigned long)p->u.uc; break;
  609. case kCharDtId: *vp = (unsigned long)p->u.c; break;
  610. case kUShortDtId: *vp = (unsigned long)p->u.us; break;
  611. case kShortDtId: *vp = (unsigned long)p->u.s; break;
  612. case kUIntDtId: *vp = (unsigned long)p->u.ui; break;
  613. case kIntDtId: *vp = (unsigned long)p->u.i; break;
  614. case kULongDtId: *vp = p->u.ul; break;
  615. case kLongDtId: *vp = (unsigned long)p->u.l; break;
  616. case kFloatDtId: *vp = (unsigned long)p->u.f; break;
  617. case kDoubleDtId: *vp = (unsigned long)p->u.d; break;
  618. default:
  619. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'ulong'.",cmDataTypeToLabel(p->tid));
  620. }
  621. return kOkDtRC;
  622. }
  623. cmDtRC_t cmDataGetFloat( const cmData_t* p, float* vp )
  624. {
  625. if( p->cid != kScalarDtId )
  626. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  627. switch( p->tid )
  628. {
  629. case kUCharDtId: *vp = (float)p->u.uc; break;
  630. case kCharDtId: *vp = (float)p->u.c; break;
  631. case kUShortDtId: *vp = (float)p->u.us; break;
  632. case kShortDtId: *vp = (float)p->u.s; break;
  633. case kUIntDtId: *vp = (float)p->u.ui; break;
  634. case kIntDtId: *vp = (float)p->u.i; break;
  635. case kULongDtId: *vp = (float)p->u.ul; break;
  636. case kLongDtId: *vp = (float)p->u.l; break;
  637. case kFloatDtId: *vp = p->u.f; break;
  638. case kDoubleDtId: *vp = (float)p->u.d; break;
  639. default:
  640. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'float'.",cmDataTypeToLabel(p->tid));
  641. }
  642. return kOkDtRC;
  643. }
  644. cmDtRC_t cmDataGetDouble( const cmData_t* p, double* vp )
  645. {
  646. if( p->cid != kScalarDtId )
  647. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  648. switch( p->tid )
  649. {
  650. case kUCharDtId: *vp = (double)p->u.uc; break;
  651. case kCharDtId: *vp = (double)p->u.c; break;
  652. case kUShortDtId: *vp = (double)p->u.us; break;
  653. case kShortDtId: *vp = (double)p->u.s; break;
  654. case kUIntDtId: *vp = (double)p->u.ui; break;
  655. case kIntDtId: *vp = (double)p->u.i; break;
  656. case kULongDtId: *vp = (double)p->u.ul; break;
  657. case kLongDtId: *vp = (double)p->u.l; break;
  658. case kFloatDtId: *vp = (double)p->u.f; break;
  659. case kDoubleDtId: *vp = p->u.d; break;
  660. default:
  661. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'double'.",cmDataTypeToLabel(p->tid));
  662. }
  663. return kOkDtRC;
  664. }
  665. cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref )
  666. {
  667. cmDtRC_t rc;
  668. if( ref != NULL )
  669. *ref = NULL;
  670. // create a new 'null' object
  671. cmData_t* d = _cmDataNew(parent, kScalarDtId, kNullDtId );
  672. // assign the value
  673. if((rc = cmDataSetArrayValue(d,tid,vp,eleCnt,flags)) != kOkDtRC )
  674. return rc;
  675. // set the flags for the new object
  676. d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl | kNoCopyDtFl));
  677. if( ref != NULL )
  678. *ref = d;
  679. return rc;
  680. }
  681. cmDtRC_t cmDataNewCharArray( cmData_t* parent, char* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  682. { return cmDataNewArray(parent, kCharDtId, v, eleCnt, flags, ref ); }
  683. cmDtRC_t cmDataNewUCharArray( cmData_t* parent, unsigned char* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  684. { return cmDataNewArray(parent, kUCharDtId, v, eleCnt, flags, ref ); }
  685. cmDtRC_t cmDataNewShortArray( cmData_t* parent, short* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  686. { return cmDataNewArray(parent, kShortDtId, v, eleCnt, flags, ref ); }
  687. cmDtRC_t cmDataNewUShortArray( cmData_t* parent, unsigned short* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  688. { return cmDataNewArray(parent, kUShortDtId, v, eleCnt, flags, ref ); }
  689. cmDtRC_t cmDataNewIntArray( cmData_t* parent, int* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  690. { return cmDataNewArray(parent, kIntDtId, v, eleCnt, flags, ref ); }
  691. cmDtRC_t cmDataNewUIntArray( cmData_t* parent, unsigned int* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  692. { return cmDataNewArray(parent, kUIntDtId, v, eleCnt, flags, ref ); }
  693. cmDtRC_t cmDataNewLongArray( cmData_t* parent, long* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  694. { return cmDataNewArray(parent, kLongDtId, v, eleCnt, flags, ref ); }
  695. cmDtRC_t cmDataNewULongArray( cmData_t* parent, unsigned long* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  696. { return cmDataNewArray(parent, kULongDtId, v, eleCnt, flags, ref ); }
  697. cmDtRC_t cmDataNewFloatArray( cmData_t* parent, float* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  698. { return cmDataNewArray(parent, kFloatDtId, v, eleCnt, flags, ref ); }
  699. cmDtRC_t cmDataNewDoubleArray( cmData_t* parent, double* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  700. { return cmDataNewArray(parent, kDoubleDtId, v, eleCnt, flags, ref ); }
  701. cmDtRC_t cmDataNewStrArray( cmData_t* parent, cmChar_t** v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  702. { return cmDataNewArray(parent, kStrDtId, v, eleCnt, flags, ref ); }
  703. cmDtRC_t cmDataNewConstStrArray( cmData_t* parent, const cmChar_t** v,unsigned eleCnt, unsigned flags, cmData_t** ref )
  704. { return cmDataNewArray(parent, kStrDtId, (cmChar_t**)v, eleCnt, flags, ref ); }
  705. cmDtRC_t cmDataSetArrayValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags )
  706. {
  707. cmDtRC_t rc = kOkDtRC;
  708. // if the type of the object is changing
  709. if( d->tid != tid || d->cid != kScalarDtId )
  710. {
  711. // verify that it is legal to change the type of the object
  712. if( cmIsFlag(d->flags,kConstObjDtFl) )
  713. return _cmDtErrMsg(d,kConstErrDtRC,"Const object violation.");
  714. // convert this to a scalar null object.
  715. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  716. return rc;
  717. }
  718. // verify that it is legal to change the value of this object
  719. if( cmIsFlag(d->flags,kConstValueDtFl) )
  720. return _cmDtErrMsg(d,kConstErrDtRC,"Const value violation.");
  721. // if the array should be reallocated
  722. if( cmIsNotFlag(flags,kNoCopyDtFl) )
  723. {
  724. unsigned byteCnt = cmDataByteWidth(tid) * eleCnt;
  725. // reallocate a new string
  726. if( d->cid == kArrayDtId && cmIsFlag(d->flags,kFreeValueDtFl) )
  727. d->u.vp = cmMemResize(char,d->u.z,byteCnt);
  728. else
  729. d->u.vp = cmMemAlloc(char,byteCnt);
  730. memcpy(d->u.z,vp,byteCnt);
  731. d->flags |= kFreeValueDtFl;
  732. }
  733. else
  734. {
  735. // free the previous value ...
  736. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  737. return rc;
  738. // and assign the new value (without reallocating the array)
  739. d->u.vp = vp;
  740. d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,cmIsFlag(flags,kFreeValueDtFl));
  741. }
  742. // we can't set this above because the string type relies
  743. // on knowing the previous type of the object
  744. d->cid = kArrayDtId;
  745. d->tid = tid;
  746. d->cnt = eleCnt;
  747. return rc;
  748. }
  749. cmDtRC_t cmDataSetCharArray( cmData_t* d, char* v, unsigned eleCnt, unsigned flags )
  750. { return cmDataSetArrayValue(d, kCharDtId, v, eleCnt, flags ); }
  751. cmDtRC_t cmDataSetUCharArray( cmData_t* d, unsigned char* v, unsigned eleCnt, unsigned flags )
  752. { return cmDataSetArrayValue(d, kUCharDtId, v, eleCnt, flags ); }
  753. cmDtRC_t cmDataSetShortArray( cmData_t* d, short* v, unsigned eleCnt, unsigned flags )
  754. { return cmDataSetArrayValue(d, kShortDtId, v, eleCnt, flags ); }
  755. cmDtRC_t cmDataSetUShortArray( cmData_t* d, unsigned short* v, unsigned eleCnt, unsigned flags )
  756. { return cmDataSetArrayValue(d, kUShortDtId, v, eleCnt, flags ); }
  757. cmDtRC_t cmDataSetIntArray( cmData_t* d, int* v, unsigned eleCnt, unsigned flags )
  758. { return cmDataSetArrayValue(d, kIntDtId, v, eleCnt, flags ); }
  759. cmDtRC_t cmDataSetUIntArray( cmData_t* d, unsigned int* v, unsigned eleCnt, unsigned flags )
  760. { return cmDataSetArrayValue(d, kUIntDtId, v, eleCnt, flags ); }
  761. cmDtRC_t cmDataSetLongArray( cmData_t* d, long* v, unsigned eleCnt, unsigned flags )
  762. { return cmDataSetArrayValue(d, kLongDtId, v, eleCnt, flags ); }
  763. cmDtRC_t cmDataSetULongArray( cmData_t* d, unsigned long* v, unsigned eleCnt, unsigned flags )
  764. { return cmDataSetArrayValue(d, kULongDtId, v, eleCnt, flags ); }
  765. cmDtRC_t cmDataSetFloatArray( cmData_t* d, float* v, unsigned eleCnt, unsigned flags )
  766. { return cmDataSetArrayValue(d, kFloatDtId, v, eleCnt, flags ); }
  767. cmDtRC_t cmDataSetDoubleArray( cmData_t* d, double* v, unsigned eleCnt, unsigned flags )
  768. { return cmDataSetArrayValue(d, kDoubleDtId, v, eleCnt, flags ); }
  769. cmDtRC_t cmDataSetStrArray( cmData_t* d, cmChar_t** v, unsigned eleCnt, unsigned flags )
  770. { return cmDataSetArrayValue(d, kStrDtId, v, eleCnt, flags ); }
  771. cmDtRC_t cmDataSetConstStrArray(cmData_t* d,const cmChar_t** v,unsigned eleCnt, unsigned flags )
  772. { return cmDataSetArrayValue(d, kStrDtId, (cmChar_t**)v, eleCnt, flags ); }
  773. unsigned cmDataArrayEleCount( const cmData_t* d )
  774. { return d->cid==kArrayDtId ? d->cnt : 0; }
  775. cmDtRC_t cmDataCharArray( const cmData_t* d, char** v )
  776. {
  777. if( d->cid != kArrayDtId )
  778. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  779. *v = (char*)d->u.vp;
  780. return kOkDtRC;
  781. }
  782. cmDtRC_t cmDataUCharArray( const cmData_t* d, unsigned char** v )
  783. {
  784. if( d->cid != kArrayDtId )
  785. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  786. *v = (unsigned char*)d->u.vp;
  787. return kOkDtRC;
  788. }
  789. cmDtRC_t cmDataShortArray( const cmData_t* d, short** v )
  790. {
  791. if( d->cid != kArrayDtId )
  792. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  793. *v = (short*)d->u.vp;
  794. return kOkDtRC;
  795. }
  796. cmDtRC_t cmDataUShortArray( const cmData_t* d, unsigned short** v )
  797. {
  798. if( d->cid != kArrayDtId )
  799. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  800. *v = (unsigned short*)d->u.vp;
  801. return kOkDtRC;
  802. }
  803. cmDtRC_t cmDataIntArray( const cmData_t* d, int** v )
  804. {
  805. if( d->cid != kArrayDtId )
  806. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  807. *v = (int*)d->u.vp;
  808. return kOkDtRC;
  809. }
  810. cmDtRC_t cmDataUIntArray( const cmData_t* d, unsigned int** v )
  811. {
  812. if( d->cid != kArrayDtId )
  813. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  814. *v = (unsigned int*)d->u.vp;
  815. return kOkDtRC;
  816. }
  817. cmDtRC_t cmDataLongArray( const cmData_t* d, long** v )
  818. {
  819. if( d->cid != kArrayDtId )
  820. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  821. *v = (long*)d->u.vp;
  822. return kOkDtRC;
  823. }
  824. cmDtRC_t cmDataULongArray( const cmData_t* d, unsigned long** v )
  825. {
  826. if( d->cid != kArrayDtId )
  827. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  828. *v = (unsigned long*)d->u.vp;
  829. return kOkDtRC;
  830. }
  831. cmDtRC_t cmDataFloatArray( const cmData_t* d, float** v )
  832. {
  833. if( d->cid != kArrayDtId )
  834. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  835. *v = (float*)d->u.vp;
  836. return kOkDtRC;
  837. }
  838. cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v )
  839. {
  840. if( d->cid != kArrayDtId )
  841. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  842. *v = (double*)d->u.vp;
  843. return kOkDtRC;
  844. }
  845. cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v )
  846. {
  847. }
  848. cmDtRC_t cmDataConstStrArray( const cmData_t* d, const cmChar_t*** v )
  849. {
  850. }
  851. //----------------------------------------------------------------------------
  852. // Structure related functions
  853. //
  854. void cmDataFree( cmData_t* p )
  855. {
  856. _cmDataFree(p);
  857. }
  858. cmData_t* cmDataUnlink( cmData_t* p )
  859. {
  860. if( p->parent == NULL )
  861. return p;
  862. assert( cmDataIsStruct(p->parent) );
  863. cmData_t* cp = p->u.child;
  864. cmData_t* pp = NULL;
  865. for(; cp!=NULL; cp=cp->sibling)
  866. if( cp == p )
  867. {
  868. if( pp == NULL )
  869. p->parent->u.child = p->sibling;
  870. else
  871. pp->sibling = cp->sibling;
  872. }
  873. return p;
  874. }
  875. void cmDataUnlinkAndFree( cmData_t* p )
  876. {
  877. cmDataUnlink(p);
  878. cmDataFree(p);
  879. }
  880. cmDtRC_t _cmDataDupl( const cmData_t* d, cmData_t* parent, cmData_t** ref )
  881. {
  882. cmDtRC_t rc = kOkDtRC;
  883. cmData_t* rp = NULL;
  884. *ref = NULL;
  885. switch( d->cid )
  886. {
  887. case kScalarDtId:
  888. if( d->tid == kBlobDtId || d->tid == kStrDtId )
  889. rc = cmDataNewScalar(parent, d->tid, d->flags, d->u.vp, d->cnt, &rp );
  890. else
  891. rc = cmDataNewScalar(parent, d->tid, d->flags, d->u.vp, 0, &rp );
  892. break;
  893. case kArrayDtId:
  894. rc = cmDataNewArray(parent, d->tid, d->u.vp, d->cnt, d->flags, &rp );
  895. break;
  896. case kListDtId:
  897. case kPairDtId:
  898. case kRecordDtId:
  899. {
  900. rp = _cmDataNew(parent,d->cid,d->tid);
  901. const cmData_t* cp = d->u.child;
  902. for(; cp!=NULL; cp=cp->sibling)
  903. {
  904. cmData_t* ncp = NULL;
  905. // duplicate the child (ncp) and append it to the parent (rp)
  906. if((rc = _cmDataDupl(cp,rp,&ncp)) == kOkDtRC )
  907. cmDataAppendChild(rp,ncp);
  908. }
  909. }
  910. break;
  911. default:
  912. assert(0);
  913. break;
  914. }
  915. if( rp != NULL )
  916. *ref = rp;
  917. return rc;
  918. }
  919. cmRC_t cmDataDupl( const cmData_t* p, cmData_t** ref )
  920. { return _cmDataDupl(p,NULL,ref); }
  921. cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src )
  922. {
  923. if( dst->parent == NULL )
  924. {
  925. cmDataUnlinkAndFree(dst);
  926. src->parent = NULL;
  927. return src;
  928. }
  929. cmData_t* parent = dst->parent;
  930. cmData_t* cp = parent->u.child;
  931. cmData_t* pp = NULL;
  932. unsigned i = 0;
  933. unsigned n = cmDataChildCount(parent);
  934. // locate dst's right sibling
  935. for(i=0; i<n; ++i,cp=cp->sibling)
  936. {
  937. if( cp == dst )
  938. {
  939. // link in 'src' in place of 'dst'
  940. src->sibling = dst->sibling;
  941. // free dst
  942. cmDataUnlinkAndFree(dst);
  943. // update the sibling link to
  944. if( pp == NULL )
  945. parent->u.child = src;
  946. else
  947. pp->sibling = src;
  948. src->parent = parent;
  949. break;
  950. }
  951. pp = cp;
  952. }
  953. return src;
  954. }
  955. unsigned cmDataChildCount( const cmData_t* p )
  956. {
  957. if( !cmDataIsStruct(p) )
  958. return 0;
  959. unsigned n = 0;
  960. const cmData_t* cp = p->u.child;
  961. for(; cp!=NULL; cp=cp->sibling)
  962. ++n;
  963. return n;
  964. }
  965. cmData_t* cmDataChild( cmData_t* p, unsigned index )
  966. {
  967. if( !cmDataIsStruct(p) )
  968. return NULL;
  969. unsigned n = 0;
  970. cmData_t* cp = p->u.child;
  971. for(; cp!=NULL; cp=cp->sibling)
  972. {
  973. if( n == index )
  974. break;
  975. ++n;
  976. }
  977. return cp;
  978. }
  979. cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p )
  980. {
  981. assert( cmDataIsStruct(p) );
  982. cmDataUnlink(p);
  983. p->u.child = parent->u.child;
  984. parent->u.child = p;
  985. p->parent = parent;
  986. return p;
  987. }
  988. cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p )
  989. {
  990. assert( cmDataIsStruct(parent) );
  991. assert( parent->cid != kRecordDtId || (parent->cid == kRecordDtId && p->cid==kPairDtId));
  992. cmDataUnlink(p);
  993. cmData_t* cp = parent->u.child;
  994. if( cp == NULL )
  995. parent->u.child = p;
  996. else
  997. {
  998. for(; cp!=NULL; cp=cp->sibling)
  999. if( cp->sibling == NULL )
  1000. {
  1001. cp->sibling = p;
  1002. break;
  1003. }
  1004. }
  1005. p->parent = parent;
  1006. p->sibling = NULL;
  1007. return p;
  1008. }
  1009. cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p )
  1010. {
  1011. if( !cmDataIsStruct(parent) )
  1012. return NULL;
  1013. cmDataUnlink(p);
  1014. unsigned n = 0;
  1015. cmData_t* cp = parent->u.child;
  1016. cmData_t* pp = NULL;
  1017. for(; cp!=NULL; cp=cp->sibling)
  1018. {
  1019. if( n == index )
  1020. {
  1021. if( pp == NULL )
  1022. {
  1023. parent->u.child = p;
  1024. p->sibling = NULL;
  1025. }
  1026. else
  1027. {
  1028. p->sibling = pp->sibling;
  1029. pp->sibling = p;
  1030. }
  1031. break;
  1032. }
  1033. ++n;
  1034. }
  1035. p->parent = parent;
  1036. return p;
  1037. }
  1038. //----------------------------------------------------------------------------
  1039. bool _cmDataPairIsValid( const cmData_t* p )
  1040. {
  1041. assert( p->cid == kPairDtId && p->tid==kStructDtId );
  1042. bool fl = p->u.child == NULL || p->u.child->sibling == NULL || p->u.child->sibling->sibling!=NULL;
  1043. return !fl;
  1044. }
  1045. // Get the key/value of a pair
  1046. cmData_t* cmDataPairKey( cmData_t* p )
  1047. {
  1048. assert( _cmDataPairIsValid(p) );
  1049. return p->u.child;
  1050. }
  1051. unsigned cmDataPairKeyId( cmData_t* p )
  1052. {
  1053. assert( _cmDataPairIsValid(p) );
  1054. unsigned id = cmInvalidId;
  1055. cmDataGetUInt(p->u.child,&id);
  1056. return id;
  1057. }
  1058. const cmChar_t* cmDataPairKeyLabel( cmData_t* p )
  1059. {
  1060. assert( _cmDataPairIsValid(p) );
  1061. const cmChar_t* label = NULL;
  1062. cmDataConstStr(p->u.child,&label);
  1063. return label;
  1064. }
  1065. cmData_t* cmDataPairValue( cmData_t* p )
  1066. {
  1067. assert( _cmDataPairIsValid(p) );
  1068. return p->u.child->sibling;
  1069. }
  1070. // Set the key or value of an existing pair node.
  1071. cmData_t* cmDataPairSetValue( cmData_t* p, cmData_t* value )
  1072. {
  1073. assert( _cmDataPairIsValid(p) );
  1074. cmDataReplace( cmDataPairValue(p), value );
  1075. return p;
  1076. }
  1077. cmData_t* cmDataPairSetKey( cmData_t* p, cmData_t* key )
  1078. {
  1079. assert( _cmDataPairIsValid(p) );
  1080. cmDataReplace( cmDataPairValue(p), key );
  1081. return p;
  1082. }
  1083. cmData_t* cmDataPairSetKeyId( cmData_t* p, unsigned id )
  1084. {
  1085. assert( _cmDataPairIsValid(p) );
  1086. cmDataSetUInt(p->u.child,id);
  1087. return p;
  1088. }
  1089. cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label )
  1090. {
  1091. assert( _cmDataPairIsValid(p) );
  1092. cmDataSetConstStr(p->u.child,kNoFlagsDtFl,label);
  1093. return p;
  1094. }
  1095. cmData_t* cmDataMakePair( cmData_t* parent, cmData_t* p, cmData_t* key, cmData_t* value )
  1096. {
  1097. _cmDataFree(p);
  1098. p->tid = kStructDtId;
  1099. p->cid = kPairDtId;
  1100. p->parent = parent;
  1101. p->flags = 0;
  1102. p->u.child = NULL;
  1103. cmDataAppendChild(p,key);
  1104. cmDataAppendChild(p,value);
  1105. return p;
  1106. }
  1107. // Dynamically allocate a pair node
  1108. cmData_t* cmDataAllocPair( cmData_t* parent, const cmData_t* key, const cmData_t* value )
  1109. {
  1110. cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId);
  1111. cmData_t* kp = NULL;
  1112. cmData_t* vp = NULL;
  1113. // BUG BUG BUG - must check return value of cmDataDupl()
  1114. cmDataDupl(key,&kp);
  1115. cmDataDupl(value,&vp);
  1116. cmDataPrependChild(p,vp);
  1117. cmDataPrependChild(p,kp);
  1118. return p;
  1119. }
  1120. cmData_t* cmDataAllocPairId(cmData_t* parent, unsigned keyId, cmData_t* value )
  1121. {
  1122. cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId);
  1123. cmDataNewUInt(p,kNoFlagsDtFl,keyId,NULL);
  1124. cmDataAppendChild(p,value);
  1125. return p;
  1126. }
  1127. cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_t* value )
  1128. {
  1129. cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId);
  1130. // BUG BUG BUG - should check return value
  1131. cmDataNewConstStr(p,kNoFlagsDtFl,label,NULL);
  1132. cmDataAppendChild(p,value);
  1133. return p;
  1134. }
  1135. cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value)
  1136. {
  1137. cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId);
  1138. // BUG BUG BUG - should check return value
  1139. cmDataNewConstStrN(p,kNoFlagsDtFl,label,charCnt,NULL);
  1140. cmDataAppendChild(p,value);
  1141. return p;
  1142. }
  1143. //----------------------------------------------------------------------------
  1144. unsigned cmDataListCount(const cmData_t* p )
  1145. { return cmDataChildCount(p); }
  1146. cmData_t* cmDataListEle( cmData_t* p, unsigned index )
  1147. { return cmDataChild(p,index); }
  1148. cmData_t* cmDataListMake( cmData_t* parent, cmData_t* p )
  1149. {
  1150. _cmDataFree(p);
  1151. p->parent = parent;
  1152. p->tid = kListDtId;
  1153. p->flags = 0;
  1154. p->u.child = NULL;
  1155. return p;
  1156. }
  1157. cmData_t* cmDataListAlloc( cmData_t* parent)
  1158. { return _cmDataNew(parent,kListDtId,kStructDtId); }
  1159. cmDtRC_t _cmDataParseArgV( cmData_t* parent, va_list vl, cmData_t** vpp )
  1160. {
  1161. cmDtRC_t rc = kOkDtRC;
  1162. cmData_t* vp = NULL;
  1163. cmDataContainerId_t cid = va_arg(vl,unsigned);
  1164. cmDataTypeId_t tid = va_arg(vl,unsigned);
  1165. switch(cid)
  1166. {
  1167. case kInvalidCntDtId: rc = kEolDtRC; break;
  1168. case kScalarDtId:
  1169. switch(tid)
  1170. {
  1171. case kNullDtId: rc = cmDataNewNull( parent,kNoFlagsDtFl,&vp); break;
  1172. case kUCharDtId: rc = cmDataNewUChar( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break;
  1173. case kCharDtId: rc = cmDataNewChar( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break;
  1174. case kUShortDtId: rc = cmDataNewUShort( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break;
  1175. case kShortDtId: rc = cmDataNewShort( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break;
  1176. case kUIntDtId: rc = cmDataNewUInt( parent,kNoFlagsDtFl,va_arg(vl,unsigned int),&vp); break;
  1177. case kIntDtId: rc = cmDataNewInt( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break;
  1178. case kULongDtId: rc = cmDataNewULong( parent,kNoFlagsDtFl,va_arg(vl,unsigned long),&vp); break;
  1179. case kLongDtId: rc = cmDataNewLong( parent,kNoFlagsDtFl,va_arg(vl,long),&vp); break;
  1180. case kFloatDtId: rc = cmDataNewFloat( parent,kNoFlagsDtFl,va_arg(vl,double),&vp); break;
  1181. case kDoubleDtId: rc = cmDataNewDouble( parent,kNoFlagsDtFl,va_arg(vl,double),&vp); break;
  1182. case kStrDtId: rc = cmDataNewStr( parent,kNoFlagsDtFl,va_arg(vl,cmChar_t*),&vp); break;
  1183. default:
  1184. // BUG BUG BUG - signal an error here
  1185. assert(0);
  1186. break;
  1187. }
  1188. break;
  1189. case kArrayDtId:
  1190. switch(tid)
  1191. {
  1192. case kUCharDtId: rc = cmDataNewUCharArray( parent,va_arg(vl,unsigned char*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1193. case kCharDtId: rc = cmDataNewCharArray( parent,va_arg(vl,char*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1194. case kUShortDtId: rc = cmDataNewUShortArray( parent,va_arg(vl,unsigned short*),va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1195. case kShortDtId: rc = cmDataNewShortArray( parent,va_arg(vl,short*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1196. case kUIntDtId: rc = cmDataNewUIntArray( parent,va_arg(vl,unsigned int*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1197. case kIntDtId: rc = cmDataNewIntArray( parent,va_arg(vl,int*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1198. case kULongDtId: rc = cmDataNewULongArray( parent,va_arg(vl,unsigned long*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1199. case kLongDtId: rc = cmDataNewLongArray( parent,va_arg(vl,long*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1200. case kFloatDtId: rc = cmDataNewFloatArray( parent,va_arg(vl,float*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1201. case kDoubleDtId: rc = cmDataNewDoubleArray( parent,va_arg(vl,double*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1202. case kStrDtId: rc = cmDataNewStrArray( parent,va_arg(vl,cmChar_t**), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break;
  1203. default:
  1204. // BUG BUG BUG - signal an error here
  1205. assert(0);
  1206. break;
  1207. }
  1208. break;
  1209. case kListDtId:
  1210. case kPairDtId:
  1211. case kRecordDtId:
  1212. vp = _cmDataNew(parent,cid,kStructDtId);
  1213. break;
  1214. default:
  1215. // BUG BUG BUG - signal an error here
  1216. assert(0);
  1217. break;
  1218. }
  1219. *vpp = vp;
  1220. return rc;
  1221. }
  1222. cmDtRC_t _cmDataListParseV(cmData_t* parent, va_list vl )
  1223. {
  1224. cmDtRC_t rc = kOkDtRC;
  1225. bool contFl = true;
  1226. while( contFl )
  1227. {
  1228. cmData_t* vp;
  1229. rc = _cmDataParseArgV(parent, vl, &vp);
  1230. if(rc != kOkDtRC || cmDataAppendChild(parent,vp)==NULL )
  1231. contFl = false;
  1232. }
  1233. return rc;
  1234. }
  1235. cmRC_t cmDataListAllocV(cmData_t* parent, cmData_t** ref, va_list vl )
  1236. {
  1237. cmData_t* p = cmDataListAlloc(parent);
  1238. cmRC_t rc;
  1239. if((rc = _cmDataListParseV(p, vl )) != kOkDtRC )
  1240. {
  1241. cmDataUnlinkAndFree(p);
  1242. return rc;
  1243. }
  1244. if( ref != NULL )
  1245. *ref = p;
  1246. return rc;
  1247. }
  1248. cmRC_t cmDataListAllocA(cmData_t* parent, cmData_t** ref, ... )
  1249. {
  1250. va_list vl;
  1251. va_start(vl,ref);
  1252. cmRC_t rc = cmDataListAllocV(parent,ref,vl);
  1253. va_end(vl);
  1254. return rc;
  1255. }
  1256. cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele )
  1257. {
  1258. assert(p->cid == kListDtId && p->tid==kStructDtId);
  1259. return cmDataAppendChild(p,ele);
  1260. }
  1261. cmData_t* cmDataListAppendEleN(cmData_t* p, cmData_t* ele[], unsigned n )
  1262. {
  1263. assert(p->cid == kListDtId && p->tid==kStructDtId);
  1264. cmData_t* rp = NULL;
  1265. unsigned i;
  1266. for(i=0; i<n; ++i)
  1267. {
  1268. cmData_t* ep = cmDataAppendChild(p,ele[i]);
  1269. if( rp == NULL )
  1270. rp = ep;
  1271. }
  1272. return rp;
  1273. }
  1274. cmDtRC_t cmDataListAppendV( cmData_t* p, va_list vl )
  1275. {
  1276. cmDtRC_t rc;
  1277. if((rc = _cmDataListParseV(p, vl )) != kOkDtRC )
  1278. return rc;
  1279. return kOkDtRC;
  1280. }
  1281. cmDtRC_t cmDataListAppend( cmData_t* p, ... )
  1282. {
  1283. va_list vl;
  1284. va_start(vl,p);
  1285. cmDtRC_t rc = cmDataListAppendV(p,vl);
  1286. va_end(vl);
  1287. return rc;
  1288. }
  1289. cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele )
  1290. { return cmDataInsertChild(p,index,ele); }
  1291. cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n )
  1292. {
  1293. unsigned i;
  1294. for(i=0; i<n; ++i)
  1295. cmDataListInsertEle(p,index+i,ele[i]);
  1296. return p;
  1297. }
  1298. //----------------------------------------------------------------------------
  1299. unsigned cmDataRecdCount( const cmData_t* p )
  1300. {
  1301. assert( p->cid == kRecordDtId && p->tid==kStructDtId );
  1302. return cmDataChildCount(p);
  1303. }
  1304. cmData_t* cmDataRecdEle( cmData_t* p, unsigned index )
  1305. {
  1306. assert( p->cid == kRecordDtId && p->tid==kStructDtId );
  1307. cmData_t* cp = cmDataChild(p,index);
  1308. assert( p->cid == kPairDtId );
  1309. return cp;
  1310. }
  1311. cmData_t* cmDataRecdValueFromIndex( cmData_t* p, unsigned index )
  1312. {
  1313. assert( p->cid == kRecordDtId && p->tid==kStructDtId );
  1314. cmData_t* cp = cmDataChild(p,index);
  1315. assert( p->cid == kPairDtId && p->tid==kStructDtId );
  1316. return cmDataPairValue(cp);
  1317. }
  1318. cmData_t* cmDataRecdValueFromId( cmData_t* p, unsigned id )
  1319. {
  1320. assert( p->cid == kRecordDtId || p->tid==kStructDtId );
  1321. cmData_t* cp = p->u.child;
  1322. for(; cp!=NULL; cp=cp->sibling)
  1323. if( cmDataPairKeyId(cp) == id )
  1324. break;
  1325. assert( cp!=NULL && cp->cid==kPairDtId && cp->tid==kStructDtId);
  1326. return cmDataPairValue(cp);
  1327. }
  1328. cmData_t* cmDataRecdValueFromLabel( cmData_t* p, const cmChar_t* label )
  1329. {
  1330. assert( p->cid == kRecordDtId && p->tid==kStructDtId);
  1331. cmData_t* cp = p->u.child;
  1332. for(; cp!=NULL; cp=cp->sibling)
  1333. {
  1334. const cmChar_t* lp = cmDataPairKeyLabel(cp);
  1335. if( lp!=NULL && strcmp(lp,label)==0 )
  1336. break;
  1337. }
  1338. assert( cp!=NULL && cp->cid==kPairDtId && cp->tid==kStructDtId);
  1339. return cmDataPairValue(cp);
  1340. }
  1341. cmData_t* cmDataRecdKey( cmData_t* p, unsigned index )
  1342. {
  1343. assert( p->cid == kRecordDtId && p->tid==kStructDtId );
  1344. cmData_t* cp = cmDataChild(p,index);
  1345. assert( cp->cid == kPairDtId && cp->tid==kStructDtId);
  1346. return cmDataPairKey(cp);
  1347. }
  1348. unsigned cmDataRecdKeyId( cmData_t* p, unsigned index )
  1349. {
  1350. cmData_t* kp = cmDataRecdKey(p,index);
  1351. unsigned id = cmInvalidId;
  1352. cmDataGetUInt(kp,&id);
  1353. return id;
  1354. }
  1355. const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index )
  1356. {
  1357. cmData_t* kp = cmDataRecdKey(p,index);
  1358. const cmChar_t* label = NULL;
  1359. // BUG BUG BUG - test return value
  1360. cmDataConstStr(kp,&label);
  1361. return label;
  1362. }
  1363. cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p )
  1364. {
  1365. _cmDataFree(p);
  1366. p->parent = parent;
  1367. p->tid = kRecordDtId;
  1368. p->flags = 0;
  1369. p->u.child = NULL;
  1370. return p;
  1371. }
  1372. cmData_t* cmDataRecdAlloc(cmData_t* parent)
  1373. { return _cmDataNew(parent,kRecordDtId,kStructDtId); }
  1374. cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair )
  1375. {
  1376. assert( p!=NULL && p->cid==kRecordDtId && p->tid==kStructDtId);
  1377. cmDataAppendChild(p,pair);
  1378. return p;
  1379. }
  1380. cmDtRC_t _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl )
  1381. {
  1382. assert( parent != NULL && parent->cid == kRecordDtId && parent->tid == kStructDtId );
  1383. bool contFl = true;
  1384. cmDtRC_t rc = kOkDtRC;
  1385. // for each record field
  1386. while( contFl )
  1387. {
  1388. cmData_t* vp = NULL;
  1389. unsigned id = cmInvalidId;
  1390. const cmChar_t* label = NULL;
  1391. // parse the field idenfier
  1392. if( idFl )
  1393. id = va_arg(vl,unsigned); // numeric field identifier
  1394. else
  1395. label = va_arg(vl,const char*); // text field label identifier
  1396. // validate the field identifier
  1397. if( (idFl && id==cmInvalidId) || (!idFl && label==NULL) )
  1398. break;
  1399. // parse the field data
  1400. if((rc =_cmDataParseArgV( NULL, vl, &vp )) != kOkDtRC )
  1401. {
  1402. contFl = false;
  1403. }
  1404. else
  1405. {
  1406. // create the field pair
  1407. if( idFl )
  1408. cmDataAllocPairId(parent,id,vp);
  1409. else
  1410. cmDataAllocPairLabel(parent,label,vp);
  1411. }
  1412. }
  1413. return rc;
  1414. }
  1415. cmData_t* cmDataRecdAllocLabelV( cmData_t* parent, va_list vl )
  1416. {
  1417. cmData_t* p = cmDataRecdAlloc(parent);
  1418. cmDtRC_t rc = _cmDataRecdParseInputV(p, false, vl );
  1419. if( rc != kOkDtRC )
  1420. {
  1421. cmDataFree(p);
  1422. p = NULL;
  1423. }
  1424. return p;
  1425. }
  1426. cmData_t* cmDataRecdAllocLabelA( cmData_t* parent, ... )
  1427. {
  1428. va_list vl;
  1429. va_start(vl,parent);
  1430. cmData_t* p = cmDataRecdAllocLabelV(parent,vl);
  1431. va_end(vl);
  1432. return p;
  1433. }
  1434. cmData_t* cmDataRecdAllocIdV( cmData_t* parent, va_list vl )
  1435. {
  1436. cmData_t* p = cmDataRecdAlloc(parent);
  1437. cmDtRC_t rc = _cmDataRecdParseInputV(p, true, vl );
  1438. if( rc != kOkDtRC )
  1439. {
  1440. cmDataFree(p);
  1441. p = NULL;
  1442. }
  1443. return p;
  1444. }
  1445. cmData_t* cmDataRecdAllocIdA( cmData_t* parent, ... )
  1446. {
  1447. va_list vl;
  1448. va_start(vl,parent);
  1449. cmData_t* p = cmDataRecdAllocIdV(parent,vl);
  1450. va_end(vl);
  1451. return p;
  1452. }
  1453. cmDtRC_t _cmDataRecdParseV(cmData_t* p, bool idFl, cmErr_t* err, unsigned errRC, va_list vl )
  1454. {
  1455. bool contFl = true;
  1456. cmDtRC_t rc = kOkDtRC;
  1457. while( contFl )
  1458. {
  1459. unsigned id = cmInvalidId;
  1460. const char* label = NULL;
  1461. // parse the field idenfier
  1462. if( idFl )
  1463. id = va_arg(vl,unsigned); // numeric field identifier
  1464. else
  1465. label = va_arg(vl,const char*); // text field label identifier
  1466. // validate the field identifier
  1467. if( (idFl && id==cmInvalidId) || (!idFl && label==NULL) )
  1468. break;
  1469. cmDataContainerId_t cid = va_arg(vl,unsigned);
  1470. cmDataTypeId_t typeId = va_arg(vl,unsigned);
  1471. void* v = va_arg(vl,void*);
  1472. cmData_t* np = NULL;
  1473. bool optFl = cmIsFlag(typeId,kOptArgDtFl);
  1474. cmDtRC_t rc0 = kOkDtRC;
  1475. typeId = cmClrFlag(typeId,kOptArgDtFl);
  1476. if( idFl )
  1477. np = cmDataRecdValueFromLabel( p, label );
  1478. else
  1479. np = cmDataRecdValueFromId( p, id );
  1480. // if the field was not found
  1481. if( np == NULL )
  1482. {
  1483. if(optFl)
  1484. continue;
  1485. if( err != NULL )
  1486. {
  1487. if( idFl )
  1488. cmErrMsg(err,errRC,"The required field (id=%i) was not found.",id);
  1489. else
  1490. cmErrMsg(err,errRC,"The required field '%s' was not found.",cmStringNullGuard(label));
  1491. }
  1492. rc = kMissingFieldDtRC;
  1493. }
  1494. switch(typeId)
  1495. {
  1496. case kNullDtId:
  1497. break;
  1498. case kUCharDtId:
  1499. rc0 = cmDataGetUChar(np,(unsigned char*)v);
  1500. break;
  1501. case kCharDtId:
  1502. rc0 = cmDataGetChar(np,(char*)v);
  1503. break;
  1504. case kUShortDtId:
  1505. rc0 = cmDataGetUShort(np,(unsigned short*)v);
  1506. break;
  1507. case kShortDtId:
  1508. rc0 = cmDataGetShort(np,(short*)v);
  1509. break;
  1510. case kUIntDtId:
  1511. rc0 = cmDataGetUInt(np,(unsigned int*)v);
  1512. break;
  1513. case kIntDtId:
  1514. rc0 = cmDataGetInt(np,(int*)v);
  1515. break;
  1516. case kULongDtId:
  1517. rc0 = cmDataGetULong(np,(unsigned long*)v);
  1518. break;
  1519. case kLongDtId:
  1520. rc0 = cmDataGetLong(np,(long*)v);
  1521. break;
  1522. case kFloatDtId:
  1523. rc0 = cmDataGetFloat(np,(float*)v);
  1524. break;
  1525. case kDoubleDtId:
  1526. rc0 = cmDataGetDouble(np,(double*)v);
  1527. break;
  1528. case kStrDtId:
  1529. rc0 = cmDataGetStr(np,(char**)v);
  1530. break;
  1531. case kConstStrDtId:
  1532. rc0 = cmDataGetConstStr(np,(const char**)v);
  1533. break;
  1534. case kUCharPtrDtId:
  1535. rc0 = cmDataGetUCharPtr(np,(unsigned char**)v);
  1536. break;
  1537. case kCharPtrDtId:
  1538. rc0 = cmDataGetCharPtr(np,(char**)v);
  1539. break;
  1540. case kUShortPtrDtId:
  1541. rc0 = cmDataGetUShortPtr(np,(unsigned short**)v);
  1542. break;
  1543. case kShortPtrDtId:
  1544. rc0 = cmDataGetShortPtr(np,(short**)v);
  1545. break;
  1546. case kUIntPtrDtId:
  1547. rc0 = cmDataGetUIntPtr(np,(unsigned int**)v);
  1548. break;
  1549. case kIntPtrDtId:
  1550. rc0 = cmDataGetIntPtr(np,(int**)v);
  1551. break;
  1552. case kULongPtrDtId:
  1553. rc0 = cmDataGetULongPtr(np,(unsigned long**)v);
  1554. break;
  1555. case kLongPtrDtId:
  1556. rc0 = cmDataGetLongPtr(np,(long**)v);
  1557. break;
  1558. case kFloatPtrDtId:
  1559. rc0 = cmDataGetFloatPtr(np,(float**)v);
  1560. break;
  1561. case kDoublePtrDtId:
  1562. rc0 = cmDataGetDoublePtr(np,(double**)v);
  1563. break;
  1564. case kVoidPtrDtId:
  1565. rc0 = cmDataGetVoidPtr(np,(void**)v);
  1566. break;
  1567. case kListDtId:
  1568. case kPairDtId:
  1569. case kRecordDtId:
  1570. if( np->tid != typeId )
  1571. rc0 = _cmDataSetError(kCvtErrDtRC);
  1572. else
  1573. *(cmData_t**)v = np;
  1574. break;
  1575. default:
  1576. rc0 = _cmDataSetError(kVarArgErrDtRC);
  1577. assert(0);
  1578. }
  1579. if( rc0 != kOkDtRC && err!=NULL)
  1580. {
  1581. if( idFl )
  1582. cmErrMsg(err,errRC,"Unable to convert field (id=%i) to requested type.",id);
  1583. else
  1584. cmErrMsg(err,errRC,"Unable to convert field '%s' to requisted type.",cmStringNullGuard(label));
  1585. rc = rc0;
  1586. }
  1587. }
  1588. return rc;
  1589. }
  1590. cmDtRC_t cmDataRecdParseLabelV(cmData_t* p, cmErr_t* err, unsigned errRC, va_list vl )
  1591. { return _cmDataRecdParseV(p,false,err,errRC,vl); }
  1592. cmDtRC_t cmDataRecdParseLabel(cmData_t* p, cmErr_t* err, unsigned errRC, ... )
  1593. {
  1594. va_list vl;
  1595. va_start(vl,errRC);
  1596. cmDtRC_t rc = cmDataRecdParseLabelV(p,err,errRC,vl);
  1597. va_end(vl);
  1598. return rc;
  1599. }
  1600. cmDtRC_t cmDataRecdParseIdV(cmData_t* p, cmErr_t* err, unsigned errRC, va_list vl )
  1601. { return _cmDataRecdParseV(p,true,err,errRC,vl); }
  1602. cmDtRC_t cmDataRecdParseId(cmData_t* p, cmErr_t* err, unsigned errRC, ... )
  1603. {
  1604. va_list vl;
  1605. va_start(vl,errRC);
  1606. cmDtRC_t rc = cmDataRecdParseIdV(p,err,errRC,vl);
  1607. va_end(vl);
  1608. return rc;
  1609. }
  1610. //============================================================================
  1611. //============================================================================
  1612. //============================================================================
  1613. unsigned _cmDataSerializeNodeByteCount( const cmData_t* p )
  1614. {
  1615. unsigned n = 0;
  1616. // all serialized data ele's begin with a cmDataFmtId_t
  1617. n += sizeof(cmDataFmtId_t);
  1618. // arrays then have a count of bytes and structures have a child count
  1619. if( cmDataIsPtr(p) || cmDataIsStruct(p) )
  1620. n += sizeof(unsigned);
  1621. // then the data itself takes a variable number of bytes
  1622. n += _cmDataByteCount(p);
  1623. return n;
  1624. }
  1625. unsigned cmDataSerializeByteCount( const cmData_t* p )
  1626. {
  1627. unsigned bn = 0;
  1628. // if this data type has a child then calculate it's size
  1629. if( kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId && p->u.child != NULL )
  1630. bn = cmDataSerializeByteCount(p->u.child);
  1631. // if this data type has siblings get their type
  1632. cmData_t* dp = p->u.child;
  1633. for(; dp != NULL; dp=dp->sibling )
  1634. bn += cmDataSerializeByteCount(dp->sibling);
  1635. //
  1636. return bn + _cmDataSerializeNodeByteCount(p);
  1637. }
  1638. char* _cmDataSerializeWriteArray( cmData_t* np, char* dp, const char* ep )
  1639. {
  1640. unsigned byteCnt = _cmDataByteCount(np);
  1641. *((unsigned*)dp) = byteCnt;
  1642. dp += sizeof(unsigned);
  1643. memcpy(dp,np->u.vp,byteCnt);
  1644. dp += byteCnt;
  1645. return dp;
  1646. }
  1647. char* _cmDataSerializeWriteStruct( cmData_t* np, char* dp, const char* ep )
  1648. {
  1649. *((unsigned*)dp) = cmDataChildCount(np);
  1650. dp += sizeof(unsigned);
  1651. return dp;
  1652. }
  1653. char* _cmDataSerializeWrite( cmData_t* np, char* dp, const char* ep )
  1654. {
  1655. assert( dp + _cmDataSerializeNodeByteCount(np) <= ep );
  1656. *((cmDataFmtId_t*)dp) = np->tid;
  1657. dp += sizeof(cmDataFmtId_t);
  1658. switch( np->tid )
  1659. {
  1660. case kNullDtId: break;
  1661. case kUCharDtId: *((unsigned char*)dp) = cmDataUChar(np); dp+=sizeof(unsigned char); break;
  1662. case kCharDtId: *((char*)dp) = cmDataChar(np); dp+=sizeof(char); break;
  1663. case kUShortDtId: *((unsigned short*)dp) = cmDataUShort(np); dp+=sizeof(unsigned short); break;
  1664. case kShortDtId: *((short*)dp) = cmDataShort(np); dp+=sizeof(short); break;
  1665. case kUIntDtId: *((unsigned int*)dp) = cmDataUInt(np); dp+=sizeof(unsigned int); break;
  1666. case kIntDtId: *((int*)dp) = cmDataInt(np); dp+=sizeof(int); break;
  1667. case kULongDtId: *((unsigned long*)dp) = cmDataULong(np); dp+=sizeof(unsigned long); break;
  1668. case kLongDtId: *((long*)dp) = cmDataLong(np); dp+=sizeof(long); break;
  1669. case kFloatDtId: *((float*)dp) = cmDataFloat(np); dp+=sizeof(float); break;
  1670. case kDoubleDtId: *((double*)dp) = cmDataDouble(np); dp+=sizeof(double); break;
  1671. case kStrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1672. case kConstStrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1673. case kUCharPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1674. case kCharPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1675. case kUShortPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1676. case kShortPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1677. case kUIntPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1678. case kIntPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1679. case kULongPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1680. case kLongPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1681. case kFloatPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1682. case kDoublePtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1683. case kVoidPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  1684. case kListDtId: dp = _cmDataSerializeWriteStruct(np,dp,ep); break;
  1685. case kPairDtId: dp = _cmDataSerializeWriteStruct(np,dp,ep); break;
  1686. case kRecordDtId: dp = _cmDataSerializeWriteStruct(np,dp,ep); break;
  1687. default:
  1688. { assert(0); }
  1689. }
  1690. return dp;
  1691. }
  1692. char* _cmDataSerialize( const cmData_t* p, char* buf, const char* ep )
  1693. {
  1694. /*
  1695. buf = _cmDataSerializeWrite(p,buf,ep);
  1696. // if this data type has a child then write the child
  1697. if( kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId && p->u.child != NULL )
  1698. buf = _cmDataSerialize(p->u.child,buf,ep);
  1699. // if this data type has siblings then write sibings
  1700. cmData_t* dp = p->u.child;
  1701. for(; dp != NULL; dp=dp->sibling )
  1702. buf = cmDataSerialize(dp->sibling,buf,ep);
  1703. return buf;
  1704. */
  1705. return NULL;
  1706. }
  1707. cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt )
  1708. {
  1709. /*
  1710. const char* ep = (char*)p + bufByteCnt;
  1711. buf = _cmDataSerialize(p,buf,bufByteCnt);
  1712. assert( buf <= ep );
  1713. */
  1714. return kOkDtRC;
  1715. }
  1716. cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp )
  1717. {
  1718. return kOkDtRC;
  1719. }
  1720. //============================================================================
  1721. //============================================================================
  1722. //============================================================================
  1723. enum
  1724. {
  1725. kLCurlyLexTId = kUserLexTId + 1,
  1726. kRCurlyLexTId,
  1727. kLParenLexTId,
  1728. kRParenLexTId,
  1729. kLBrackLexTId,
  1730. kRBrackLexTId,
  1731. kColonLexTId,
  1732. kCommaLexTId,
  1733. };
  1734. typedef struct
  1735. {
  1736. unsigned id;
  1737. const cmChar_t* label;
  1738. } cmDtToken_t;
  1739. cmDtToken_t _cmDtTokenArray[] =
  1740. {
  1741. { kLCurlyLexTId, "{" },
  1742. { kRCurlyLexTId, "}" },
  1743. { kLBrackLexTId, "[" },
  1744. { kRBrackLexTId, "]" },
  1745. { kLParenLexTId, "(" },
  1746. { kRParenLexTId, ")" },
  1747. { kColonLexTId, ":" },
  1748. { kCommaLexTId, "," },
  1749. { kErrorLexTId,""}
  1750. };
  1751. typedef struct
  1752. {
  1753. cmErr_t err;
  1754. cmLexH lexH;
  1755. cmStackH_t stH;
  1756. } cmDataParser_t;
  1757. cmDataParserH_t cmDataParserNullHandle = cmSTATIC_NULL_HANDLE;
  1758. cmDataParser_t* _cmDataParserHandleToPtr( cmDataParserH_t h )
  1759. {
  1760. cmDataParser_t* p = (cmDataParser_t*)h.h;
  1761. assert( p!= NULL );
  1762. return p;
  1763. }
  1764. cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p )
  1765. {
  1766. if( cmLexFinal(&p->lexH) != kOkLexRC )
  1767. cmErrMsg(&p->err,kLexFailDtRC,"Lexer release failed.");
  1768. if( cmStackFree(&p->stH) != kOkStRC )
  1769. cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack release failed.");
  1770. cmMemFree(p);
  1771. return kOkDtRC;
  1772. }
  1773. cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp )
  1774. {
  1775. cmDtRC_t rc;
  1776. unsigned i;
  1777. if((rc = cmDataParserDestroy(hp)) != kOkDtRC )
  1778. return rc;
  1779. cmDataParser_t* p = cmMemAllocZ(cmDataParser_t,1);
  1780. cmErrSetup(&p->err,&ctx->rpt,"Data Parser");
  1781. if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,&ctx->rpt))==false)
  1782. {
  1783. rc = cmErrMsg(&p->err, kLexFailDtRC, "The data object parser lexer create failed.");
  1784. goto errLabel;
  1785. }
  1786. for(i=0; _cmDtTokenArray[i].id != kErrorLexTId; ++i)
  1787. if( cmLexRegisterToken(p->lexH, _cmDtTokenArray[i].id, _cmDtTokenArray[i].label) != kOkLexRC )
  1788. {
  1789. rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",_cmDtTokenArray[i].label);
  1790. goto errLabel;
  1791. }
  1792. if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmData_t*)) != kOkStRC )
  1793. {
  1794. rc = cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack create failed.");
  1795. goto errLabel;
  1796. }
  1797. hp->h = p;
  1798. errLabel:
  1799. if( rc != kOkDtRC )
  1800. _cmDataParserDestroy(p);
  1801. return kOkDtRC;
  1802. }
  1803. cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp )
  1804. {
  1805. cmDtRC_t rc=kOkDtRC;
  1806. if( hp==NULL || cmDataParserIsValid(*hp)==false )
  1807. return rc;
  1808. cmDataParser_t* p = _cmDataParserHandleToPtr(*hp);
  1809. if((rc = _cmDataParserDestroy(p)) != kOkDtRC )
  1810. return rc;
  1811. hp->h = NULL;
  1812. return kOkDtRC;
  1813. }
  1814. bool cmDataParserIsValid( cmDataParserH_t h )
  1815. { return h.h != NULL; }
  1816. // {
  1817. // id0 : scalar_value
  1818. // id1 : ( heterogenous, array, value )
  1819. // id2 : [ homogeneous array values ]
  1820. // id3 :
  1821. // }
  1822. // flags describing the expected next token
  1823. enum
  1824. {
  1825. kValueExpFl = 0x01,
  1826. kIdExpFl = 0x02,
  1827. kColonExpFl = 0x04,
  1828. kCommaExpFl = 0x08
  1829. };
  1830. typedef struct
  1831. {
  1832. cmData_t* dp;
  1833. } cmDataStEle_t;
  1834. typedef struct
  1835. {
  1836. cmDataParser_t* p;
  1837. cmData_t* cnp;
  1838. unsigned flags;
  1839. cmChar_t* tmpStr;
  1840. unsigned arrayCnt;
  1841. void* arrayMem;
  1842. } cmDataParserCtx_t;
  1843. cmDtRC_t _cmDpSyntaxErrV( cmDataParserCtx_t* c, const cmChar_t* fmt, va_list vl )
  1844. {
  1845. cmChar_t* s0 = NULL;
  1846. cmChar_t* s1 = NULL;
  1847. s0 = cmTsVPrintfP(s0,fmt,vl);
  1848. s1 = cmMemAllocStrN(cmLexTokenText(c->p->lexH),cmLexTokenCharCount(c->p->lexH));
  1849. cmDtRC_t rc = cmErrMsg(&c->p->err,kSyntaxErrDtRC,"Syntax error on line %i column:%i token:'%s'. %s",cmLexCurrentLineNumber(c->p->lexH),cmLexCurrentColumnNumber(c->p->lexH),s1,cmStringNullGuard(s0));
  1850. cmMemFree(s0);
  1851. cmMemFree(s1);
  1852. return rc;
  1853. }
  1854. cmDtRC_t _cmDpSyntaxErr( cmDataParserCtx_t* c, const cmChar_t* fmt, ... )
  1855. {
  1856. va_list vl;
  1857. va_start(vl,fmt);
  1858. cmDtRC_t rc = _cmDpSyntaxErrV(c,fmt,vl);
  1859. va_end(vl);
  1860. return rc;
  1861. }
  1862. cmDtRC_t _cmDpPopStack( cmDataParserCtx_t* c, cmData_t** pp )
  1863. {
  1864. const void* vp;
  1865. if((vp = cmStackTop(c->p->stH)) == NULL )
  1866. return _cmDpSyntaxErr(c,"Stack underflow.");
  1867. if( cmStackPop(c->p->stH,1) != kOkStRC )
  1868. return _cmDpSyntaxErr(c,"Stack pop failed.");
  1869. *pp = *(cmData_t**)vp;
  1870. //printf("pop: %p\n",*pp);
  1871. return kOkDtRC;
  1872. }
  1873. cmDtRC_t _cmDpPushStack( cmDataParserCtx_t* c, cmData_t* np )
  1874. {
  1875. //printf("push:%p\n",np);
  1876. // store the current node
  1877. if( cmStackPush(c->p->stH, &np, 1 ) != kOkStRC )
  1878. return _cmDpSyntaxErr(c,"Parser stack push failed.");
  1879. return kOkDtRC;
  1880. }
  1881. cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned eleByteCnt, unsigned tid )
  1882. {
  1883. if( c->cnp->tid == kVoidPtrDtId )
  1884. c->cnp->tid = tid;
  1885. else
  1886. if( c->cnp->tid != tid )
  1887. return _cmDpSyntaxErr(c,"Mixed types were detected in an array list.");
  1888. unsigned newByteCnt = (c->cnp->cnt+1)*eleByteCnt;
  1889. char* vp = cmMemResizeP(char, c->cnp->u.vp, newByteCnt);
  1890. memcpy(vp + c->cnp->cnt*eleByteCnt,dp,eleByteCnt);
  1891. c->cnp->u.vp = vp;
  1892. c->cnp->cnt += 1;
  1893. c->flags = kValueExpFl | kCommaExpFl;
  1894. return kOkDtRC;
  1895. }
  1896. cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c )
  1897. {
  1898. cmDtRC_t rc = kOkDtRC;
  1899. assert( c->cnp->tid == kRecordDtId );
  1900. // create a pair with a 'null' value which will be replaced when the pair's value is parsed
  1901. cmData_t* nnp = cmDataAllocNull(NULL);
  1902. cmData_t* pnp = cmDataAllocPairLabelN( c->cnp, cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH), nnp );
  1903. // store the current node
  1904. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  1905. return rc;
  1906. // make the new pair the current node
  1907. c->cnp = pnp;
  1908. // pair openings must be followed by a colon.
  1909. c->flags = kColonExpFl;
  1910. return rc;
  1911. }
  1912. cmDtRC_t _cmDataParserClosePair( cmDataParserCtx_t* c )
  1913. {
  1914. cmDtRC_t rc;
  1915. // make the pair's parent record the current node
  1916. if((rc = _cmDpPopStack(c, &c->cnp )) != kOkDtRC )
  1917. return rc;
  1918. // pairs only occur in records
  1919. if( c->cnp->tid != kRecordDtId )
  1920. return _cmDpSyntaxErr(c,"A 'pair' end was found outside of a 'record'.");
  1921. // pairs must be followed by id's or comma's
  1922. c->flags = kIdExpFl | kCommaExpFl;
  1923. return rc;
  1924. }
  1925. cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* typeLabel )
  1926. {
  1927. assert( np != NULL );
  1928. cmDtRC_t rc = kOkDtRC;
  1929. switch( c->cnp->tid )
  1930. {
  1931. case kPairDtId:
  1932. // assign the new node as the value of the pair
  1933. cmDataPairSetValue(c->cnp,np);
  1934. // close the values parent pair
  1935. rc = _cmDataParserClosePair(c);
  1936. break;
  1937. case kListDtId:
  1938. cmDataAppendChild(c->cnp,np);
  1939. c->flags = kValueExpFl;
  1940. break;
  1941. default:
  1942. rc = _cmDpSyntaxErr(c,"A '%s' value was found outside of a valid container.",typeLabel);
  1943. // Free the new data node because it was not attached and will
  1944. // otherwise be lost
  1945. cmDataFree(np);
  1946. }
  1947. c->flags |= kCommaExpFl;
  1948. return rc;
  1949. }
  1950. cmDtRC_t _cmDataParserReal( cmDataParserCtx_t* c )
  1951. {
  1952. cmDtRC_t rc = kOkDtRC;
  1953. bool floatFl = cmLexTokenIsSinglePrecision(c->p->lexH);
  1954. double dval;
  1955. float fval;
  1956. if( floatFl )
  1957. fval = cmLexTokenFloat(c->p->lexH);
  1958. else
  1959. dval = cmLexTokenDouble(c->p->lexH);
  1960. if( cmDataIsPtr(c->cnp) )
  1961. {
  1962. if( floatFl )
  1963. rc = _cmDpStoreArrayEle(c,&fval,sizeof(fval),kFloatPtrDtId);
  1964. else
  1965. rc = _cmDpStoreArrayEle(c,&dval,sizeof(dval),kDoublePtrDtId);
  1966. }
  1967. else
  1968. {
  1969. cmData_t* np = floatFl ? cmDataAllocFloat(NULL,fval) : cmDataAllocDouble(NULL,dval);
  1970. rc = _cmDpStoreValue(c,np,"real");
  1971. }
  1972. return rc;
  1973. }
  1974. cmDtRC_t _cmDataParserInt( cmDataParserCtx_t* c )
  1975. {
  1976. cmDtRC_t rc = kOkDtRC;
  1977. int val = cmLexTokenInt(c->p->lexH);
  1978. bool unsignedFl = cmLexTokenIsUnsigned(c->p->lexH);
  1979. if( cmDataIsPtr(c->cnp) )
  1980. rc = _cmDpStoreArrayEle(c,&val,sizeof(val),unsignedFl ? kUIntPtrDtId : kIntPtrDtId);
  1981. else
  1982. {
  1983. cmData_t* np = unsignedFl ? cmDataAllocUInt(NULL,val) : cmDataAllocInt(NULL,val);
  1984. rc = _cmDpStoreValue(c,np,"int");
  1985. }
  1986. return rc;
  1987. }
  1988. cmDtRC_t _cmDataParserString( cmDataParserCtx_t* c )
  1989. {
  1990. // if we are expecting a pair label
  1991. if( cmIsFlag(c->flags,kIdExpFl) )
  1992. return _cmDataParserOpenPair(c);
  1993. // otherwise a 'value' must be expected
  1994. if( cmIsNotFlag(c->flags,kValueExpFl) )
  1995. return _cmDpSyntaxErr(c,"Unexpected string.");
  1996. cmData_t* np = cmDataConstStrAllocN(NULL,cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH));
  1997. return _cmDpStoreValue(c,np,"string");
  1998. }
  1999. cmDtRC_t _cmDataParserOpenRecd( cmDataParserCtx_t* c )
  2000. {
  2001. cmDtRC_t rc = kOkDtRC;
  2002. // records are values - so we must be expecting a value
  2003. if( cmIsFlag(c->flags,kValueExpFl) == false )
  2004. return _cmDpSyntaxErr(c,"Unexpected '{'.");
  2005. // store the current node
  2006. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  2007. return rc;
  2008. // alloc a new record and make it the current node
  2009. if( (c->cnp = cmDataRecdAlloc(NULL)) == NULL )
  2010. return _cmDpSyntaxErr(c,"'recd' allocate failed.");
  2011. // new records must be followed by an id token.
  2012. c->flags = kIdExpFl;
  2013. return rc;
  2014. }
  2015. cmDtRC_t _cmDataParserCloseContainer( cmDataParserCtx_t* c, const cmChar_t* typeLabelStr )
  2016. {
  2017. cmDtRC_t rc;
  2018. cmData_t* np = c->cnp;
  2019. // make the parent node the new current node
  2020. if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
  2021. return rc;
  2022. return _cmDpStoreValue(c,np,typeLabelStr);
  2023. }
  2024. cmDtRC_t _cmDataParserCloseRecd( cmDataParserCtx_t* c )
  2025. {
  2026. assert( c->cnp->tid == kRecordDtId );
  2027. return _cmDataParserCloseContainer(c,"record");
  2028. }
  2029. cmDtRC_t _cmDataParserOpenList( cmDataParserCtx_t* c )
  2030. {
  2031. cmDtRC_t rc = kOkDtRC;
  2032. // lists are values - so we must be expecting a value
  2033. if( cmIsFlag(c->flags,kValueExpFl) == false )
  2034. return _cmDpSyntaxErr(c,"Unexpected '('.");
  2035. // store the current node
  2036. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  2037. return rc;
  2038. // create a new list
  2039. if( (c->cnp = cmDataListAlloc(NULL)) == NULL )
  2040. return _cmDpSyntaxErr(c,"'list' allocate failed.");
  2041. // new lists must be followed by a value
  2042. c->flags = kValueExpFl;
  2043. return rc;
  2044. }
  2045. cmDtRC_t _cmDataParserCloseList( cmDataParserCtx_t* c )
  2046. {
  2047. assert( c->cnp->tid == kListDtId );
  2048. return _cmDataParserCloseContainer(c,"list");
  2049. }
  2050. cmDtRC_t _cmDataParserOpenArray( cmDataParserCtx_t* c )
  2051. {
  2052. cmDtRC_t rc = kOkDtRC;
  2053. // arrays are values - so we must be expecting a value
  2054. if( cmIsFlag(c->flags,kValueExpFl) == false )
  2055. return _cmDpSyntaxErr(c,"Unexpected '('.");
  2056. // store the current node
  2057. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  2058. return rc;
  2059. // create a new array
  2060. if( (c->cnp = cmDataVoidAllocPtr(NULL, NULL, 0 )) == NULL )
  2061. return _cmDpSyntaxErr(c,"'array' allocate failed.");
  2062. // new arrays must be followed by a value
  2063. c->flags = kValueExpFl;
  2064. return rc;
  2065. }
  2066. cmDtRC_t _cmDataParserCloseArray( cmDataParserCtx_t* c )
  2067. {
  2068. assert( cmDataIsPtr(c->cnp) );
  2069. return _cmDataParserCloseContainer(c,"array");
  2070. }
  2071. cmDtRC_t _cmDataParserOnColon( cmDataParserCtx_t* c )
  2072. {
  2073. // colons only follow field identifiers and are always followed by values.
  2074. if( cmIsFlag(c->flags,kColonExpFl) == false )
  2075. return _cmDpSyntaxErr(c,"Unexpected colon.");
  2076. c->flags = kValueExpFl;
  2077. return kOkDtRC;
  2078. }
  2079. cmDtRC_t _cmDataParserOnComma( cmDataParserCtx_t* c )
  2080. {
  2081. // comma's may be found in three places:
  2082. // 1) following field values
  2083. // 2) between list values
  2084. // 3) between array values
  2085. // comma's are always followed by values
  2086. if( cmIsFlag(c->flags,kCommaExpFl) == false )
  2087. return _cmDpSyntaxErr(c, "Unexpected comma.");
  2088. c->flags = kValueExpFl;
  2089. return kOkDtRC;
  2090. }
  2091. cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp )
  2092. {
  2093. cmDtRC_t rc = kOkDtRC;
  2094. cmDataParser_t* p = _cmDataParserHandleToPtr(h);
  2095. unsigned tokenId;
  2096. cmDataParserCtx_t ctx;
  2097. cmData_t* root = cmDataRecdAlloc(NULL);
  2098. ctx.cnp = root;
  2099. ctx.p = p;
  2100. ctx.flags = kIdExpFl;
  2101. if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC )
  2102. return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset.");
  2103. cmStackClear(p->stH,false);
  2104. while(rc==kOkDtRC && (tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId )
  2105. {
  2106. switch(tokenId)
  2107. {
  2108. case kRealLexTId: // real number (contains a decimal point or is in scientific notation)
  2109. rc = _cmDataParserReal(&ctx);
  2110. break;
  2111. case kIntLexTId: // decimal integer
  2112. case kHexLexTId: // hexidecimal integer
  2113. rc = _cmDataParserInt(&ctx);
  2114. break;
  2115. case kIdentLexTId: // identifiers are treated as strings
  2116. case kQStrLexTId: // quoted string
  2117. rc = _cmDataParserString(&ctx);
  2118. break;
  2119. case kLCurlyLexTId: // a new record is starting
  2120. rc = _cmDataParserOpenRecd(&ctx);
  2121. break;
  2122. case kRCurlyLexTId: // the current record is finished
  2123. rc = _cmDataParserCloseRecd(&ctx);
  2124. break;
  2125. case kLParenLexTId: // a list is starting
  2126. rc = _cmDataParserOpenList(&ctx);
  2127. break;
  2128. case kRParenLexTId: // a list is finished
  2129. rc = _cmDataParserCloseList(&ctx);
  2130. break;
  2131. case kLBrackLexTId: // an array is starting
  2132. rc = _cmDataParserOpenArray(&ctx);
  2133. break;
  2134. case kRBrackLexTId: // an array is ending
  2135. rc = _cmDataParserCloseArray(&ctx);
  2136. break;
  2137. case kColonLexTId: // the previous id was a field id
  2138. rc = _cmDataParserOnColon(&ctx);
  2139. break;
  2140. case kCommaLexTId: // comma sep. for array or fields
  2141. rc = _cmDataParserOnComma(&ctx);
  2142. break;
  2143. case kBlockCmtLexTId: // block comment
  2144. case kLineCmtLexTId: // line comment
  2145. case kErrorLexTId: // the lexer was unable to identify the current token
  2146. case kUnknownLexTId: // the token is of an unknown type (only used when kReturnUnknownLexFl is set)
  2147. case kEofLexTId: // the lexer reached the end of input
  2148. case kSpaceLexTId: // white space
  2149. {
  2150. rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed with an unexpected token '%s' on line '%i'.",cmLexIdToLabel(p->lexH,tokenId),cmLexCurrentLineNumber(p->lexH));
  2151. goto errLabel;
  2152. }
  2153. }
  2154. }
  2155. errLabel:
  2156. if( rc == kOkDtRC )
  2157. *pp = ctx.cnp;
  2158. else
  2159. {
  2160. if( ctx.cnp != root )
  2161. cmDataUnlinkAndFree(ctx.cnp);
  2162. cmDataUnlinkAndFree(root);
  2163. }
  2164. return rc;
  2165. }
  2166. //============================================================================
  2167. //============================================================================
  2168. //============================================================================
  2169. #define parr(rpt,fmt,arr,n) do{int i=0; cmRptPrintf(rpt,"[ "); for(;i<n;++i) cmRptPrintf(rpt,fmt,arr[i]); cmRptPrintf(rpt," ]"); }while(0)
  2170. void _cmDataPrintIndent( cmRpt_t* rpt, unsigned indent )
  2171. {
  2172. unsigned j=0;
  2173. for(; j<indent; ++j)
  2174. cmRptPrintf(rpt," ");
  2175. }
  2176. void _cmDataPrint( const cmData_t* p, cmRpt_t* rpt, unsigned indent )
  2177. {
  2178. cmData_t* cp;
  2179. //_cmDataPrintIndent(rpt,indent);
  2180. switch(p->tid)
  2181. {
  2182. case kNullDtId: cmRptPrintf(rpt,"<null>"); break;
  2183. case kUCharDtId: cmRptPrintf(rpt,"%c ",cmDataUChar(p)); break;
  2184. case kCharDtId: cmRptPrintf(rpt,"%c ",cmDataChar(p)); break;
  2185. case kUShortDtId: cmRptPrintf(rpt,"%i ",cmDataUShort(p)); break;
  2186. case kShortDtId: cmRptPrintf(rpt,"%i ",cmDataShort(p)); break;
  2187. case kUIntDtId: cmRptPrintf(rpt,"%i ",cmDataUInt(p)); break;
  2188. case kIntDtId: cmRptPrintf(rpt,"%i ",cmDataInt(p)); break;
  2189. case kULongDtId: cmRptPrintf(rpt,"%i ",cmDataULong(p)); break;
  2190. case kLongDtId: cmRptPrintf(rpt,"%i ",cmDataLong(p)); break;
  2191. case kFloatDtId: cmRptPrintf(rpt,"%f ",cmDataFloat(p)); break;
  2192. case kDoubleDtId: cmRptPrintf(rpt,"%f ",cmDataDouble(p)); break;
  2193. case kStrDtId: cmRptPrintf(rpt,"%s ",cmDataStr(p)); break;
  2194. case kConstStrDtId: cmRptPrintf(rpt,"%s ",cmDataConstStr(p)); break;
  2195. case kUCharPtrDtId: parr(rpt,"%c ",cmDataUCharPtr(p), p->cnt); break;
  2196. case kCharPtrDtId: parr(rpt,"%c ",cmDataCharPtr(p), p->cnt); break;
  2197. case kUShortPtrDtId: parr(rpt,"%i ",cmDataUShortPtr(p),p->cnt); break;
  2198. case kShortPtrDtId: parr(rpt,"%i ",cmDataShortPtr(p), p->cnt); break;
  2199. case kUIntPtrDtId: parr(rpt,"%i ",cmDataUIntPtr(p), p->cnt); break;
  2200. case kIntPtrDtId: parr(rpt,"%i ",cmDataIntPtr(p), p->cnt); break;
  2201. case kULongPtrDtId: parr(rpt,"%i ",cmDataULongPtr(p), p->cnt); break;
  2202. case kLongPtrDtId: parr(rpt,"%i ",cmDataLongPtr(p), p->cnt); break;
  2203. case kFloatPtrDtId: parr(rpt,"%f ",cmDataFloatPtr(p), p->cnt); break;
  2204. case kDoublePtrDtId: parr(rpt,"%f ",cmDataDoublePtr(p),p->cnt); break;
  2205. case kVoidPtrDtId: cmRptPrintf(rpt,"<void:%i>",p->cnt); break;
  2206. case kPairDtId:
  2207. _cmDataPrint(p->u.child,rpt,indent);
  2208. cmRptPrintf(rpt," : ");
  2209. _cmDataPrint(p->u.child->sibling,rpt,indent);
  2210. cmRptPrintf(rpt,"\n");
  2211. break;
  2212. case kListDtId:
  2213. cmRptPrintf(rpt,"(\n");
  2214. indent += 2;
  2215. cp = p->u.child;
  2216. for(; cp!=NULL; cp=cp->sibling)
  2217. {
  2218. _cmDataPrintIndent(rpt,indent);
  2219. _cmDataPrint(cp,rpt,indent);
  2220. cmRptPrintf(rpt,"\n");
  2221. }
  2222. indent -= 2;
  2223. _cmDataPrintIndent(rpt,indent);
  2224. cmRptPrintf(rpt,")\n");
  2225. break;
  2226. case kRecordDtId:
  2227. cmRptPrintf(rpt,"{\n");
  2228. indent += 2;
  2229. cp = p->u.child;
  2230. for(; cp!=NULL; cp=cp->sibling)
  2231. {
  2232. _cmDataPrintIndent(rpt,indent);
  2233. _cmDataPrint(cp,rpt, indent);
  2234. }
  2235. indent -= 2;
  2236. _cmDataPrintIndent(rpt,indent);
  2237. cmRptPrintf(rpt,"}\n");
  2238. break;
  2239. default:
  2240. break;
  2241. }
  2242. }
  2243. void cmDataPrint( const cmData_t* p, cmRpt_t* rpt )
  2244. { _cmDataPrint(p,rpt,0); }
  2245. cmDtRC_t cmDataParserTest( cmCtx_t* ctx )
  2246. {
  2247. cmDtRC_t rc = kOkDtRC;
  2248. cmDataParserH_t h = cmDataParserNullHandle;
  2249. cmErr_t err;
  2250. cmData_t* dp = NULL;
  2251. const cmChar_t text[] =
  2252. {
  2253. //0 1 2 3
  2254. //0123456789012345678901234567890123
  2255. "f0:1.23 f1:\"hey\" f2:( a b c ) f3:[ 0f 1f 2f ]"
  2256. //"f0:1.23 f1:\"hey\""
  2257. };
  2258. cmErrSetup(&err,&ctx->rpt,"Data Parser Tester");
  2259. if((rc = cmDataParserCreate(ctx, &h )) != kOkDtRC )
  2260. {
  2261. rc = cmErrMsg(&err,rc,"Data parser create failed.");
  2262. goto errLabel;
  2263. }
  2264. if( cmDataParserExec(h,text,&dp) != kOkDtRC )
  2265. rc = cmErrMsg(&err,rc,"Data parser exec failed.");
  2266. else
  2267. if( dp != NULL )
  2268. cmDataPrint(dp,&ctx->rpt);
  2269. errLabel:
  2270. if( cmDataParserDestroy( &h ) != kOkDtRC )
  2271. {
  2272. rc = cmErrMsg(&err,rc,"Data parser destroy failed.");
  2273. goto errLabel;
  2274. }
  2275. cmDataFree(dp);
  2276. return rc;
  2277. }
  2278. void cmDataTest( cmCtx_t* ctx )
  2279. {
  2280. float farr[] = { 1.23, 45.6, 7.89 };
  2281. cmDataParserTest(ctx);
  2282. return;
  2283. cmData_t* d0 = cmDataRecdAllocLabelA(NULL,
  2284. "name",kConstStrDtId,"This is a string.",
  2285. "id", kUIntDtId, 21,
  2286. "real",kFloatDtId, 1.23,
  2287. "arr", kFloatPtrDtId, farr, 3,
  2288. NULL);
  2289. cmDataPrint(d0,&ctx->rpt);
  2290. cmDataFree(d0);
  2291. cmData_t* d1 = cmDataListAllocA(NULL,
  2292. kUIntDtId, 53,
  2293. kStrDtId, "Blah blah",
  2294. kFloatPtrDtId, farr, 3,
  2295. kInvalidDtId );
  2296. cmDataPrint(d1,&ctx->rpt);
  2297. cmDataFree(d1);
  2298. cmRptPrintf(&ctx->rpt,"Done!.\n");
  2299. }