libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

cmData.c 95KB

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