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 120KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300
  1. #include "cmGlobal.h"
  2. #include "cmRpt.h"
  3. #include "cmErr.h"
  4. #include "cmCtx.h"
  5. #include "cmMem.h"
  6. #include "cmMallocDebug.h"
  7. #include "cmLinkedHeap.h"
  8. #include "cmData.h"
  9. #include "cmLex.h"
  10. #include "cmText.h"
  11. #include "cmStack.h"
  12. typedef struct
  13. {
  14. cmDataTypeId_t typeId;
  15. unsigned byteWidth;
  16. const cmChar_t* label;
  17. } cmDtTypeInfo_t;
  18. typedef struct
  19. {
  20. cmDataContainerId_t id;
  21. const cmChar_t* label;
  22. } cmDtCntInfo_t;
  23. cmDtTypeInfo_t _cmDtTypeInfoArray[] =
  24. {
  25. { kNullDtId, 0, "null" },
  26. { kUCharDtId, sizeof(unsigned char), "uchar" },
  27. { kCharDtId, sizeof(char), "char" },
  28. { kUShortDtId, sizeof(unsigned short), "ushort" },
  29. { kShortDtId, sizeof(short), "short" },
  30. { kUIntDtId, sizeof(unsigned int), "uint" },
  31. { kIntDtId, sizeof(int), "int" },
  32. { kULongDtId, sizeof(unsigned long), "ulong" },
  33. { kLongDtId, sizeof(long), "long" },
  34. { kFloatDtId, sizeof(float), "float" },
  35. { kDoubleDtId, sizeof(double), "double" },
  36. { kStrDtId, sizeof(char*), "string" },
  37. { kBlobDtId, sizeof(void*), "blob" },
  38. { kInvalidTypeDtId, 0, "<invalid-type>" },
  39. };
  40. cmDtCntInfo_t _cmDtCntInfoArray[] =
  41. {
  42. { kScalarDtId, "scalar" },
  43. { kArrayDtId, "array" },
  44. { kListDtId, "list" },
  45. { kPairDtId, "pair" },
  46. { kRecordDtId, "record"},
  47. { kInvalidCntDtId,"<invalid-container>"}
  48. };
  49. cmData_t cmDataNull = { kInvalidTypeDtId,kInvalidCntDtId,0,NULL,NULL,0 };
  50. cmDtRC_t _cmDtErrMsgV( const cmData_t* d, cmDtRC_t rc, const cmChar_t* fmt, va_list vl )
  51. {
  52. // REPLACE this with a global cmRpt call.
  53. vprintf(fmt,vl);
  54. return rc;
  55. }
  56. cmDtRC_t _cmDtErrMsg( const cmData_t* d, cmDtRC_t rc, const cmChar_t* fmt, ... )
  57. {
  58. va_list vl;
  59. va_start(vl,fmt);
  60. rc = _cmDtErrMsgV(d,rc,fmt,vl);
  61. va_end(vl);
  62. return rc;
  63. }
  64. const cmChar_t* cmDataTypeToLabel( cmDataTypeId_t tid )
  65. {
  66. unsigned i;
  67. for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i)
  68. if( _cmDtTypeInfoArray[i].typeId == tid )
  69. return _cmDtTypeInfoArray[i].label;
  70. return NULL;
  71. }
  72. cmDataTypeId_t cmDataLabelToType( const cmChar_t* typeLabelStr )
  73. {
  74. unsigned i;
  75. for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i)
  76. if( strcmp(_cmDtTypeInfoArray[i].label,typeLabelStr) == 0 )
  77. return _cmDtTypeInfoArray[i].typeId;
  78. return kInvalidTypeDtId;
  79. }
  80. unsigned cmDataByteWidth( cmDataTypeId_t tid )
  81. {
  82. unsigned i;
  83. for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i)
  84. if( _cmDtTypeInfoArray[i].typeId == tid )
  85. return _cmDtTypeInfoArray[i].byteWidth;
  86. return cmInvalidCnt;
  87. }
  88. const cmChar_t* cmDataContainerIdToLabel( cmDataContainerId_t tid )
  89. {
  90. unsigned i;
  91. for(i=0; _cmDtCntInfoArray[i].id!=kInvalidCntDtId; ++i)
  92. if( _cmDtCntInfoArray[i].id == tid )
  93. return _cmDtCntInfoArray[i].label;
  94. return NULL;
  95. }
  96. cmDataContainerId_t cmDataLabelToContainerId( const cmChar_t* contLabelStr )
  97. {
  98. unsigned i;
  99. for(i=0; _cmDtCntInfoArray[i].id!=kInvalidCntDtId; ++i)
  100. if( strcmp(_cmDtCntInfoArray[i].label,contLabelStr) == 0 )
  101. return _cmDtCntInfoArray[i].id;
  102. return kInvalidCntDtId;
  103. }
  104. bool _cmDataIsDataOwner( const cmData_t* d )
  105. { return cmIsFlag(d->flags,kFreeValueDtFl) && (d->cid==kArrayDtId || d->tid==kStrDtId || d->tid==kBlobDtId); }
  106. cmDtRC_t _cmDataFreeData( cmData_t* d )
  107. {
  108. if( _cmDataIsDataOwner(d) )
  109. {
  110. // A object marked with kFreeValueDtFl should never also be 'const.
  111. // (??? is this true ???? )
  112. assert( cmIsNotFlag(d->flags,kConstValueDtFl) );
  113. cmMemPtrFree(&d->u.vp);
  114. }
  115. d->flags = cmClrFlag(d->flags,kFreeValueDtFl | kConstValueDtFl );
  116. d->tid = kNullDtId; // objects without data are always of type 'null'.
  117. d->cnt = 0;
  118. memset(&d->u,0,sizeof(d->u));
  119. return kOkDtRC;
  120. }
  121. void _cmDataFree( cmData_t* p )
  122. {
  123. if( p == NULL )
  124. return;
  125. if( cmDataIsStruct(p) )
  126. {
  127. cmData_t* cp = p->u.child;
  128. for(; cp!=NULL; cp=cp->sibling)
  129. _cmDataFree(cp);
  130. }
  131. _cmDataFreeData(p);
  132. if( cmIsFlag(p->flags,kFreeObjDtFl) )
  133. cmMemFree(p);
  134. }
  135. /*
  136. cmData_t* _cmDataAllocNode( cmData_t* parent, cmDataFmtId_t tid )
  137. {
  138. cmData_t* p = cmMemAllocZ(cmData_t,1);
  139. p->tid = tid;
  140. p->flags = kDynObjDtFl;
  141. p->parent = parent;
  142. if( parent != NULL )
  143. return cmDataAppendChild(parent,p);
  144. return p;
  145. }
  146. */
  147. // Dynamically allocate a 'null' data object.
  148. cmDtRC_t _cmDataNew(cmData_t* parent, cmData_t** ref)
  149. {
  150. cmData_t* d = cmMemAllocZ(cmData_t,1);
  151. d->tid = kNullDtId; // objects without data are of type 'null'.
  152. d->cid = kScalarDtId;
  153. d->flags = kFreeObjDtFl;
  154. d->parent = parent;
  155. d->cnt = 0;
  156. if( parent != NULL )
  157. cmDataAppendChild(parent,d);
  158. *ref = d;
  159. return kOkDtRC;
  160. }
  161. bool cmDataIsConstObj( const cmData_t* d )
  162. { return cmIsFlag(d->flags,kConstObjDtFl); }
  163. void cmDataEnableConstObj( cmData_t* d, bool enaFl )
  164. { d->flags = cmEnaFlag(d->flags,kConstObjDtFl,enaFl); }
  165. bool cmDataIsConstValue( const cmData_t* d )
  166. { return cmIsFlag(d->flags,kConstValueDtFl); }
  167. void cmDataEnableConstValue( cmData_t* d, bool enaFl )
  168. { d->flags = cmEnaFlag(d->flags,kConstValueDtFl,enaFl); }
  169. bool cmDataIsFreeValue( const cmData_t* d )
  170. { return cmIsFlag(d->flags,kFreeValueDtFl); }
  171. void cmDataEnableFreeValue( cmData_t* d, bool enaFl )
  172. { d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,enaFl); }
  173. bool cmDataIsLeaf( const cmData_t* d)
  174. { return d->cid == kScalarDtId || d->cid == kArrayDtId; }
  175. bool cmDataIsStruct( const cmData_t* d )
  176. { return !cmDataIsLeaf(d); }
  177. cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref )
  178. {
  179. cmData_t* d = NULL;
  180. cmDtRC_t rc;
  181. *ref = NULL;
  182. // create a scalar null object
  183. if((rc = _cmDataNew(parent,&d)) != kOkDtRC )
  184. return rc;
  185. if( tid!=kStrDtId && tid!=kBlobDtId )
  186. {
  187. // When used with scalars kFreeValueDtFl and kNoCopyDtFl only
  188. // has meaning for strings and blobs - so clear these flags for other types.
  189. flags = cmClrFlag(flags,kFreeValueDtFl | kNoCopyDtFl);
  190. // if this is not a blob or string then the byteCnt is reset
  191. byteCnt = cmDataByteWidth(tid);
  192. }
  193. // assign the value
  194. if((rc = cmDataSetScalarValue(d,tid,vp,byteCnt,flags)) != kOkDtRC )
  195. return rc;
  196. // set the const flags for the new object
  197. d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl));
  198. *ref = d;
  199. return rc;
  200. }
  201. cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref )
  202. { return _cmDataNew(parent, ref); }
  203. cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref )
  204. { return cmDataNewScalar(parent,kCharDtId,flags,&v,0,ref); }
  205. cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref )
  206. { return cmDataNewScalar(parent,kUCharDtId,flags,&v,0,ref); }
  207. cmDtRC_t cmDataNewShort( cmData_t* parent, unsigned flags, short v, cmData_t** ref )
  208. { return cmDataNewScalar(parent,kShortDtId,flags,&v,0,ref); }
  209. cmDtRC_t cmDataNewUShort( cmData_t* parent, unsigned flags, unsigned short v, cmData_t** ref )
  210. { return cmDataNewScalar(parent,kUShortDtId,flags,&v,0,ref); }
  211. cmDtRC_t cmDataNewInt( cmData_t* parent, unsigned flags, int v, cmData_t** ref )
  212. { return cmDataNewScalar(parent,kIntDtId,flags,&v,0,ref); }
  213. cmDtRC_t cmDataNewUInt( cmData_t* parent, unsigned flags, unsigned int v, cmData_t** ref )
  214. { return cmDataNewScalar(parent,kUIntDtId,flags,&v,0,ref); }
  215. cmDtRC_t cmDataNewLong( cmData_t* parent, unsigned flags, long v, cmData_t** ref )
  216. { return cmDataNewScalar(parent,kLongDtId,flags,&v,0,ref); }
  217. cmDtRC_t cmDataNewULong( cmData_t* parent, unsigned flags, unsigned long v, cmData_t** ref )
  218. { return cmDataNewScalar(parent,kULongDtId,flags,&v,0,ref); }
  219. cmDtRC_t cmDataNewFloat( cmData_t* parent, unsigned flags, float v, cmData_t** ref )
  220. { return cmDataNewScalar(parent,kFloatDtId,flags,&v,0,ref); }
  221. cmDtRC_t cmDataNewDouble( cmData_t* parent, unsigned flags, double v, cmData_t** ref )
  222. { return cmDataNewScalar(parent,kDoubleDtId,flags,&v,0,ref); }
  223. cmDtRC_t cmDataNewStr( cmData_t* parent, unsigned flags, cmChar_t* v, cmData_t** ref )
  224. { return cmDataNewScalar(parent,kStrDtId,flags,v,strlen(v)+1,ref); }
  225. cmDtRC_t cmDataNewConstStr( cmData_t* parent, unsigned flags, const cmChar_t* v, cmData_t** ref )
  226. { return cmDataNewScalar(parent,kStrDtId,flags | kConstValueDtFl, (void*)v,strlen(v)+1,ref); }
  227. cmDtRC_t cmDataNewStrN( cmData_t* parent, unsigned flags, cmChar_t* v, unsigned charCnt, cmData_t** ref )
  228. { return cmDataNewScalar(parent,kStrDtId,flags,v,charCnt+1,ref); }
  229. cmDtRC_t cmDataNewConstStrN( cmData_t* parent, unsigned flags, const cmChar_t* v, unsigned charCnt, cmData_t** ref )
  230. { return cmDataNewScalar(parent,kStrDtId,flags | kConstValueDtFl, (void*)v,charCnt+1,ref); }
  231. cmDtRC_t cmDataNewBlob( cmData_t* parent, unsigned flags, void* v, unsigned byteCnt, cmData_t** ref )
  232. { return cmDataNewScalar(parent,kBlobDtId,flags,v,byteCnt,ref); }
  233. cmDtRC_t cmDataNewConstBlob( cmData_t* parent, unsigned flags, const void* v, unsigned byteCnt, cmData_t** ref )
  234. { return cmDataNewScalar(parent,kBlobDtId,flags | kConstValueDtFl, (void*)v,byteCnt,ref); }
  235. cmDtRC_t cmDataSetScalarValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned byteCnt, unsigned flags )
  236. {
  237. cmDtRC_t rc;
  238. // if the type of the object is changing
  239. if( d->tid != tid || d->cid != kScalarDtId )
  240. {
  241. // verify that it is legal to change the type of the object
  242. if( cmIsFlag(d->flags,kConstObjDtFl) )
  243. return _cmDtErrMsg(d,kConstErrDtRC,"Const object violation.");
  244. // convert this to a scalar null object.
  245. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  246. return rc;
  247. }
  248. // verify that it is legal to change the value of this object
  249. if( cmIsFlag(d->flags,kConstValueDtFl) )
  250. return _cmDtErrMsg(d,kConstErrDtRC,"Const value violation.");
  251. switch( tid )
  252. {
  253. case kInvalidTypeDtId:
  254. return _cmDtErrMsg(d,kAssertErrDtRC,"Invalid data type.");
  255. case kNullDtId: // 'd' is already NULL.
  256. break;
  257. case kUCharDtId: d->u.uc = *(unsigned char*)vp; break;
  258. case kCharDtId: d->u.c = *(char*)vp; break;
  259. case kUShortDtId: d->u.us = *(unsigned short*)vp; break;
  260. case kShortDtId: d->u.s = *(short*)vp; break;
  261. case kUIntDtId: d->u.ui = *(unsigned int*)vp; break;
  262. case kIntDtId: d->u.i = *(int*)vp; break;
  263. case kULongDtId: d->u.ul = *(unsigned long*)vp; break;
  264. case kLongDtId: d->u.l = *(long*)vp; break;
  265. case kFloatDtId: d->u.f = *(float*)vp; break;
  266. case kDoubleDtId: d->u.d = *(double*)vp; break;
  267. case kStrDtId:
  268. case kBlobDtId:
  269. {
  270. cmChar_t* blankStr = "";
  271. // strings must have a byteCnt of at least one
  272. assert( tid==kBlobDtId || (tid==kStrDtId && byteCnt>0) );
  273. // if a NULL source string is encountered then make it a 0 length string
  274. if( d->tid==kStrDtId && vp==NULL )
  275. vp = blankStr;
  276. // if an empty blob was passed in then be sure it's src ptr is NULL and byteCnt==0
  277. if( d->tid==kBlobDtId && (vp==NULL || byteCnt==0) )
  278. {
  279. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  280. return rc;
  281. byteCnt = 0;
  282. d->u.z = NULL;
  283. break;
  284. }
  285. // if the incoming string/blob should be internally duplicated
  286. if( cmIsNotFlag(flags,kNoCopyDtFl) )
  287. {
  288. // allocate internal space to store the incoming data
  289. if( (d->tid==kBlobDtId || d->tid == kStrDtId) && cmIsFlag(d->flags,kFreeValueDtFl) )
  290. d->u.z = cmMemResize(char,d->u.z,byteCnt);
  291. else
  292. d->u.z = cmMemAlloc(char,byteCnt);
  293. // store the source string/blob into the internal memory buffer
  294. memcpy(d->u.z,vp,byteCnt);
  295. // by default the system now takes responsibility for freeing this buffer
  296. d->flags |= kFreeValueDtFl;
  297. }
  298. else // the incoming string/blob pointer is simply being assigned w/o duplication
  299. {
  300. // free the objects previous value ...
  301. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  302. return rc;
  303. // and assign the new value (without reallocating the string)
  304. d->u.z = vp;
  305. d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,cmIsFlag(flags,kFreeValueDtFl));
  306. d->flags |= kNoCopyDtFl;
  307. }
  308. }
  309. break;
  310. default:
  311. break;
  312. }
  313. // we can't set this above because the string type relies
  314. // on knowing the previous type of the object
  315. d->cid = kScalarDtId;
  316. d->tid = tid;
  317. d->cnt = byteCnt;
  318. return rc;
  319. }
  320. cmDtRC_t cmDataSetNull( cmData_t* d )
  321. { return cmDataSetScalarValue(d, kNullDtId, NULL, 0, kNoFlagsDtFl ); }
  322. cmDtRC_t cmDataSetChar( cmData_t* d, char v )
  323. { return cmDataSetScalarValue(d, kCharDtId, &v, 0, kNoFlagsDtFl ); }
  324. cmDtRC_t cmDataSetUChar( cmData_t* d, unsigned char v )
  325. { return cmDataSetScalarValue(d, kUCharDtId, &v, 0, kNoFlagsDtFl ); }
  326. cmDtRC_t cmDataSetShort( cmData_t* d, short v )
  327. { return cmDataSetScalarValue(d, kShortDtId, &v, 0, kNoFlagsDtFl ); }
  328. cmDtRC_t cmDataSetUShort( cmData_t* d, unsigned short v )
  329. { return cmDataSetScalarValue(d, kUShortDtId, &v, 0, kNoFlagsDtFl ); }
  330. cmDtRC_t cmDataSetInt( cmData_t* d, int v )
  331. { return cmDataSetScalarValue(d, kIntDtId, &v, 0, kNoFlagsDtFl ); }
  332. cmDtRC_t cmDataSetUInt( cmData_t* d, unsigned int v )
  333. { return cmDataSetScalarValue(d, kUIntDtId, &v, 0, kNoFlagsDtFl ); }
  334. cmDtRC_t cmDataSetLong( cmData_t* d, long v )
  335. { return cmDataSetScalarValue(d, kLongDtId, &v, 0, kNoFlagsDtFl ); }
  336. cmDtRC_t cmDataSetULong( cmData_t* d, unsigned long v )
  337. { return cmDataSetScalarValue(d, kULongDtId, &v, 0, kNoFlagsDtFl ); }
  338. cmDtRC_t cmDataSetFloat( cmData_t* d, float v )
  339. { return cmDataSetScalarValue(d, kFloatDtId, &v, 0, kNoFlagsDtFl ); }
  340. cmDtRC_t cmDataSetDouble( cmData_t* d, double v )
  341. { return cmDataSetScalarValue(d, kDoubleDtId, &v, 0, kNoFlagsDtFl ); }
  342. cmDtRC_t cmDataSetStr( cmData_t* d, unsigned flags, cmChar_t* v )
  343. { return cmDataSetScalarValue(d, kStrDtId, v, v==NULL ? 1 : strlen(v)+1, flags ); }
  344. cmDtRC_t cmDataSetConstStr( cmData_t* d, unsigned flags, const cmChar_t* v )
  345. { return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : strlen(v)+1, flags |= kConstValueDtFl ); }
  346. cmDtRC_t cmDataSetStrN( cmData_t* d, unsigned flags, cmChar_t* v, unsigned charCnt )
  347. { return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : charCnt+1, flags); }
  348. cmDtRC_t cmDataSetConstStrN( cmData_t* d, unsigned flags, const cmChar_t* v, unsigned charCnt )
  349. { return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : charCnt+1, flags |= kConstValueDtFl); }
  350. cmDtRC_t cmDataSetBlob( cmData_t* d, unsigned flags, void* v, unsigned byteCnt )
  351. { return cmDataSetScalarValue(d, kBlobDtId, v, byteCnt, flags); }
  352. cmDtRC_t cmDataSetConstBlob( cmData_t* d, unsigned flags, const void* v, unsigned byteCnt )
  353. { return cmDataSetScalarValue(d, kBlobDtId, (void*)v, byteCnt, flags |= kConstValueDtFl); }
  354. cmDtRC_t cmDataChar( const cmData_t* d, char* v )
  355. {
  356. if( d->tid != kCharDtId )
  357. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:char but encountered type:%s.",cmDataTypeToLabel(d->tid));
  358. *v = d->u.c;
  359. return kOkDtRC;
  360. }
  361. cmDtRC_t cmDataUChar( const cmData_t* d, unsigned char* v )
  362. {
  363. if( d->tid != kUCharDtId )
  364. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:uchar but encountered type:%s.",cmDataTypeToLabel(d->tid));
  365. *v = d->u.uc;
  366. return kOkDtRC;
  367. }
  368. cmDtRC_t cmDataShort( const cmData_t* d, short* v )
  369. {
  370. if( d->tid != kShortDtId )
  371. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:short but encountered type:%s.",cmDataTypeToLabel(d->tid));
  372. *v = d->u.s;
  373. return kOkDtRC;
  374. }
  375. cmDtRC_t cmDataUShort( const cmData_t* d, unsigned short* v )
  376. {
  377. if( d->tid != kUShortDtId )
  378. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:ushort but encountered type:%s.",cmDataTypeToLabel(d->tid));
  379. *v = d->u.us;
  380. return kOkDtRC;
  381. }
  382. cmDtRC_t cmDataInt( const cmData_t* d, int* v )
  383. {
  384. if( d->tid != kIntDtId )
  385. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:int but encountered type:%s.",cmDataTypeToLabel(d->tid));
  386. *v = d->u.i;
  387. return kOkDtRC;
  388. }
  389. cmDtRC_t cmDataUInt( const cmData_t* d, unsigned int* v )
  390. {
  391. if( d->tid != kUIntDtId )
  392. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:uint but encountered type:%s.",cmDataTypeToLabel(d->tid));
  393. *v = d->u.ui;
  394. return kOkDtRC;
  395. }
  396. cmDtRC_t cmDataLong( const cmData_t* d, long* v )
  397. {
  398. if( d->tid != kLongDtId )
  399. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:long but encountered type:%s.",cmDataTypeToLabel(d->tid));
  400. *v = d->u.l;
  401. return kOkDtRC;
  402. }
  403. cmDtRC_t cmDataULong( const cmData_t* d, unsigned long* v )
  404. {
  405. if( d->tid != kULongDtId )
  406. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:ulong but encountered type:%s.",cmDataTypeToLabel(d->tid));
  407. *v = d->u.ul;
  408. return kOkDtRC;
  409. }
  410. cmDtRC_t cmDataFloat( const cmData_t* d, float* v )
  411. {
  412. if( d->tid != kFloatDtId )
  413. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:float but encountered type:%s.",cmDataTypeToLabel(d->tid));
  414. *v = d->u.f;
  415. return kOkDtRC;
  416. }
  417. cmDtRC_t cmDataDouble( const cmData_t* d, double* v )
  418. {
  419. if( d->tid != kDoubleDtId )
  420. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:double but encountered type:%s.",cmDataTypeToLabel(d->tid));
  421. *v = d->u.d;
  422. return kOkDtRC;
  423. }
  424. cmDtRC_t cmDataStr( const cmData_t* d, cmChar_t** v )
  425. {
  426. if( d->tid != kStrDtId )
  427. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  428. if( cmIsFlag(d->flags,kConstValueDtFl) )
  429. return _cmDtErrMsg(d,kConstErrDtRC,"A const string cannot return as a non-const string.");
  430. *v = d->u.z;
  431. return kOkDtRC;
  432. }
  433. cmDtRC_t cmDataConstStr( const cmData_t* d, const cmChar_t** v )
  434. {
  435. if( d->tid != kStrDtId )
  436. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  437. *v = d->u.z;
  438. return kOkDtRC;
  439. }
  440. cmDtRC_t cmDataBlob( const cmData_t* d, cmChar_t** v, unsigned* byteCntRef )
  441. {
  442. if( v != NULL )
  443. *v = NULL;
  444. if( byteCntRef != NULL )
  445. *byteCntRef = 0;
  446. if( d->tid != kBlobDtId )
  447. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  448. if( v != NULL )
  449. *v = d->u.z;
  450. if( byteCntRef != NULL )
  451. *byteCntRef = d->cnt;
  452. return kOkDtRC;
  453. }
  454. cmDtRC_t cmDataConstBlob( const cmData_t* d, const cmChar_t** v, unsigned* byteCntRef )
  455. {
  456. if( v != NULL )
  457. *v = NULL;
  458. if( byteCntRef != NULL )
  459. *byteCntRef = 0;
  460. if( d->tid != kBlobDtId )
  461. return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid));
  462. if( v != NULL )
  463. *v = d->u.z;
  464. if( byteCntRef != NULL )
  465. *byteCntRef = d->cnt;
  466. return kOkDtRC;
  467. }
  468. cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* vp )
  469. {
  470. if( p->cid != kScalarDtId )
  471. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  472. switch( p->tid )
  473. {
  474. case kUCharDtId: *vp = p->u.uc; break;
  475. case kCharDtId: *vp = (unsigned char)p->u.c; break;
  476. case kUShortDtId: *vp = (unsigned char)p->u.us; break;
  477. case kShortDtId: *vp = (unsigned char)p->u.s; break;
  478. case kUIntDtId: *vp = (unsigned char)p->u.ui; break;
  479. case kIntDtId: *vp = (unsigned char)p->u.i; break;
  480. case kULongDtId: *vp = (unsigned char)p->u.ul; break;
  481. case kLongDtId: *vp = (unsigned char)p->u.l; break;
  482. case kFloatDtId: *vp = (unsigned char)p->u.f; break;
  483. case kDoubleDtId: *vp = (unsigned char)p->u.d; break;
  484. default:
  485. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'uchar'.",cmDataTypeToLabel(p->tid));
  486. }
  487. return kOkDtRC;
  488. }
  489. cmDtRC_t cmDataGetChar( const cmData_t* p, char* vp )
  490. {
  491. if( p->cid != kScalarDtId )
  492. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  493. switch( p->tid )
  494. {
  495. case kUCharDtId: *vp = (char)p->u.uc; break;
  496. case kCharDtId: *vp = p->u.c; break;
  497. case kUShortDtId: *vp = (char)p->u.us; break;
  498. case kShortDtId: *vp = (char)p->u.s; break;
  499. case kUIntDtId: *vp = (char)p->u.ui; break;
  500. case kIntDtId: *vp = (char)p->u.i; break;
  501. case kULongDtId: *vp = (char)p->u.ul; break;
  502. case kLongDtId: *vp = (char)p->u.l; break;
  503. case kFloatDtId: *vp = (char)p->u.f; break;
  504. case kDoubleDtId: *vp = (char)p->u.d; break;
  505. default:
  506. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'char'.",cmDataTypeToLabel(p->tid));
  507. }
  508. return kOkDtRC;
  509. }
  510. cmDtRC_t cmDataGetShort( const cmData_t* p, short* vp )
  511. {
  512. if( p->cid != kScalarDtId )
  513. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  514. switch( p->tid )
  515. {
  516. case kUCharDtId: *vp = (short)p->u.uc; break;
  517. case kCharDtId: *vp = (short)p->u.c; break;
  518. case kUShortDtId: *vp = (short)p->u.us; break;
  519. case kShortDtId: *vp = p->u.s; break;
  520. case kUIntDtId: *vp = (short)p->u.ui; break;
  521. case kIntDtId: *vp = (short)p->u.i; break;
  522. case kULongDtId: *vp = (short)p->u.ul; break;
  523. case kLongDtId: *vp = (short)p->u.l; break;
  524. case kFloatDtId: *vp = (short)p->u.f; break;
  525. case kDoubleDtId: *vp = (short)p->u.d; break;
  526. default:
  527. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'short'.",cmDataTypeToLabel(p->tid));
  528. }
  529. return kOkDtRC;
  530. }
  531. cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* vp )
  532. {
  533. if( p->cid != kScalarDtId )
  534. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  535. switch( p->tid )
  536. {
  537. case kUCharDtId: *vp = (unsigned short)p->u.uc; break;
  538. case kCharDtId: *vp = (unsigned short)p->u.c; break;
  539. case kUShortDtId: *vp = p->u.us; break;
  540. case kShortDtId: *vp = (unsigned short)p->u.s; break;
  541. case kUIntDtId: *vp = (unsigned short)p->u.ui; break;
  542. case kIntDtId: *vp = (unsigned short)p->u.i; break;
  543. case kULongDtId: *vp = (unsigned short)p->u.ul; break;
  544. case kLongDtId: *vp = (unsigned short)p->u.l; break;
  545. case kFloatDtId: *vp = (unsigned short)p->u.f; break;
  546. case kDoubleDtId: *vp = (unsigned short)p->u.d; break;
  547. default:
  548. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'ushort'.",cmDataTypeToLabel(p->tid));
  549. }
  550. return kOkDtRC;
  551. }
  552. cmDtRC_t cmDataGetInt( const cmData_t* p, int* vp )
  553. {
  554. if( p->cid != kScalarDtId )
  555. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  556. switch( p->tid )
  557. {
  558. case kUCharDtId: *vp = (int)p->u.uc; break;
  559. case kCharDtId: *vp = (int)p->u.c; break;
  560. case kUShortDtId: *vp = (int)p->u.us; break;
  561. case kShortDtId: *vp = (int)p->u.s; break;
  562. case kUIntDtId: *vp = (int)p->u.ui; break;
  563. case kIntDtId: *vp = p->u.i; break;
  564. case kULongDtId: *vp = (int)p->u.ul; break;
  565. case kLongDtId: *vp = (int)p->u.l; break;
  566. case kFloatDtId: *vp = (int)p->u.f; break;
  567. case kDoubleDtId: *vp = (int)p->u.d; break;
  568. default:
  569. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'int'.",cmDataTypeToLabel(p->tid));
  570. }
  571. return kOkDtRC;
  572. }
  573. cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* vp )
  574. {
  575. if( p->cid != kScalarDtId )
  576. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  577. switch( p->tid )
  578. {
  579. case kUCharDtId: *vp = (unsigned int)p->u.uc; break;
  580. case kCharDtId: *vp = (unsigned int)p->u.c; break;
  581. case kUShortDtId: *vp = (unsigned int)p->u.us; break;
  582. case kShortDtId: *vp = (unsigned int)p->u.s; break;
  583. case kUIntDtId: *vp = p->u.ui; break;
  584. case kIntDtId: *vp = (unsigned int)p->u.i; break;
  585. case kULongDtId: *vp = (unsigned int)p->u.ul; break;
  586. case kLongDtId: *vp = (unsigned int)p->u.l; break;
  587. case kFloatDtId: *vp = (unsigned int)p->u.f; break;
  588. case kDoubleDtId: *vp = (unsigned int)p->u.d; break;
  589. default:
  590. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'uint'.",cmDataTypeToLabel(p->tid));
  591. }
  592. return kOkDtRC;
  593. }
  594. cmDtRC_t cmDataGetLong( const cmData_t* p, long* vp )
  595. {
  596. if( p->cid != kScalarDtId )
  597. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  598. switch( p->tid )
  599. {
  600. case kUCharDtId: *vp = (long)p->u.uc; break;
  601. case kCharDtId: *vp = (long)p->u.c; break;
  602. case kUShortDtId: *vp = (long)p->u.us; break;
  603. case kShortDtId: *vp = (long)p->u.s; break;
  604. case kUIntDtId: *vp = (long)p->u.ui; break;
  605. case kIntDtId: *vp = (long)p->u.i; break;
  606. case kULongDtId: *vp = (long)p->u.ul; break;
  607. case kLongDtId: *vp = p->u.l; break;
  608. case kFloatDtId: *vp = (long)p->u.f; break;
  609. case kDoubleDtId: *vp = (long)p->u.d; break;
  610. default:
  611. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'long'.",cmDataTypeToLabel(p->tid));
  612. }
  613. return kOkDtRC;
  614. }
  615. cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* vp )
  616. {
  617. if( p->cid != kScalarDtId )
  618. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  619. switch( p->tid )
  620. {
  621. case kUCharDtId: *vp = (unsigned long)p->u.uc; break;
  622. case kCharDtId: *vp = (unsigned long)p->u.c; break;
  623. case kUShortDtId: *vp = (unsigned long)p->u.us; break;
  624. case kShortDtId: *vp = (unsigned long)p->u.s; break;
  625. case kUIntDtId: *vp = (unsigned long)p->u.ui; break;
  626. case kIntDtId: *vp = (unsigned long)p->u.i; break;
  627. case kULongDtId: *vp = p->u.ul; break;
  628. case kLongDtId: *vp = (unsigned long)p->u.l; break;
  629. case kFloatDtId: *vp = (unsigned long)p->u.f; break;
  630. case kDoubleDtId: *vp = (unsigned long)p->u.d; break;
  631. default:
  632. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'ulong'.",cmDataTypeToLabel(p->tid));
  633. }
  634. return kOkDtRC;
  635. }
  636. cmDtRC_t cmDataGetFloat( const cmData_t* p, float* vp )
  637. {
  638. if( p->cid != kScalarDtId )
  639. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  640. switch( p->tid )
  641. {
  642. case kUCharDtId: *vp = (float)p->u.uc; break;
  643. case kCharDtId: *vp = (float)p->u.c; break;
  644. case kUShortDtId: *vp = (float)p->u.us; break;
  645. case kShortDtId: *vp = (float)p->u.s; break;
  646. case kUIntDtId: *vp = (float)p->u.ui; break;
  647. case kIntDtId: *vp = (float)p->u.i; break;
  648. case kULongDtId: *vp = (float)p->u.ul; break;
  649. case kLongDtId: *vp = (float)p->u.l; break;
  650. case kFloatDtId: *vp = p->u.f; break;
  651. case kDoubleDtId: *vp = (float)p->u.d; break;
  652. default:
  653. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'float'.",cmDataTypeToLabel(p->tid));
  654. }
  655. return kOkDtRC;
  656. }
  657. cmDtRC_t cmDataGetDouble( const cmData_t* p, double* vp )
  658. {
  659. if( p->cid != kScalarDtId )
  660. return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value.");
  661. switch( p->tid )
  662. {
  663. case kUCharDtId: *vp = (double)p->u.uc; break;
  664. case kCharDtId: *vp = (double)p->u.c; break;
  665. case kUShortDtId: *vp = (double)p->u.us; break;
  666. case kShortDtId: *vp = (double)p->u.s; break;
  667. case kUIntDtId: *vp = (double)p->u.ui; break;
  668. case kIntDtId: *vp = (double)p->u.i; break;
  669. case kULongDtId: *vp = (double)p->u.ul; break;
  670. case kLongDtId: *vp = (double)p->u.l; break;
  671. case kFloatDtId: *vp = (double)p->u.f; break;
  672. case kDoubleDtId: *vp = p->u.d; break;
  673. default:
  674. return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'double'.",cmDataTypeToLabel(p->tid));
  675. }
  676. return kOkDtRC;
  677. }
  678. cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref )
  679. {
  680. cmDtRC_t rc;
  681. cmData_t* d = NULL;
  682. *ref = NULL;
  683. // create a new 'null' object
  684. if((rc = _cmDataNew(parent, &d)) != kOkDtRC )
  685. return rc;
  686. // assign the value
  687. if((rc = cmDataSetArrayValue(d,tid,vp,eleCnt,flags)) != kOkDtRC )
  688. return rc;
  689. // set the flags for the new object
  690. d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl | kNoCopyDtFl));
  691. *ref = d;
  692. return rc;
  693. }
  694. cmDtRC_t cmDataNewCharArray( cmData_t* parent, char* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  695. { return cmDataNewArray(parent, kCharDtId, v, eleCnt, flags, ref ); }
  696. cmDtRC_t cmDataNewUCharArray( cmData_t* parent, unsigned char* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  697. { return cmDataNewArray(parent, kUCharDtId, v, eleCnt, flags, ref ); }
  698. cmDtRC_t cmDataNewShortArray( cmData_t* parent, short* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  699. { return cmDataNewArray(parent, kShortDtId, v, eleCnt, flags, ref ); }
  700. cmDtRC_t cmDataNewUShortArray( cmData_t* parent, unsigned short* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  701. { return cmDataNewArray(parent, kUShortDtId, v, eleCnt, flags, ref ); }
  702. cmDtRC_t cmDataNewIntArray( cmData_t* parent, int* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  703. { return cmDataNewArray(parent, kIntDtId, v, eleCnt, flags, ref ); }
  704. cmDtRC_t cmDataNewUIntArray( cmData_t* parent, unsigned int* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  705. { return cmDataNewArray(parent, kUIntDtId, v, eleCnt, flags, ref ); }
  706. cmDtRC_t cmDataNewLongArray( cmData_t* parent, long* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  707. { return cmDataNewArray(parent, kLongDtId, v, eleCnt, flags, ref ); }
  708. cmDtRC_t cmDataNewULongArray( cmData_t* parent, unsigned long* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  709. { return cmDataNewArray(parent, kULongDtId, v, eleCnt, flags, ref ); }
  710. cmDtRC_t cmDataNewFloatArray( cmData_t* parent, float* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  711. { return cmDataNewArray(parent, kFloatDtId, v, eleCnt, flags, ref ); }
  712. cmDtRC_t cmDataNewDoubleArray( cmData_t* parent, double* v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  713. { return cmDataNewArray(parent, kDoubleDtId, v, eleCnt, flags, ref ); }
  714. cmDtRC_t cmDataNewStrArray( cmData_t* parent, cmChar_t** v, unsigned eleCnt, unsigned flags, cmData_t** ref )
  715. { return cmDataNewArray(parent, kStrDtId, v, eleCnt, flags, ref ); }
  716. cmDtRC_t cmDataNewConstStrArray( cmData_t* parent, const cmChar_t** v,unsigned eleCnt, unsigned flags, cmData_t** ref )
  717. { return cmDataNewArray(parent, kStrDtId, (cmChar_t**)v, eleCnt, flags, ref ); }
  718. cmDtRC_t cmDataSetArrayValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags )
  719. {
  720. cmDtRC_t rc = kOkDtRC;
  721. // if the type of the object is changing
  722. if( d->tid != tid || d->cid != kScalarDtId )
  723. {
  724. // verify that it is legal to change the type of the object
  725. if( cmIsFlag(d->flags,kConstObjDtFl) )
  726. return _cmDtErrMsg(d,kConstErrDtRC,"Const object violation.");
  727. // convert this to a scalar null object.
  728. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  729. return rc;
  730. }
  731. // verify that it is legal to change the value of this object
  732. if( cmIsFlag(d->flags,kConstValueDtFl) )
  733. return _cmDtErrMsg(d,kConstErrDtRC,"Const value violation.");
  734. // if the array should be reallocated
  735. if( cmIsNotFlag(flags,kNoCopyDtFl) )
  736. {
  737. unsigned byteCnt = cmDataByteWidth(tid) * eleCnt;
  738. // reallocate a new string
  739. if( d->cid == kArrayDtId && cmIsFlag(d->flags,kFreeValueDtFl) )
  740. d->u.vp = cmMemResize(char,d->u.z,byteCnt);
  741. else
  742. d->u.vp = cmMemAlloc(char,byteCnt);
  743. memcpy(d->u.z,vp,byteCnt);
  744. d->flags |= kFreeValueDtFl;
  745. }
  746. else
  747. {
  748. // free the previous value ...
  749. if((rc = _cmDataFreeData(d)) != kOkDtRC )
  750. return rc;
  751. // and assign the new value (without reallocating the array)
  752. d->u.vp = vp;
  753. d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,cmIsFlag(flags,kFreeValueDtFl));
  754. }
  755. // we can't set this above because the string type relies
  756. // on knowing the previous type of the object
  757. d->cid = kArrayDtId;
  758. d->tid = tid;
  759. d->cnt = eleCnt;
  760. return rc;
  761. }
  762. cmDtRC_t cmDataSetCharArray( cmData_t* d, char* v, unsigned eleCnt, unsigned flags )
  763. { return cmDataSetArrayValue(d, kCharDtId, v, eleCnt, flags ); }
  764. cmDtRC_t cmDataSetUCharArray( cmData_t* d, unsigned char* v, unsigned eleCnt, unsigned flags )
  765. { return cmDataSetArrayValue(d, kUCharDtId, v, eleCnt, flags ); }
  766. cmDtRC_t cmDataSetShortArray( cmData_t* d, short* v, unsigned eleCnt, unsigned flags )
  767. { return cmDataSetArrayValue(d, kShortDtId, v, eleCnt, flags ); }
  768. cmDtRC_t cmDataSetUShortArray( cmData_t* d, unsigned short* v, unsigned eleCnt, unsigned flags )
  769. { return cmDataSetArrayValue(d, kUShortDtId, v, eleCnt, flags ); }
  770. cmDtRC_t cmDataSetIntArray( cmData_t* d, int* v, unsigned eleCnt, unsigned flags )
  771. { return cmDataSetArrayValue(d, kIntDtId, v, eleCnt, flags ); }
  772. cmDtRC_t cmDataSetUIntArray( cmData_t* d, unsigned int* v, unsigned eleCnt, unsigned flags )
  773. { return cmDataSetArrayValue(d, kUIntDtId, v, eleCnt, flags ); }
  774. cmDtRC_t cmDataSetLongArray( cmData_t* d, long* v, unsigned eleCnt, unsigned flags )
  775. { return cmDataSetArrayValue(d, kLongDtId, v, eleCnt, flags ); }
  776. cmDtRC_t cmDataSetULongArray( cmData_t* d, unsigned long* v, unsigned eleCnt, unsigned flags )
  777. { return cmDataSetArrayValue(d, kULongDtId, v, eleCnt, flags ); }
  778. cmDtRC_t cmDataSetFloatArray( cmData_t* d, float* v, unsigned eleCnt, unsigned flags )
  779. { return cmDataSetArrayValue(d, kFloatDtId, v, eleCnt, flags ); }
  780. cmDtRC_t cmDataSetDoubleArray( cmData_t* d, double* v, unsigned eleCnt, unsigned flags )
  781. { return cmDataSetArrayValue(d, kDoubleDtId, v, eleCnt, flags ); }
  782. cmDtRC_t cmDataSetStrArray( cmData_t* d, cmChar_t** v, unsigned eleCnt, unsigned flags )
  783. { return cmDataSetArrayValue(d, kStrDtId, v, eleCnt, flags ); }
  784. cmDtRC_t cmDataSetConstStrArray(cmData_t* d,const cmChar_t** v,unsigned eleCnt, unsigned flags )
  785. { return cmDataSetArrayValue(d, kStrDtId, (cmChar_t**)v, eleCnt, flags ); }
  786. unsigned cmDataArrayEleCount( const cmData_t* d )
  787. { return d->cid==kArrayDtId ? d->cnt : 0; }
  788. cmDtRC_t cmDataCharArray( const cmData_t* d, char** v )
  789. {
  790. if( d->cid != kArrayDtId )
  791. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  792. *v = (char*)d->u.vp;
  793. return kOkDtRC;
  794. }
  795. cmDtRC_t cmDataUCharArray( const cmData_t* d, unsigned char** v )
  796. {
  797. if( d->cid != kArrayDtId )
  798. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  799. *v = (unsigned char*)d->u.vp;
  800. return kOkDtRC;
  801. }
  802. cmDtRC_t cmDataShortArray( const cmData_t* d, short** v )
  803. {
  804. if( d->cid != kArrayDtId )
  805. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  806. *v = (short*)d->u.vp;
  807. return kOkDtRC;
  808. }
  809. cmDtRC_t cmDataUShortArray( const cmData_t* d, unsigned short** v )
  810. {
  811. if( d->cid != kArrayDtId )
  812. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  813. *v = (unsigned short*)d->u.vp;
  814. return kOkDtRC;
  815. }
  816. cmDtRC_t cmDataIntArray( const cmData_t* d, int** v )
  817. {
  818. if( d->cid != kArrayDtId )
  819. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  820. *v = (int*)d->u.vp;
  821. return kOkDtRC;
  822. }
  823. cmDtRC_t cmDataUIntArray( const cmData_t* d, unsigned int** v )
  824. {
  825. if( d->cid != kArrayDtId )
  826. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  827. *v = (unsigned int*)d->u.vp;
  828. return kOkDtRC;
  829. }
  830. cmDtRC_t cmDataLongArray( const cmData_t* d, long** v )
  831. {
  832. if( d->cid != kArrayDtId )
  833. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  834. *v = (long*)d->u.vp;
  835. return kOkDtRC;
  836. }
  837. cmDtRC_t cmDataULongArray( const cmData_t* d, unsigned long** v )
  838. {
  839. if( d->cid != kArrayDtId )
  840. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  841. *v = (unsigned long*)d->u.vp;
  842. return kOkDtRC;
  843. }
  844. cmDtRC_t cmDataFloatArray( const cmData_t* d, float** v )
  845. {
  846. if( d->cid != kArrayDtId )
  847. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  848. *v = (float*)d->u.vp;
  849. return kOkDtRC;
  850. }
  851. cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v )
  852. {
  853. if( d->cid != kArrayDtId )
  854. return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid));
  855. *v = (double*)d->u.vp;
  856. return kOkDtRC;
  857. }
  858. cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v )
  859. {
  860. }
  861. cmDtRC_t cmDataConstStrArray( const cmData_t* d, const cmChar_t*** v )
  862. {
  863. }
  864. //----------------------------------------------------------------------------
  865. // Structure related functions
  866. //
  867. void cmDataFree( cmData_t* p )
  868. {
  869. _cmDataFree(p);
  870. }
  871. cmData_t* cmDataUnlink( cmData_t* p )
  872. {
  873. if( p->parent == NULL )
  874. return p;
  875. assert( cmDataIsStruct(p->parent) );
  876. cmData_t* cp = p->u.child;
  877. cmData_t* pp = NULL;
  878. for(; cp!=NULL; cp=cp->sibling)
  879. if( cp == p )
  880. {
  881. if( pp == NULL )
  882. p->parent->u.child = p->sibling;
  883. else
  884. pp->sibling = cp->sibling;
  885. }
  886. return p;
  887. }
  888. void cmDataUnlinkAndFree( cmData_t* p )
  889. {
  890. cmDataUnlink(p);
  891. cmDataFree(p);
  892. }
  893. cmDtRC_t _cmDataDupl( const cmData_t* d, cmData_t* parent, cmData_t** ref )
  894. {
  895. cmData_t* rp = NULL;
  896. *ref = NULL;
  897. switch( d->cid )
  898. {
  899. case kScalarDtId:
  900. if( d->tid == kBlobDtId || d->tid == kStrDtId )
  901. rc = cmDataNewScalar(parent, d->tid, d->flags, d->u.vp, d->cnt, &rp );
  902. else
  903. rc = cmDataNewScalar(parent, d->tid, d->flags, d->u.vp, 0, &rp );
  904. break;
  905. case kArrayDtId:
  906. rc = cmDataNewArray(parent, d->tid, d->u.vp, d->cnt, d->flags, &rp );
  907. break;
  908. case kListDtId:
  909. case kPairDtId:
  910. case kRecordDtId:
  911. {
  912. rp = _cmDataAllocNode(parent,d->tid);
  913. cmData_t* cp = d->u.child;
  914. for(; cp!=NULL; cp=cd->sibling)
  915. cmDataAppendChild(rp,_cmDataDupl(cp,rp));
  916. }
  917. break;
  918. default:
  919. assert(0);
  920. break;
  921. }
  922. if( rp != NULL )
  923. *ref = rp;
  924. return rc;
  925. /*
  926. cmData_t* rp = NULL;
  927. switch( p->tid )
  928. {
  929. case kNullDtId: rp = cmDataAllocNull(parent); break;
  930. case kUCharDtId: rp = cmDataAllocUChar(parent,p->u.uc); break;
  931. case kCharDtId: rp = cmDataAllocChar(parent,p->u.c); break;
  932. case kUShortDtId: rp = cmDataAllocShort(parent,p->u.us); break;
  933. case kShortDtId: rp = cmDataAllocUShort(parent,p->u.s); break;
  934. case kUIntDtId: rp = cmDataAllocUInt(parent,p->u.i); break;
  935. case kIntDtId: rp = cmDataAllocInt(parent,p->u.ui); break;
  936. case kULongDtId: rp = cmDataAllocULong(parent,p->u.ul); break;
  937. case kLongDtId: rp = cmDataAllocLong(parent,p->u.l); break;
  938. case kFloatDtId: rp = cmDataAllocFloat(parent,p->u.f); break;
  939. case kDoubleDtId: rp = cmDataAllocDouble(parent,p->u.d); break;
  940. case kStrDtId: rp = cmDataStrAlloc(parent,p->u.z); break;
  941. case kConstStrDtId: rp = cmDataConstStrAlloc(parent,p->u.cz); break;
  942. case kUCharPtrDtId: rp = cmDataUCharAllocPtr(parent,p->u.ucp,p->cnt); break;
  943. case kCharPtrDtId: rp = cmDataCharAllocPtr(parent,p->u.cp,p->cnt); break;
  944. case kUShortPtrDtId: rp = cmDataUShortAllocPtr(parent,p->u.usp,p->cnt); break;
  945. case kShortPtrDtId: rp = cmDataShortAllocPtr(parent,p->u.sp,p->cnt); break;
  946. case kUIntPtrDtId: rp = cmDataUIntAllocPtr(parent,p->u.uip,p->cnt); break;
  947. case kIntPtrDtId: rp = cmDataIntAllocPtr(parent,p->u.ip,p->cnt); break;
  948. case kULongPtrDtId: rp = cmDataULongAllocPtr(parent,p->u.ulp,p->cnt); break;
  949. case kLongPtrDtId: rp = cmDataLongAllocPtr(parent,p->u.lp,p->cnt); break;
  950. case kFloatPtrDtId: rp = cmDataFloatAllocPtr(parent,p->u.fp,p->cnt); break;
  951. case kDoublePtrDtId: rp = cmDataDoubleAllocPtr(parent,p->u.dp,p->cnt); break;
  952. case kVoidPtrDtId: rp = cmDataVoidAllocPtr(parent,p->u.vp,p->cnt); break;
  953. case kListDtId:
  954. case kPairDtId:
  955. case kRecordDtId:
  956. {
  957. rp = _cmDataAllocNode(parent,p->tid);
  958. cmData_t* cp = p->u.child;
  959. for(; cp!=NULL; cp=cp->sibling)
  960. cmDataAppendChild(rp,_cmDataDupl(cp,rp));
  961. }
  962. break;
  963. default:
  964. assert(0);
  965. }
  966. return rp;
  967. */
  968. }
  969. cmData_t* cmDataDupl( const cmData_t* p )
  970. { return _cmDataDupl(p,NULL); }
  971. cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src )
  972. {
  973. if( dst->parent == NULL )
  974. {
  975. cmDataUnlinkAndFree(dst);
  976. src->parent = NULL;
  977. return src;
  978. }
  979. cmData_t* parent = dst->parent;
  980. cmData_t* cp = parent->u.child;
  981. cmData_t* pp = NULL;
  982. unsigned i = 0;
  983. unsigned n = cmDataChildCount(parent);
  984. // locate dst's right sibling
  985. for(i=0; i<n; ++i,cp=cp->sibling)
  986. {
  987. if( cp == dst )
  988. {
  989. // link in 'src' in place of 'dst'
  990. src->sibling = dst->sibling;
  991. // free dst
  992. cmDataUnlinkAndFree(dst);
  993. // update the sibling link to
  994. if( pp == NULL )
  995. parent->u.child = src;
  996. else
  997. pp->sibling = src;
  998. src->parent = parent;
  999. break;
  1000. }
  1001. pp = cp;
  1002. }
  1003. return src;
  1004. }
  1005. unsigned cmDataChildCount( const cmData_t* p )
  1006. {
  1007. if( !cmDataIsStruct(p) )
  1008. return 0;
  1009. unsigned n = 0;
  1010. const cmData_t* cp = p->u.child;
  1011. for(; cp!=NULL; cp=cp->sibling)
  1012. ++n;
  1013. return n;
  1014. }
  1015. cmData_t* cmDataChild( cmData_t* p, unsigned index )
  1016. {
  1017. if( !cmDataIsStruct(p) )
  1018. return NULL;
  1019. unsigned n = 0;
  1020. cmData_t* cp = p->u.child;
  1021. for(; cp!=NULL; cp=cp->sibling)
  1022. {
  1023. if( n == index )
  1024. break;
  1025. ++n;
  1026. }
  1027. return cp;
  1028. }
  1029. cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p )
  1030. {
  1031. assert( cmDataIsStruct(p) );
  1032. cmDataUnlink(p);
  1033. p->u.child = parent->u.child;
  1034. parent->u.child = p;
  1035. p->parent = parent;
  1036. return p;
  1037. }
  1038. cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p )
  1039. {
  1040. assert( cmDataIsStruct(parent) );
  1041. assert( parent->cid != kRecordDtId || (parent->cid == kRecordDtId && p->cid==kPairDtId));
  1042. cmDataUnlink(p);
  1043. cmData_t* cp = parent->u.child;
  1044. if( cp == NULL )
  1045. parent->u.child = p;
  1046. else
  1047. {
  1048. for(; cp!=NULL; cp=cp->sibling)
  1049. if( cp->sibling == NULL )
  1050. {
  1051. cp->sibling = p;
  1052. break;
  1053. }
  1054. }
  1055. p->parent = parent;
  1056. p->sibling = NULL;
  1057. return p;
  1058. }
  1059. cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p )
  1060. {
  1061. if( !cmDataIsStruct(parent) )
  1062. return NULL;
  1063. cmDataUnlink(p);
  1064. unsigned n = 0;
  1065. cmData_t* cp = parent->u.child;
  1066. cmData_t* pp = NULL;
  1067. for(; cp!=NULL; cp=cp->sibling)
  1068. {
  1069. if( n == index )
  1070. {
  1071. if( pp == NULL )
  1072. {
  1073. parent->u.child = p;
  1074. p->sibling = NULL;
  1075. }
  1076. else
  1077. {
  1078. p->sibling = pp->sibling;
  1079. pp->sibling = p;
  1080. }
  1081. break;
  1082. }
  1083. ++n;
  1084. }
  1085. p->parent = parent;
  1086. return p;
  1087. }
  1088. void cmDataTest( cmCtx_t* ctx )
  1089. {
  1090. }
  1091. ////////////////////////////////////////////////////////////////////////////////////////////////
  1092. ////////////////////////////////////////////////////////////////////////////////////////////////
  1093. ////////////////////////////////////////////////////////////////////////////////////////////////
  1094. ////////////////////////////////////////////////////////////////////////////////////////////////
  1095. #ifdef NOT_DEF
  1096. cmDtRC_t _cmDataErrNo = kOkDtRC;
  1097. cmData_t cmDataNull = { kInvalidDtId,0,NULL,NULL,0 };
  1098. cmDtRC_t _cmDataSetError( unsigned err )
  1099. {
  1100. _cmDataErrNo = err;
  1101. return err;
  1102. }
  1103. void _cmDataFreeArray( cmData_t* p )
  1104. {
  1105. if(cmIsFlag(p->flags,kDynPtrDtFl))
  1106. {
  1107. cmMemFree(p->u.vp);
  1108. p->u.vp = NULL;
  1109. p->flags = cmClrFlag(p->flags,kDynPtrDtFl);
  1110. }
  1111. p->tid = kInvalidDtId;
  1112. p->cnt = 0;
  1113. }
  1114. void _cmDataFree( cmData_t* p )
  1115. {
  1116. if( p == NULL )
  1117. return;
  1118. if( cmDataIsStruct(p) )
  1119. {
  1120. cmData_t* cp = p->u.child;
  1121. for(; cp!=NULL; cp=cp->sibling)
  1122. _cmDataFree(cp);
  1123. }
  1124. _cmDataFreeArray(p);
  1125. if( cmIsFlag(p->flags,kDynObjDtFl) )
  1126. cmMemFree(p);
  1127. }
  1128. cmData_t* _cmDataAllocNode( cmData_t* parent, cmDataFmtId_t tid )
  1129. {
  1130. cmData_t* p = cmMemAllocZ(cmData_t,1);
  1131. p->tid = tid;
  1132. p->flags = kDynObjDtFl;
  1133. p->parent = parent;
  1134. if( parent != NULL )
  1135. return cmDataAppendChild(parent,p);
  1136. return p;
  1137. }
  1138. unsigned _cmDataByteCount( const cmData_t* p )
  1139. {
  1140. unsigned n = 0;
  1141. switch( p->tid )
  1142. {
  1143. case kInvalidDtId: return 0;
  1144. case kNullDtId: return n;
  1145. case kUCharDtId: return n + sizeof(unsigned char);
  1146. case kCharDtId: return n + sizeof(char);
  1147. case kUShortDtId: return n + sizeof(unsigned short);
  1148. case kShortDtId: return n + sizeof(short);
  1149. case kUIntDtId: return n + sizeof(unsigned int);
  1150. case kIntDtId: return n + sizeof(int);
  1151. case kULongDtId: return n + sizeof(unsigned long);
  1152. case kLongDtId: return n + sizeof(long);
  1153. case kFloatDtId: return n + sizeof(float);
  1154. case kDoubleDtId: return n + sizeof(double);
  1155. case kStrDtId: return n + (p->u.z ==NULL ? 0 : strlen(p->u.z) + 1);
  1156. case kConstStrDtId: return n + (p->u.cz==NULL ? 0 : strlen(p->u.cz) + 1);
  1157. case kUCharPtrDtId: return n + p->cnt * sizeof(unsigned char);
  1158. case kCharPtrDtId: return n + p->cnt * sizeof(char);
  1159. case kUShortPtrDtId: return n + p->cnt * sizeof(unsigned short);
  1160. case kShortPtrDtId: return n + p->cnt * sizeof(short);
  1161. case kUIntPtrDtId: return n + p->cnt * sizeof(unsigned int);
  1162. case kIntPtrDtId: return n + p->cnt * sizeof(int);
  1163. case kULongPtrDtId: return n + p->cnt * sizeof(unsigned long);
  1164. case kLongPtrDtId: return n + p->cnt * sizeof(long);
  1165. case kFloatPtrDtId: return n + p->cnt * sizeof(float);
  1166. case kDoublePtrDtId: return n + p->cnt * sizeof(double);
  1167. case kVoidPtrDtId: return n + p->cnt * sizeof(char);
  1168. default:
  1169. return n;
  1170. }
  1171. assert(0);
  1172. return 0;
  1173. }
  1174. bool cmDataIsValue( const cmData_t* p )
  1175. { return kMinValDtId <= p->tid && p->tid <= kMaxValDtId; }
  1176. bool cmDataIsPtr( const cmData_t* p )
  1177. { return kMinPtrDtId <= p->tid && p->tid <= kMaxPtrDtId; }
  1178. bool cmDataIsStruct( const cmData_t* p )
  1179. { return kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId; }
  1180. char cmDataChar( const cmData_t* p ) { assert(p->tid==kCharDtId); return p->u.c; }
  1181. unsigned char cmDataUChar( const cmData_t* p ) { assert(p->tid==kUCharDtId); return p->u.uc; }
  1182. short cmDataShort( const cmData_t* p ) { assert(p->tid==kShortDtId); return p->u.s; }
  1183. unsigned short cmDataUShort( const cmData_t* p ) { assert(p->tid==kUShortDtId); return p->u.us; }
  1184. int cmDataInt( const cmData_t* p ) { assert(p->tid==kIntDtId); return p->u.i; }
  1185. unsigned int cmDataUInt( const cmData_t* p ) { assert(p->tid==kUIntDtId); return p->u.ui; }
  1186. long cmDataLong( const cmData_t* p ) { assert(p->tid==kLongDtId); return p->u.l; }
  1187. unsigned long cmDataULong( const cmData_t* p ) { assert(p->tid==kULongDtId); return p->u.ul; }
  1188. float cmDataFloat( const cmData_t* p ) { assert(p->tid==kFloatDtId); return p->u.f; }
  1189. double cmDataDouble( const cmData_t* p ) { assert(p->tid==kDoubleDtId); return p->u.d; }
  1190. cmChar_t* cmDataStr( const cmData_t* p ) { assert(p->tid==kStrDtId); return p->u.z; }
  1191. const cmChar_t* cmDataConstStr( const cmData_t* p ) { assert(p->tid==kConstStrDtId); return p->u.cz; }
  1192. void* cmDataVoidPtr( const cmData_t* p ) { assert(p->tid==kVoidPtrDtId); return p->u.vp; }
  1193. char* cmDataCharPtr( const cmData_t* p ) { assert(p->tid==kCharPtrDtId); return p->u.cp; }
  1194. unsigned char* cmDataUCharPtr( const cmData_t* p ) { assert(p->tid==kUCharPtrDtId); return p->u.ucp; }
  1195. short* cmDataShortPtr( const cmData_t* p ) { assert(p->tid==kShortPtrDtId); return p->u.sp; }
  1196. unsigned short* cmDataUShortPtr( const cmData_t* p ) { assert(p->tid==kUShortPtrDtId); return p->u.usp; }
  1197. int* cmDataIntPtr( const cmData_t* p ) { assert(p->tid==kIntPtrDtId); return p->u.ip; }
  1198. unsigned int* cmDataUIntPtr( const cmData_t* p ) { assert(p->tid==kUIntPtrDtId); return p->u.uip; }
  1199. long* cmDataLongPtr( const cmData_t* p ) { assert(p->tid==kLongPtrDtId); return p->u.lp; }
  1200. unsigned long* cmDataULongPtr( const cmData_t* p ) { assert(p->tid==kULongPtrDtId); return p->u.ulp; }
  1201. float* cmDataFloatPtr( const cmData_t* p ) { assert(p->tid==kFloatPtrDtId); return p->u.fp; }
  1202. double* cmDataDoublePtr( const cmData_t* p ) { assert(p->tid==kDoublePtrDtId); return p->u.dp; }
  1203. cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* vp )
  1204. {
  1205. switch( p->tid )
  1206. {
  1207. case kUCharDtId: *vp = p->u.uc; break;
  1208. case kCharDtId: *vp = (unsigned char)p->u.c; break;
  1209. case kUShortDtId: *vp = (unsigned char)p->u.us; break;
  1210. case kShortDtId: *vp = (unsigned char)p->u.s; break;
  1211. case kUIntDtId: *vp = (unsigned char)p->u.ui; break;
  1212. case kIntDtId: *vp = (unsigned char)p->u.i; break;
  1213. case kULongDtId: *vp = (unsigned char)p->u.ul; break;
  1214. case kLongDtId: *vp = (unsigned char)p->u.l; break;
  1215. case kFloatDtId: *vp = (unsigned char)p->u.f; break;
  1216. case kDoubleDtId: *vp = (unsigned char)p->u.d; break;
  1217. default:
  1218. return _cmDataSetError(kCvtErrDtRC);
  1219. }
  1220. return kOkDtRC;
  1221. }
  1222. cmDtRC_t cmDataGetChar( const cmData_t* p, char* vp )
  1223. {
  1224. switch( p->tid )
  1225. {
  1226. case kUCharDtId: *vp = (char)p->u.uc; break;
  1227. case kCharDtId: *vp = p->u.c; break;
  1228. case kUShortDtId: *vp = (char)p->u.us; break;
  1229. case kShortDtId: *vp = (char)p->u.s; break;
  1230. case kUIntDtId: *vp = (char)p->u.ui; break;
  1231. case kIntDtId: *vp = (char)p->u.i; break;
  1232. case kULongDtId: *vp = (char)p->u.ul; break;
  1233. case kLongDtId: *vp = (char)p->u.l; break;
  1234. case kFloatDtId: *vp = (char)p->u.f; break;
  1235. case kDoubleDtId: *vp = (char)p->u.d; break;
  1236. default:
  1237. return _cmDataSetError(kCvtErrDtRC);
  1238. }
  1239. return kOkDtRC;
  1240. }
  1241. cmDtRC_t cmDataGetShort( const cmData_t* p, short* vp )
  1242. {
  1243. switch( p->tid )
  1244. {
  1245. case kUCharDtId: *vp = (short)p->u.uc; break;
  1246. case kCharDtId: *vp = (short)p->u.c; break;
  1247. case kUShortDtId: *vp = (short)p->u.us; break;
  1248. case kShortDtId: *vp = p->u.s; break;
  1249. case kUIntDtId: *vp = (short)p->u.ui; break;
  1250. case kIntDtId: *vp = (short)p->u.i; break;
  1251. case kULongDtId: *vp = (short)p->u.ul; break;
  1252. case kLongDtId: *vp = (short)p->u.l; break;
  1253. case kFloatDtId: *vp = (short)p->u.f; break;
  1254. case kDoubleDtId: *vp = (short)p->u.d; break;
  1255. default:
  1256. return _cmDataSetError(kCvtErrDtRC);
  1257. }
  1258. return kOkDtRC;
  1259. }
  1260. cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* vp )
  1261. {
  1262. switch( p->tid )
  1263. {
  1264. case kUCharDtId: *vp = (unsigned short)p->u.uc; break;
  1265. case kCharDtId: *vp = (unsigned short)p->u.c; break;
  1266. case kUShortDtId: *vp = p->u.us; break;
  1267. case kShortDtId: *vp = (unsigned short)p->u.s; break;
  1268. case kUIntDtId: *vp = (unsigned short)p->u.ui; break;
  1269. case kIntDtId: *vp = (unsigned short)p->u.i; break;
  1270. case kULongDtId: *vp = (unsigned short)p->u.ul; break;
  1271. case kLongDtId: *vp = (unsigned short)p->u.l; break;
  1272. case kFloatDtId: *vp = (unsigned short)p->u.f; break;
  1273. case kDoubleDtId: *vp = (unsigned short)p->u.d; break;
  1274. default:
  1275. return _cmDataSetError(kCvtErrDtRC);
  1276. }
  1277. return kOkDtRC;
  1278. }
  1279. cmDtRC_t cmDataGetInt( const cmData_t* p, int* vp )
  1280. {
  1281. switch( p->tid )
  1282. {
  1283. case kUCharDtId: *vp = (int)p->u.uc; break;
  1284. case kCharDtId: *vp = (int)p->u.c; break;
  1285. case kUShortDtId: *vp = (int)p->u.us; break;
  1286. case kShortDtId: *vp = (int)p->u.s; break;
  1287. case kUIntDtId: *vp = (int)p->u.ui; break;
  1288. case kIntDtId: *vp = p->u.i; break;
  1289. case kULongDtId: *vp = (int)p->u.ul; break;
  1290. case kLongDtId: *vp = (int)p->u.l; break;
  1291. case kFloatDtId: *vp = (int)p->u.f; break;
  1292. case kDoubleDtId: *vp = (int)p->u.d; break;
  1293. default:
  1294. return _cmDataSetError(kCvtErrDtRC);
  1295. }
  1296. return kOkDtRC;
  1297. }
  1298. cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* vp )
  1299. {
  1300. switch( p->tid )
  1301. {
  1302. case kUCharDtId: *vp = (unsigned int)p->u.uc; break;
  1303. case kCharDtId: *vp = (unsigned int)p->u.c; break;
  1304. case kUShortDtId: *vp = (unsigned int)p->u.us; break;
  1305. case kShortDtId: *vp = (unsigned int)p->u.s; break;
  1306. case kUIntDtId: *vp = p->u.ui; break;
  1307. case kIntDtId: *vp = (unsigned int)p->u.i; break;
  1308. case kULongDtId: *vp = (unsigned int)p->u.ul; break;
  1309. case kLongDtId: *vp = (unsigned int)p->u.l; break;
  1310. case kFloatDtId: *vp = (unsigned int)p->u.f; break;
  1311. case kDoubleDtId: *vp = (unsigned int)p->u.d; break;
  1312. default:
  1313. return _cmDataSetError(kCvtErrDtRC);
  1314. }
  1315. return kOkDtRC;
  1316. }
  1317. cmDtRC_t cmDataGetLong( const cmData_t* p, long* vp )
  1318. {
  1319. switch( p->tid )
  1320. {
  1321. case kUCharDtId: *vp = (long)p->u.uc; break;
  1322. case kCharDtId: *vp = (long)p->u.c; break;
  1323. case kUShortDtId: *vp = (long)p->u.us; break;
  1324. case kShortDtId: *vp = (long)p->u.s; break;
  1325. case kUIntDtId: *vp = (long)p->u.ui; break;
  1326. case kIntDtId: *vp = (long)p->u.i; break;
  1327. case kULongDtId: *vp = (long)p->u.ul; break;
  1328. case kLongDtId: *vp = p->u.l; break;
  1329. case kFloatDtId: *vp = (long)p->u.f; break;
  1330. case kDoubleDtId: *vp = (long)p->u.d; break;
  1331. default:
  1332. return _cmDataSetError(kCvtErrDtRC);
  1333. }
  1334. return kOkDtRC;
  1335. }
  1336. cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* vp )
  1337. {
  1338. switch( p->tid )
  1339. {
  1340. case kUCharDtId: *vp = (unsigned long)p->u.uc; break;
  1341. case kCharDtId: *vp = (unsigned long)p->u.c; break;
  1342. case kUShortDtId: *vp = (unsigned long)p->u.us; break;
  1343. case kShortDtId: *vp = (unsigned long)p->u.s; break;
  1344. case kUIntDtId: *vp = (unsigned long)p->u.ui; break;
  1345. case kIntDtId: *vp = (unsigned long)p->u.i; break;
  1346. case kULongDtId: *vp = p->u.ul; break;
  1347. case kLongDtId: *vp = (unsigned long)p->u.l; break;
  1348. case kFloatDtId: *vp = (unsigned long)p->u.f; break;
  1349. case kDoubleDtId: *vp = (unsigned long)p->u.d; break;
  1350. default:
  1351. return _cmDataSetError(kCvtErrDtRC);
  1352. }
  1353. return kOkDtRC;
  1354. }
  1355. cmDtRC_t cmDataGetFloat( const cmData_t* p, float* vp )
  1356. {
  1357. switch( p->tid )
  1358. {
  1359. case kUCharDtId: *vp = (float)p->u.uc; break;
  1360. case kCharDtId: *vp = (float)p->u.c; break;
  1361. case kUShortDtId: *vp = (float)p->u.us; break;
  1362. case kShortDtId: *vp = (float)p->u.s; break;
  1363. case kUIntDtId: *vp = (float)p->u.ui; break;
  1364. case kIntDtId: *vp = (float)p->u.i; break;
  1365. case kULongDtId: *vp = (float)p->u.ul; break;
  1366. case kLongDtId: *vp = (float)p->u.l; break;
  1367. case kFloatDtId: *vp = p->u.f; break;
  1368. case kDoubleDtId: *vp = (float)p->u.d; break;
  1369. default:
  1370. return _cmDataSetError(kCvtErrDtRC);
  1371. }
  1372. return kOkDtRC;
  1373. }
  1374. cmDtRC_t cmDataGetDouble( const cmData_t* p, double* vp )
  1375. {
  1376. switch( p->tid )
  1377. {
  1378. case kUCharDtId: *vp = (double)p->u.uc; break;
  1379. case kCharDtId: *vp = (double)p->u.c; break;
  1380. case kUShortDtId: *vp = (double)p->u.us; break;
  1381. case kShortDtId: *vp = (double)p->u.s; break;
  1382. case kUIntDtId: *vp = (double)p->u.ui; break;
  1383. case kIntDtId: *vp = (double)p->u.i; break;
  1384. case kULongDtId: *vp = (double)p->u.ul; break;
  1385. case kLongDtId: *vp = (double)p->u.l; break;
  1386. case kFloatDtId: *vp = (double)p->u.f; break;
  1387. case kDoubleDtId: *vp = p->u.d; break;
  1388. default:
  1389. return _cmDataSetError(kCvtErrDtRC);
  1390. }
  1391. return kOkDtRC;
  1392. }
  1393. cmDtRC_t cmDataGetStr( const cmData_t* p, cmChar_t** vp )
  1394. {
  1395. if( p->tid == kStrDtId || p->tid == kConstStrDtId)
  1396. {
  1397. *vp = (p->tid == kStrDtId || p->tid == kConstStrDtId) ? p->u.z : NULL;
  1398. return kOkDtRC;
  1399. }
  1400. return _cmDataSetError(kCvtErrDtRC);
  1401. }
  1402. cmDtRC_t cmDataGetConstStr( const cmData_t* p, const cmChar_t** vp )
  1403. {
  1404. if( p->tid == kStrDtId || p->tid == kConstStrDtId)
  1405. {
  1406. *vp = (p->tid == kStrDtId || p->tid == kConstStrDtId) ? p->u.cz : NULL;
  1407. return kOkDtRC;
  1408. }
  1409. return _cmDataSetError(kCvtErrDtRC);
  1410. }
  1411. cmDtRC_t cmDataGetVoidPtr( const cmData_t* p, void** vp )
  1412. {
  1413. if( kMinPtrDtId <= p->tid && p->tid <= kMaxPtrDtId )
  1414. {
  1415. *vp = ( kMinPtrDtId <= p->tid && p->tid <= kMaxPtrDtId ) ? p->u.vp : NULL;
  1416. return kOkDtRC;
  1417. }
  1418. return _cmDataSetError(kCvtErrDtRC);
  1419. }
  1420. cmDtRC_t cmDataGetCharPtr( const cmData_t* p, char** vp )
  1421. {
  1422. if( p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId )
  1423. {
  1424. *vp = (p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId) ? p->u.cp : NULL;
  1425. return kOkDtRC;
  1426. }
  1427. return _cmDataSetError(kCvtErrDtRC);
  1428. }
  1429. cmDtRC_t cmDataGetUCharPtr( const cmData_t* p, unsigned char** vp )
  1430. {
  1431. if( p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId )
  1432. {
  1433. *vp = (p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId) ? p->u.ucp : NULL;
  1434. return kOkDtRC;
  1435. }
  1436. return _cmDataSetError(kCvtErrDtRC);
  1437. }
  1438. cmDtRC_t cmDataGetShortPtr( const cmData_t* p, short** vp )
  1439. {
  1440. if( p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId )
  1441. {
  1442. *vp = (p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId ) ? p->u.sp : NULL;
  1443. return kOkDtRC;
  1444. }
  1445. return _cmDataSetError(kCvtErrDtRC);
  1446. }
  1447. cmDtRC_t cmDataGetUShortPtr( const cmData_t* p, unsigned short** vp )
  1448. {
  1449. if( p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId )
  1450. {
  1451. *vp = (p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId ) ? p->u.usp : NULL;
  1452. return kOkDtRC;
  1453. }
  1454. return _cmDataSetError(kCvtErrDtRC);
  1455. }
  1456. cmDtRC_t cmDataGetIntPtr( const cmData_t* p, int** vp )
  1457. {
  1458. if( p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId )
  1459. {
  1460. *vp = (p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId ) ? p->u.ip : NULL;
  1461. return kOkDtRC;
  1462. }
  1463. return _cmDataSetError(kCvtErrDtRC);
  1464. }
  1465. cmDtRC_t cmDataGetUIntPtr( const cmData_t* p, unsigned int** vp )
  1466. {
  1467. if( p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId )
  1468. {
  1469. *vp = (p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId ) ? p->u.uip : NULL;
  1470. return kOkDtRC;
  1471. }
  1472. return _cmDataSetError(kCvtErrDtRC);
  1473. }
  1474. cmDtRC_t cmDataGetLongPtr( const cmData_t* p, long** vp )
  1475. {
  1476. if( p->tid == kLongPtrDtId || p->tid == kULongPtrDtId )
  1477. {
  1478. *vp = (p->tid == kLongPtrDtId || p->tid == kULongPtrDtId ) ? p->u.lp : NULL;
  1479. return kOkDtRC;
  1480. }
  1481. return _cmDataSetError(kCvtErrDtRC);
  1482. }
  1483. cmDtRC_t cmDataGetULongPtr( const cmData_t* p, unsigned long** vp )
  1484. {
  1485. if( p->tid == kLongPtrDtId || p->tid == kULongPtrDtId )
  1486. {
  1487. *vp = (p->tid == kLongPtrDtId || p->tid == kULongPtrDtId ) ? p->u.ulp : NULL;
  1488. return kOkDtRC;
  1489. }
  1490. return _cmDataSetError(kCvtErrDtRC);
  1491. }
  1492. cmDtRC_t cmDataGetFloatPtr( const cmData_t* p, float** vp )
  1493. {
  1494. if( p->tid == kFloatPtrDtId )
  1495. {
  1496. *vp = p->u.fp;
  1497. return kOkDtRC;
  1498. }
  1499. return _cmDataSetError(kCvtErrDtRC);
  1500. }
  1501. cmDtRC_t cmDataGetDoublePtr( const cmData_t* p, double** vp )
  1502. {
  1503. if( p->tid == kDoublePtrDtId )
  1504. {
  1505. *vp = p->u.dp;
  1506. return kOkDtRC;
  1507. }
  1508. return _cmDataSetError(kCvtErrDtRC);
  1509. }
  1510. // Set the value of an existing data object.
  1511. cmData_t* cmDataSetNull( cmData_t* p )
  1512. {
  1513. _cmDataFreeArray(p);
  1514. p->tid = kNullDtId;
  1515. return p;
  1516. }
  1517. cmData_t* cmDataSetChar( cmData_t* p, char v )
  1518. {
  1519. _cmDataFreeArray(p);
  1520. p->tid = kCharDtId;
  1521. p->u.c = v;
  1522. return p;
  1523. }
  1524. cmData_t* cmDataSetUChar( cmData_t* p, unsigned char v )
  1525. {
  1526. _cmDataFreeArray(p);
  1527. p->tid = kUCharDtId;
  1528. p->u.uc = v;
  1529. return p;
  1530. }
  1531. cmData_t* cmDataSetShort( cmData_t* p, short v )
  1532. {
  1533. _cmDataFreeArray(p);
  1534. p->tid = kShortDtId;
  1535. p->u.s = v;
  1536. return p;
  1537. }
  1538. cmData_t* cmDataSetUShort( cmData_t* p, unsigned short v )
  1539. {
  1540. _cmDataFreeArray(p);
  1541. p->tid = kUShortDtId;
  1542. p->u.us = v;
  1543. return p;
  1544. }
  1545. cmData_t* cmDataSetInt( cmData_t* p, int v )
  1546. {
  1547. _cmDataFreeArray(p);
  1548. p->tid = kCharDtId;
  1549. p->u.c = v;
  1550. return p;
  1551. }
  1552. cmData_t* cmDataSetUInt( cmData_t* p, unsigned int v )
  1553. {
  1554. _cmDataFreeArray(p);
  1555. p->tid = kUIntDtId;
  1556. p->u.ui = v;
  1557. return p;
  1558. }
  1559. cmData_t* cmDataSetLong( cmData_t* p, long v )
  1560. {
  1561. _cmDataFreeArray(p);
  1562. p->tid = kLongDtId;
  1563. p->u.l = v;
  1564. return p;
  1565. }
  1566. cmData_t* cmDataSetULong( cmData_t* p, unsigned long v )
  1567. {
  1568. _cmDataFreeArray(p);
  1569. p->tid = kULongDtId;
  1570. p->u.ul = v;
  1571. return p;
  1572. }
  1573. cmData_t* cmDataSetFloat( cmData_t* p, float v )
  1574. {
  1575. _cmDataFreeArray(p);
  1576. p->tid = kFloatDtId;
  1577. p->u.f = v;
  1578. return p;
  1579. }
  1580. cmData_t* cmDataSetDouble( cmData_t* p, double v )
  1581. {
  1582. _cmDataFreeArray(p);
  1583. p->tid = kDoubleDtId;
  1584. p->u.d = v;
  1585. return p;
  1586. }
  1587. cmData_t* cmDataSetStr( cmData_t* p, cmChar_t* s )
  1588. {
  1589. _cmDataFreeArray(p);
  1590. p->tid = kStrDtId;
  1591. p->u.z = s;
  1592. return p;
  1593. }
  1594. cmData_t* cmDataSetConstStr( cmData_t* p, const cmChar_t* s )
  1595. {
  1596. _cmDataFreeArray(p);
  1597. p->tid = kConstStrDtId;
  1598. p->u.cz = s;
  1599. return p;
  1600. }
  1601. // Set the value of an existing data object to an external array.
  1602. // The array is not copied.
  1603. cmData_t* cmDataSetVoidPtr( cmData_t* p, void* vp, unsigned cnt )
  1604. {
  1605. cmDataSetCharPtr(p,(char*)vp,cnt);
  1606. p->tid = kVoidPtrDtId;
  1607. return p;
  1608. }
  1609. cmData_t* cmDataSetCharPtr( cmData_t* p, char* vp, unsigned cnt )
  1610. {
  1611. _cmDataFreeArray(p);
  1612. p->tid = kCharPtrDtId;
  1613. p->u.cp = vp;
  1614. p->cnt = cnt;
  1615. return p;
  1616. }
  1617. cmData_t* cmDataSetUCharPtr( cmData_t* p, unsigned char* vp, unsigned cnt )
  1618. {
  1619. _cmDataFreeArray(p);
  1620. p->tid = kUCharPtrDtId;
  1621. p->u.ucp = vp;
  1622. p->cnt = cnt;
  1623. return p;
  1624. }
  1625. cmData_t* cmDataSetShortPtr( cmData_t* p, short* vp, unsigned cnt )
  1626. {
  1627. _cmDataFreeArray(p);
  1628. p->tid = kShortPtrDtId;
  1629. p->u.sp = vp;
  1630. p->cnt = cnt;
  1631. return p;
  1632. }
  1633. cmData_t* cmDataSetUShortPtr( cmData_t* p, unsigned short* vp, unsigned cnt )
  1634. {
  1635. _cmDataFreeArray(p);
  1636. p->tid = kUShortPtrDtId;
  1637. p->u.usp = vp;
  1638. p->cnt = cnt;
  1639. return p;
  1640. }
  1641. cmData_t* cmDataSetIntPtr( cmData_t* p, int* vp, unsigned cnt )
  1642. {
  1643. _cmDataFreeArray(p);
  1644. p->tid = kCharPtrDtId;
  1645. p->u.ip = vp;
  1646. p->cnt = cnt;
  1647. return p;
  1648. }
  1649. cmData_t* cmDataSetUIntPtr( cmData_t* p, unsigned int* vp, unsigned cnt )
  1650. {
  1651. _cmDataFreeArray(p);
  1652. p->tid = kUIntPtrDtId;
  1653. p->u.uip = vp;
  1654. p->cnt = cnt;
  1655. return p;
  1656. }
  1657. cmData_t* cmDataSetLongPtr( cmData_t* p, long* vp, unsigned cnt )
  1658. {
  1659. _cmDataFreeArray(p);
  1660. p->tid = kLongPtrDtId;
  1661. p->u.lp = vp;
  1662. p->cnt = cnt;
  1663. return p;
  1664. }
  1665. cmData_t* cmDataSetULongPtr( cmData_t* p, unsigned long* vp, unsigned cnt )
  1666. {
  1667. _cmDataFreeArray(p);
  1668. p->tid = kULongPtrDtId;
  1669. p->u.ulp = vp;
  1670. p->cnt = cnt;
  1671. return p;
  1672. }
  1673. cmData_t* cmDataSetFloatPtr( cmData_t* p, float* vp, unsigned cnt )
  1674. {
  1675. _cmDataFreeArray(p);
  1676. p->tid = kFloatPtrDtId;
  1677. p->u.fp = vp;
  1678. p->cnt = cnt;
  1679. return p;
  1680. }
  1681. cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt )
  1682. {
  1683. _cmDataFreeArray(p);
  1684. p->tid = kDoublePtrDtId;
  1685. p->u.dp = vp;
  1686. p->cnt = cnt;
  1687. return p;
  1688. }
  1689. // Set the value of an existing array based data object.
  1690. // Allocate the internal array and copy the array into it.
  1691. cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt )
  1692. {
  1693. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1694. cmMemResizeStrN(p->u.z,s,charCnt);
  1695. else
  1696. {
  1697. _cmDataFreeArray(p);
  1698. p->u.z = cmMemAllocStrN(s,charCnt);
  1699. }
  1700. p->tid = kStrDtId;
  1701. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1702. return p;
  1703. }
  1704. cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s )
  1705. { return cmDataSetStrAllocN(p,s,strlen(s)); }
  1706. cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt )
  1707. { return cmDataSetStrAllocN(p,s,charCnt); }
  1708. cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s )
  1709. { return cmDataSetStrAlloc(p,s); }
  1710. cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt )
  1711. { return cmDataSetCharAllocPtr(p,(char*)vp,cnt); }
  1712. cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt )
  1713. {
  1714. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1715. p->u.cp = cmMemResize(char, p->u.cp, cnt );
  1716. else
  1717. {
  1718. _cmDataFreeArray(p);
  1719. p->u.cp = cmMemAlloc(char, cnt );
  1720. }
  1721. memcpy(p->u.cp,vp,sizeof(char)*cnt);
  1722. p->tid = kCharPtrDtId;
  1723. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1724. p->cnt = cnt;
  1725. return p;
  1726. }
  1727. cmData_t* cmDataSetUCharAllocPtr( cmData_t* p, const unsigned char* vp, unsigned cnt )
  1728. {
  1729. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1730. p->u.ucp = cmMemResize(unsigned char, p->u.ucp, cnt );
  1731. else
  1732. {
  1733. _cmDataFreeArray(p);
  1734. p->u.ucp = cmMemAlloc(unsigned char, cnt );
  1735. }
  1736. memcpy(p->u.ucp,vp,sizeof(unsigned char)*cnt);
  1737. p->tid = kUCharPtrDtId;
  1738. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1739. p->cnt = cnt;
  1740. return p;
  1741. }
  1742. cmData_t* cmDataSetShortAllocPtr( cmData_t* p, const short* vp, unsigned cnt )
  1743. {
  1744. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1745. p->u.sp = cmMemResize(short, p->u.sp, cnt );
  1746. else
  1747. {
  1748. _cmDataFreeArray(p);
  1749. p->u.sp = cmMemAlloc(short, cnt );
  1750. }
  1751. memcpy(p->u.sp,vp,sizeof(short)*cnt);
  1752. p->tid = kShortPtrDtId;
  1753. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1754. p->cnt = cnt;
  1755. return p;
  1756. }
  1757. cmData_t* cmDataSetUShortAllocPtr( cmData_t* p, const unsigned short* vp, unsigned cnt )
  1758. {
  1759. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1760. p->u.usp = cmMemResize(unsigned short, p->u.usp, cnt );
  1761. else
  1762. {
  1763. _cmDataFreeArray(p);
  1764. p->u.usp = cmMemAlloc(unsigned short, cnt );
  1765. }
  1766. memcpy(p->u.usp,vp,sizeof(unsigned short)*cnt);
  1767. p->tid = kUShortPtrDtId;
  1768. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1769. p->cnt = cnt;
  1770. return p;
  1771. }
  1772. cmData_t* cmDataSetIntAllocPtr( cmData_t* p, const int* vp, unsigned cnt )
  1773. {
  1774. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1775. p->u.ip = cmMemResize(int, p->u.ip, cnt );
  1776. else
  1777. {
  1778. _cmDataFreeArray(p);
  1779. p->u.ip = cmMemAlloc(int, cnt );
  1780. }
  1781. memcpy(p->u.ip,vp,sizeof(int)*cnt);
  1782. p->tid = kIntPtrDtId;
  1783. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1784. p->cnt = cnt;
  1785. return p;
  1786. }
  1787. cmData_t* cmDataSetUIntAllocPtr( cmData_t* p, const unsigned int* vp, unsigned cnt )
  1788. {
  1789. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1790. p->u.uip = cmMemResize(unsigned int, p->u.uip, cnt );
  1791. else
  1792. {
  1793. _cmDataFreeArray(p);
  1794. p->u.uip = cmMemAlloc(unsigned int, cnt );
  1795. }
  1796. memcpy(p->u.uip,vp,sizeof(unsigned int)*cnt);
  1797. p->tid = kUIntPtrDtId;
  1798. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1799. p->cnt = cnt;
  1800. return p;
  1801. }
  1802. cmData_t* cmDataSetLongAllocPtr( cmData_t* p, const long* vp, unsigned cnt )
  1803. {
  1804. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1805. p->u.lp = cmMemResize(long, p->u.lp, cnt );
  1806. else
  1807. {
  1808. _cmDataFreeArray(p);
  1809. p->u.lp = cmMemAlloc(long, cnt );
  1810. }
  1811. memcpy(p->u.lp,vp,sizeof(long)*cnt);
  1812. p->tid = kLongPtrDtId;
  1813. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1814. p->cnt = cnt;
  1815. return p;
  1816. }
  1817. cmData_t* cmDataSetULongAllocPtr( cmData_t* p, const unsigned long* vp, unsigned cnt )
  1818. {
  1819. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1820. p->u.ulp = cmMemResize(unsigned long, p->u.ulp, cnt );
  1821. else
  1822. {
  1823. _cmDataFreeArray(p);
  1824. p->u.ulp = cmMemAlloc(unsigned long, cnt );
  1825. }
  1826. memcpy(p->u.ulp,vp,sizeof(unsigned long)*cnt);
  1827. p->tid = kULongPtrDtId;
  1828. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1829. p->cnt = cnt;
  1830. return p;
  1831. }
  1832. cmData_t* cmDataSetFloatAllocPtr( cmData_t* p, const float* vp, unsigned cnt )
  1833. {
  1834. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1835. p->u.fp = cmMemResize(float, p->u.fp, cnt );
  1836. else
  1837. {
  1838. _cmDataFreeArray(p);
  1839. p->u.fp = cmMemAlloc(float, cnt );
  1840. }
  1841. memcpy(p->u.fp,vp,sizeof(float)*cnt);
  1842. p->tid = kFloatPtrDtId;
  1843. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1844. p->cnt = cnt;
  1845. return p;
  1846. }
  1847. cmData_t* cmDataSetDoubleAllocPtr( cmData_t* p, const double* vp, unsigned cnt )
  1848. {
  1849. if( cmIsFlag(p->flags,kDynPtrDtFl) )
  1850. p->u.dp = cmMemResize(double, p->u.dp, cnt );
  1851. else
  1852. {
  1853. _cmDataFreeArray(p);
  1854. p->u.dp = cmMemAlloc(double, cnt );
  1855. }
  1856. memcpy(p->u.dp,vp,sizeof(double)*cnt);
  1857. p->tid = kDoublePtrDtId;
  1858. p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
  1859. p->cnt = cnt;
  1860. return p;
  1861. }
  1862. // Dynamically allocate a data object and set it's value.
  1863. cmData_t* cmDataAllocNull( cmData_t* parent )
  1864. { return _cmDataAllocNode(parent,kNullDtId); }
  1865. cmData_t* cmDataAllocChar( cmData_t* parent, char v )
  1866. {
  1867. cmData_t* p = _cmDataAllocNode(parent,kCharDtId);
  1868. cmDataSetChar(p,v);
  1869. return p;
  1870. }
  1871. cmData_t* cmDataAllocUChar( cmData_t* parent, unsigned char v )
  1872. {
  1873. cmData_t* p = _cmDataAllocNode(parent,kUCharDtId);
  1874. cmDataSetUChar(p,v);
  1875. return p;
  1876. }
  1877. cmData_t* cmDataAllocShort( cmData_t* parent, short v )
  1878. {
  1879. cmData_t* p = _cmDataAllocNode(parent,kShortDtId);
  1880. cmDataSetShort(p,v);
  1881. return p;
  1882. }
  1883. cmData_t* cmDataAllocUShort( cmData_t* parent, unsigned short v )
  1884. {
  1885. cmData_t* p = _cmDataAllocNode(parent,kUShortDtId);
  1886. cmDataSetUShort(p,v);
  1887. return p;
  1888. }
  1889. cmData_t* cmDataAllocInt( cmData_t* parent, int v )
  1890. {
  1891. cmData_t* p = _cmDataAllocNode(parent,kIntDtId);
  1892. cmDataSetInt(p,v);
  1893. return p;
  1894. }
  1895. cmData_t* cmDataAllocUInt( cmData_t* parent, unsigned int v )
  1896. {
  1897. cmData_t* p = _cmDataAllocNode(parent,kUIntDtId);
  1898. cmDataSetUInt(p,v);
  1899. return p;
  1900. }
  1901. cmData_t* cmDataAllocLong( cmData_t* parent, long v )
  1902. {
  1903. cmData_t* p = _cmDataAllocNode(parent,kLongDtId);
  1904. cmDataSetLong(p,v);
  1905. return p;
  1906. }
  1907. cmData_t* cmDataAllocULong( cmData_t* parent, unsigned long v )
  1908. {
  1909. cmData_t* p = _cmDataAllocNode(parent,kULongDtId);
  1910. cmDataSetULong(p,v);
  1911. return p;
  1912. }
  1913. cmData_t* cmDataAllocFloat( cmData_t* parent, float v )
  1914. {
  1915. cmData_t* p = _cmDataAllocNode(parent,kFloatDtId);
  1916. cmDataSetFloat(p,v);
  1917. return p;
  1918. }
  1919. cmData_t* cmDataAllocDouble( cmData_t* parent, double v )
  1920. {
  1921. cmData_t* p = _cmDataAllocNode(parent,kDoubleDtId);
  1922. cmDataSetDouble(p,v);
  1923. return p;
  1924. }
  1925. // Dynamically allocate a data object and set its array value to an external
  1926. // array. The data is not copied.
  1927. cmData_t* cmDataAllocStr( cmData_t* parent, cmChar_t* str )
  1928. {
  1929. cmData_t* p = _cmDataAllocNode(parent,kStrDtId);
  1930. cmDataSetStr(p,str);
  1931. return p;
  1932. }
  1933. cmData_t* cmDataAllocConstStr( cmData_t* parent, const cmChar_t* str )
  1934. {
  1935. cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
  1936. cmDataSetConstStr(p,str);
  1937. return p;
  1938. }
  1939. cmData_t* cmDataAllocCharPtr( cmData_t* parent, char* v, unsigned cnt )
  1940. {
  1941. cmData_t* p = _cmDataAllocNode(parent,kCharPtrDtId);
  1942. cmDataSetCharPtr(p,(char*)v,cnt);
  1943. return p;
  1944. }
  1945. cmData_t* cmDataAllocUCharPtr( cmData_t* parent, unsigned char* v, unsigned cnt )
  1946. {
  1947. cmData_t* p = _cmDataAllocNode(parent,kUCharPtrDtId);
  1948. cmDataSetUCharPtr(p,(unsigned char*)v,cnt);
  1949. return p;
  1950. }
  1951. cmData_t* cmDataAllocShortPtr( cmData_t* parent, short* v, unsigned cnt )
  1952. {
  1953. cmData_t* p = _cmDataAllocNode(parent,kShortPtrDtId);
  1954. cmDataSetShortPtr(p,(short*)v,cnt);
  1955. return p;
  1956. }
  1957. cmData_t* cmDataAllocUShortPtr( cmData_t* parent, unsigned short* v, unsigned cnt )
  1958. {
  1959. cmData_t* p = _cmDataAllocNode(parent,kUShortPtrDtId);
  1960. cmDataSetUShortPtr(p,(unsigned short*)v,cnt);
  1961. return p;
  1962. }
  1963. cmData_t* cmDataAllocIntPtr( cmData_t* parent, int* v, unsigned cnt )
  1964. {
  1965. cmData_t* p = _cmDataAllocNode(parent,kIntPtrDtId);
  1966. cmDataSetIntPtr(p,(int*)v,cnt);
  1967. return p;
  1968. }
  1969. cmData_t* cmDataAllocUIntPtr( cmData_t* parent, unsigned int* v, unsigned cnt )
  1970. {
  1971. cmData_t* p = _cmDataAllocNode(parent,kUIntPtrDtId);
  1972. cmDataSetUIntPtr(p,(unsigned int*)v,cnt);
  1973. return p;
  1974. }
  1975. cmData_t* cmDataAllocLongPtr( cmData_t* parent, long* v, unsigned cnt )
  1976. {
  1977. cmData_t* p = _cmDataAllocNode(parent,kLongPtrDtId);
  1978. cmDataSetLongPtr(p,(long*)v,cnt);
  1979. return p;
  1980. }
  1981. cmData_t* cmDataAllocULongPtr( cmData_t* parent, unsigned long* v, unsigned cnt )
  1982. {
  1983. cmData_t* p = _cmDataAllocNode(parent,kULongPtrDtId);
  1984. cmDataSetULongPtr(p,(unsigned long*)v,cnt);
  1985. return p;
  1986. }
  1987. cmData_t* cmDataAllocFloatPtr( cmData_t* parent, float* v, unsigned cnt )
  1988. {
  1989. cmData_t* p = _cmDataAllocNode(parent,kFloatPtrDtId);
  1990. cmDataSetFloatPtr(p,(float*)v,cnt);
  1991. return p;
  1992. }
  1993. cmData_t* cmDataAllocDoublePtr( cmData_t* parent, double* v, unsigned cnt )
  1994. {
  1995. cmData_t* p = _cmDataAllocNode(parent,kDoublePtrDtId);
  1996. cmDataSetDoublePtr(p,(double*)v,cnt);
  1997. return p;
  1998. }
  1999. cmData_t* cmDataAllocVoidPtr( cmData_t* parent, void* v, unsigned cnt )
  2000. {
  2001. cmData_t* p = _cmDataAllocNode(parent,kVoidPtrDtId);
  2002. cmDataSetCharPtr(p,(char*)v,cnt);
  2003. p->tid = kVoidPtrDtId;
  2004. return p;
  2005. }
  2006. // Dynamically allocate a data object and its array value.
  2007. // v[cnt] is copied into the allocated array.
  2008. cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str )
  2009. {
  2010. cmData_t* p = _cmDataAllocNode(parent,kStrDtId);
  2011. cmDataSetStrAlloc(p,str);
  2012. return p;
  2013. }
  2014. cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt )
  2015. {
  2016. cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
  2017. cmDataSetConstStrAllocN(p,str,charCnt);
  2018. return p;
  2019. }
  2020. cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str )
  2021. {
  2022. cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
  2023. cmDataSetConstStrAlloc(p,str);
  2024. return p;
  2025. }
  2026. cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt )
  2027. {
  2028. cmData_t* p = _cmDataAllocNode(parent,kCharPtrDtId);
  2029. cmDataSetCharAllocPtr(p, v, cnt );
  2030. return p;
  2031. }
  2032. cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt )
  2033. {
  2034. cmData_t* p = _cmDataAllocNode(parent,kUCharPtrDtId);
  2035. cmDataSetUCharAllocPtr(p, v, cnt );
  2036. return p;
  2037. }
  2038. cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt )
  2039. {
  2040. cmData_t* p = _cmDataAllocNode(parent,kShortPtrDtId);
  2041. cmDataSetShortAllocPtr(p, v, cnt );
  2042. return p;
  2043. }
  2044. cmData_t* cmDataUShortAllocPtr( cmData_t* parent, const unsigned short* v, unsigned cnt )
  2045. {
  2046. cmData_t* p = _cmDataAllocNode(parent,kUShortPtrDtId);
  2047. cmDataSetUShortAllocPtr(p, v, cnt );
  2048. return p;
  2049. }
  2050. cmData_t* cmDataIntAllocPtr( cmData_t* parent, const int* v, unsigned cnt )
  2051. {
  2052. cmData_t* p = _cmDataAllocNode(parent,kIntPtrDtId);
  2053. cmDataSetIntAllocPtr(p, v, cnt );
  2054. return p;
  2055. }
  2056. cmData_t* cmDataUIntAllocPtr( cmData_t* parent, const unsigned int* v, unsigned cnt )
  2057. {
  2058. cmData_t* p = _cmDataAllocNode(parent,kUIntPtrDtId);
  2059. cmDataSetUIntAllocPtr(p, v, cnt );
  2060. return p;
  2061. }
  2062. cmData_t* cmDataLongAllocPtr( cmData_t* parent, const long* v, unsigned cnt )
  2063. {
  2064. cmData_t* p = _cmDataAllocNode(parent,kLongPtrDtId);
  2065. cmDataSetLongAllocPtr(p, v, cnt );
  2066. return p;
  2067. }
  2068. cmData_t* cmDataULongAllocPtr( cmData_t* parent, const unsigned long* v, unsigned cnt )
  2069. {
  2070. cmData_t* p = _cmDataAllocNode(parent,kULongPtrDtId);
  2071. cmDataSetULongAllocPtr(p, v, cnt );
  2072. return p;
  2073. }
  2074. cmData_t* cmDataFloatAllocPtr( cmData_t* parent, const float* v, unsigned cnt )
  2075. {
  2076. cmData_t* p = _cmDataAllocNode(parent,kFloatPtrDtId);
  2077. cmDataSetFloatAllocPtr(p, v, cnt );
  2078. return p;
  2079. }
  2080. cmData_t* cmDataDoubleAllocPtr( cmData_t* parent, const double* v, unsigned cnt )
  2081. {
  2082. cmData_t* p = _cmDataAllocNode(parent,kDoublePtrDtId);
  2083. cmDataSetDoubleAllocPtr(p, v, cnt );
  2084. return p;
  2085. }
  2086. cmData_t* cmDataVoidAllocPtr( cmData_t* parent, const void* v, unsigned cnt )
  2087. {
  2088. cmData_t* p = _cmDataAllocNode(parent,kVoidPtrDtId);
  2089. cmDataSetCharAllocPtr(p, (const char*)v, cnt );
  2090. p->tid = kVoidPtrDtId;
  2091. return p;
  2092. }
  2093. void cmDataFree( cmData_t* p )
  2094. {
  2095. _cmDataFree(p);
  2096. }
  2097. cmData_t* cmDataUnlink( cmData_t* p )
  2098. {
  2099. if( p->parent == NULL )
  2100. return p;
  2101. assert( cmDataIsStruct(p->parent) );
  2102. cmData_t* cp = p->u.child;
  2103. cmData_t* pp = NULL;
  2104. for(; cp!=NULL; cp=cp->sibling)
  2105. if( cp == p )
  2106. {
  2107. if( pp == NULL )
  2108. p->parent->u.child = p->sibling;
  2109. else
  2110. pp->sibling = cp->sibling;
  2111. }
  2112. return p;
  2113. }
  2114. void cmDataUnlinkAndFree( cmData_t* p )
  2115. {
  2116. cmDataUnlink(p);
  2117. cmDataFree(p);
  2118. }
  2119. cmData_t* _cmDataDupl( const cmData_t* p, cmData_t* parent )
  2120. {
  2121. cmData_t* rp = NULL;
  2122. switch( p->tid )
  2123. {
  2124. case kNullDtId: rp = cmDataAllocNull(parent); break;
  2125. case kUCharDtId: rp = cmDataAllocUChar(parent,p->u.uc); break;
  2126. case kCharDtId: rp = cmDataAllocChar(parent,p->u.c); break;
  2127. case kUShortDtId: rp = cmDataAllocShort(parent,p->u.us); break;
  2128. case kShortDtId: rp = cmDataAllocUShort(parent,p->u.s); break;
  2129. case kUIntDtId: rp = cmDataAllocUInt(parent,p->u.i); break;
  2130. case kIntDtId: rp = cmDataAllocInt(parent,p->u.ui); break;
  2131. case kULongDtId: rp = cmDataAllocULong(parent,p->u.ul); break;
  2132. case kLongDtId: rp = cmDataAllocLong(parent,p->u.l); break;
  2133. case kFloatDtId: rp = cmDataAllocFloat(parent,p->u.f); break;
  2134. case kDoubleDtId: rp = cmDataAllocDouble(parent,p->u.d); break;
  2135. case kStrDtId: rp = cmDataStrAlloc(parent,p->u.z); break;
  2136. case kConstStrDtId: rp = cmDataConstStrAlloc(parent,p->u.cz); break;
  2137. case kUCharPtrDtId: rp = cmDataUCharAllocPtr(parent,p->u.ucp,p->cnt); break;
  2138. case kCharPtrDtId: rp = cmDataCharAllocPtr(parent,p->u.cp,p->cnt); break;
  2139. case kUShortPtrDtId: rp = cmDataUShortAllocPtr(parent,p->u.usp,p->cnt); break;
  2140. case kShortPtrDtId: rp = cmDataShortAllocPtr(parent,p->u.sp,p->cnt); break;
  2141. case kUIntPtrDtId: rp = cmDataUIntAllocPtr(parent,p->u.uip,p->cnt); break;
  2142. case kIntPtrDtId: rp = cmDataIntAllocPtr(parent,p->u.ip,p->cnt); break;
  2143. case kULongPtrDtId: rp = cmDataULongAllocPtr(parent,p->u.ulp,p->cnt); break;
  2144. case kLongPtrDtId: rp = cmDataLongAllocPtr(parent,p->u.lp,p->cnt); break;
  2145. case kFloatPtrDtId: rp = cmDataFloatAllocPtr(parent,p->u.fp,p->cnt); break;
  2146. case kDoublePtrDtId: rp = cmDataDoubleAllocPtr(parent,p->u.dp,p->cnt); break;
  2147. case kVoidPtrDtId: rp = cmDataVoidAllocPtr(parent,p->u.vp,p->cnt); break;
  2148. case kListDtId:
  2149. case kPairDtId:
  2150. case kRecordDtId:
  2151. {
  2152. rp = _cmDataAllocNode(parent,p->tid);
  2153. cmData_t* cp = p->u.child;
  2154. for(; cp!=NULL; cp=cp->sibling)
  2155. cmDataAppendChild(rp,_cmDataDupl(cp,rp));
  2156. }
  2157. break;
  2158. default:
  2159. assert(0);
  2160. }
  2161. return rp;
  2162. }
  2163. cmData_t* cmDataDupl( const cmData_t* p )
  2164. { return _cmDataDupl(p,NULL); }
  2165. cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src )
  2166. {
  2167. if( dst->parent == NULL )
  2168. {
  2169. cmDataUnlinkAndFree(dst);
  2170. src->parent = NULL;
  2171. return src;
  2172. }
  2173. cmData_t* parent = dst->parent;
  2174. cmData_t* cp = parent->u.child;
  2175. cmData_t* pp = NULL;
  2176. unsigned i = 0;
  2177. unsigned n = cmDataChildCount(parent);
  2178. // locate dst's right sibling
  2179. for(i=0; i<n; ++i,cp=cp->sibling)
  2180. {
  2181. if( cp == dst )
  2182. {
  2183. // link in 'src' in place of 'dst'
  2184. src->sibling = dst->sibling;
  2185. // free dst
  2186. cmDataUnlinkAndFree(dst);
  2187. // update the sibling link to
  2188. if( pp == NULL )
  2189. parent->u.child = src;
  2190. else
  2191. pp->sibling = src;
  2192. src->parent = parent;
  2193. break;
  2194. }
  2195. pp = cp;
  2196. }
  2197. return src;
  2198. }
  2199. unsigned cmDataChildCount( const cmData_t* p )
  2200. {
  2201. if( !cmDataIsStruct(p) )
  2202. return 0;
  2203. unsigned n = 0;
  2204. const cmData_t* cp = p->u.child;
  2205. for(; cp!=NULL; cp=cp->sibling)
  2206. ++n;
  2207. return n;
  2208. }
  2209. cmData_t* cmDataChild( cmData_t* p, unsigned index )
  2210. {
  2211. if( !cmDataIsStruct(p) )
  2212. return NULL;
  2213. unsigned n = 0;
  2214. cmData_t* cp = p->u.child;
  2215. for(; cp!=NULL; cp=cp->sibling)
  2216. {
  2217. if( n == index )
  2218. break;
  2219. ++n;
  2220. }
  2221. return cp;
  2222. }
  2223. cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p )
  2224. {
  2225. assert( cmDataIsStruct(p) );
  2226. cmDataUnlink(p);
  2227. p->u.child = parent->u.child;
  2228. parent->u.child = p;
  2229. p->parent = parent;
  2230. return p;
  2231. }
  2232. cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p )
  2233. {
  2234. assert( cmDataIsStruct(parent) );
  2235. assert( parent->tid != kRecordDtId || (parent->tid == kRecordDtId && p->tid==kPairDtId));
  2236. cmDataUnlink(p);
  2237. cmData_t* cp = parent->u.child;
  2238. if( cp == NULL )
  2239. parent->u.child = p;
  2240. else
  2241. {
  2242. for(; cp!=NULL; cp=cp->sibling)
  2243. if( cp->sibling == NULL )
  2244. {
  2245. cp->sibling = p;
  2246. break;
  2247. }
  2248. }
  2249. p->parent = parent;
  2250. p->sibling = NULL;
  2251. return p;
  2252. }
  2253. cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p )
  2254. {
  2255. if( !cmDataIsStruct(parent) )
  2256. return NULL;
  2257. cmDataUnlink(p);
  2258. unsigned n = 0;
  2259. cmData_t* cp = parent->u.child;
  2260. cmData_t* pp = NULL;
  2261. for(; cp!=NULL; cp=cp->sibling)
  2262. {
  2263. if( n == index )
  2264. {
  2265. if( pp == NULL )
  2266. {
  2267. parent->u.child = p;
  2268. p->sibling = NULL;
  2269. }
  2270. else
  2271. {
  2272. p->sibling = pp->sibling;
  2273. pp->sibling = p;
  2274. }
  2275. break;
  2276. }
  2277. ++n;
  2278. }
  2279. p->parent = parent;
  2280. return p;
  2281. }
  2282. //----------------------------------------------------------------------------
  2283. bool _cmDataPairIsValid( const cmData_t* p )
  2284. {
  2285. assert( p->tid == kPairDtId );
  2286. bool fl = p->u.child == NULL || p->u.child->sibling == NULL || p->u.child->sibling->sibling!=NULL;
  2287. return !fl;
  2288. }
  2289. // Get the key/value of a pair
  2290. cmData_t* cmDataPairKey( cmData_t* p )
  2291. {
  2292. assert( _cmDataPairIsValid(p) );
  2293. return p->u.child;
  2294. }
  2295. unsigned cmDataPairKeyId( cmData_t* p )
  2296. {
  2297. assert( _cmDataPairIsValid(p) );
  2298. unsigned id = cmInvalidId;
  2299. cmDataGetUInt(p->u.child,&id);
  2300. return id;
  2301. }
  2302. const cmChar_t* cmDataPairKeyLabel( cmData_t* p )
  2303. {
  2304. assert( _cmDataPairIsValid(p) );
  2305. const cmChar_t* label = NULL;
  2306. cmDataGetConstStr(p->u.child,&label);
  2307. return label;
  2308. }
  2309. cmData_t* cmDataPairValue( cmData_t* p )
  2310. {
  2311. assert( _cmDataPairIsValid(p) );
  2312. return p->u.child->sibling;
  2313. }
  2314. // Set the key or value of an existing pair node.
  2315. cmData_t* cmDataPairSetValue( cmData_t* p, cmData_t* value )
  2316. {
  2317. assert( _cmDataPairIsValid(p) );
  2318. cmDataReplace( cmDataPairValue(p), value );
  2319. return p;
  2320. }
  2321. cmData_t* cmDataPairSetKey( cmData_t* p, cmData_t* key )
  2322. {
  2323. assert( _cmDataPairIsValid(p) );
  2324. cmDataReplace( cmDataPairValue(p), key );
  2325. return p;
  2326. }
  2327. cmData_t* cmDataPairSetKeyId( cmData_t* p, unsigned id )
  2328. {
  2329. assert( _cmDataPairIsValid(p) );
  2330. cmDataSetUInt(p->u.child,id);
  2331. return p;
  2332. }
  2333. cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label )
  2334. {
  2335. assert( _cmDataPairIsValid(p) );
  2336. cmDataSetConstStrAlloc(p->u.child,label);
  2337. return p;
  2338. }
  2339. cmData_t* cmDataMakePair( cmData_t* parent, cmData_t* p, cmData_t* key, cmData_t* value )
  2340. {
  2341. _cmDataFree(p);
  2342. p->tid = kPairDtId;
  2343. p->parent = parent;
  2344. p->flags = 0;
  2345. p->u.child = NULL;
  2346. cmDataAppendChild(p,key);
  2347. cmDataAppendChild(p,value);
  2348. return p;
  2349. }
  2350. // Dynamically allocate a pair node
  2351. cmData_t* cmDataAllocPair( cmData_t* parent, const cmData_t* key, const cmData_t* value )
  2352. {
  2353. cmData_t* p = _cmDataAllocNode(parent,kPairDtId);
  2354. cmData_t* kp = cmDataDupl(key);
  2355. cmData_t* vp = cmDataDupl(value);
  2356. cmDataPrependChild(p,vp);
  2357. cmDataPrependChild(p,kp);
  2358. return p;
  2359. }
  2360. cmData_t* cmDataAllocPairId(cmData_t* parent, unsigned keyId, cmData_t* value )
  2361. {
  2362. cmData_t* p = _cmDataAllocNode(parent,kPairDtId);
  2363. cmDataAllocUInt(p,keyId);
  2364. cmDataAppendChild(p,value);
  2365. return p;
  2366. }
  2367. cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_t* value )
  2368. {
  2369. cmData_t* p = _cmDataAllocNode(parent,kPairDtId);
  2370. cmDataConstStrAlloc(p,label);
  2371. cmDataAppendChild(p,value);
  2372. return p;
  2373. }
  2374. cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value)
  2375. {
  2376. cmData_t* p = _cmDataAllocNode(parent,kPairDtId);
  2377. cmDataConstStrAllocN(p,label,charCnt);
  2378. cmDataAppendChild(p,value);
  2379. return p;
  2380. }
  2381. //----------------------------------------------------------------------------
  2382. unsigned cmDataListCount(const cmData_t* p )
  2383. { return cmDataChildCount(p); }
  2384. cmData_t* cmDataListEle( cmData_t* p, unsigned index )
  2385. { return cmDataChild(p,index); }
  2386. cmData_t* cmDataListMake( cmData_t* parent, cmData_t* p )
  2387. {
  2388. _cmDataFree(p);
  2389. p->parent = parent;
  2390. p->tid = kListDtId;
  2391. p->flags = 0;
  2392. p->u.child = NULL;
  2393. return p;
  2394. }
  2395. cmData_t* cmDataListAlloc( cmData_t* parent)
  2396. { return _cmDataAllocNode(parent,kListDtId); }
  2397. cmDtRC_t _cmDataParseArgV( cmData_t* parent, va_list vl, cmData_t** vpp )
  2398. {
  2399. cmDtRC_t rc = kOkDtRC;
  2400. cmData_t* vp = NULL;
  2401. unsigned tid = va_arg(vl,unsigned);
  2402. switch(tid)
  2403. {
  2404. case kInvalidDtId: rc = kEolDtRC; break;
  2405. case kNullDtId: vp = cmDataAllocNull(parent); break;
  2406. case kUCharDtId: vp = cmDataAllocUChar( parent,va_arg(vl,int)); break;
  2407. case kCharDtId: vp = cmDataAllocChar( parent,va_arg(vl,int)); break;
  2408. case kUShortDtId: vp = cmDataAllocUShort( parent,va_arg(vl,int)); break;
  2409. case kShortDtId: vp = cmDataAllocShort( parent,va_arg(vl,int)); break;
  2410. case kUIntDtId: vp = cmDataAllocUInt( parent,va_arg(vl,unsigned int)); break;
  2411. case kIntDtId: vp = cmDataAllocInt( parent,va_arg(vl,int)); break;
  2412. case kULongDtId: vp = cmDataAllocULong( parent,va_arg(vl,unsigned long)); break;
  2413. case kLongDtId: vp = cmDataAllocLong( parent,va_arg(vl,long)); break;
  2414. case kFloatDtId: vp = cmDataAllocFloat( parent,va_arg(vl,double)); break;
  2415. case kDoubleDtId: vp = cmDataAllocDouble( parent,va_arg(vl,double)); break;
  2416. case kStrDtId: vp = cmDataStrAlloc( parent,va_arg(vl,cmChar_t*)); break;
  2417. case kConstStrDtId: vp = cmDataConstStrAlloc( parent,va_arg(vl,const cmChar_t*)); break;
  2418. case kUCharPtrDtId:
  2419. {
  2420. unsigned char* p = va_arg(vl,unsigned char*);
  2421. vp = cmDataUCharAllocPtr(parent, p, va_arg(vl,unsigned));
  2422. }
  2423. break;
  2424. case kCharPtrDtId:
  2425. {
  2426. char* p = va_arg(vl,char*);
  2427. vp = cmDataCharAllocPtr(parent, p, va_arg(vl,unsigned));
  2428. }
  2429. break;
  2430. case kUShortPtrDtId:
  2431. {
  2432. unsigned short* p = va_arg(vl,unsigned short*);
  2433. vp = cmDataUShortAllocPtr(parent, p, va_arg(vl,unsigned));
  2434. }
  2435. break;
  2436. case kShortPtrDtId:
  2437. {
  2438. short* p = va_arg(vl,short*);
  2439. vp = cmDataShortAllocPtr(parent, p, va_arg(vl,unsigned));
  2440. }
  2441. break;
  2442. case kUIntPtrDtId:
  2443. {
  2444. unsigned int* p = va_arg(vl,unsigned int*);
  2445. vp = cmDataUIntAllocPtr(parent, p, va_arg(vl,unsigned));
  2446. }
  2447. break;
  2448. case kIntPtrDtId:
  2449. {
  2450. int * p = va_arg(vl,int*);
  2451. vp = cmDataIntAllocPtr(parent, p, va_arg(vl,unsigned));
  2452. }
  2453. break;
  2454. case kULongPtrDtId:
  2455. {
  2456. unsigned long* p = va_arg(vl,unsigned long*);
  2457. vp = cmDataULongAllocPtr(parent, p, va_arg(vl,unsigned));
  2458. }
  2459. break;
  2460. case kLongPtrDtId:
  2461. {
  2462. long* p = va_arg(vl,long*);
  2463. vp = cmDataLongAllocPtr(parent, p, va_arg(vl,unsigned));
  2464. }
  2465. break;
  2466. case kFloatPtrDtId:
  2467. {
  2468. float* p = va_arg(vl,float*);
  2469. vp = cmDataFloatAllocPtr(parent, p, va_arg(vl,unsigned));
  2470. }
  2471. break;
  2472. case kDoublePtrDtId:
  2473. {
  2474. double* p = va_arg(vl,double*);
  2475. vp = cmDataDoubleAllocPtr(parent,p, va_arg(vl,unsigned));
  2476. }
  2477. break;
  2478. case kVoidPtrDtId:
  2479. {
  2480. void* p = va_arg(vl,void*);
  2481. vp = cmDataVoidAllocPtr(parent, p, va_arg(vl,unsigned));
  2482. }
  2483. break;
  2484. case kListDtId:
  2485. case kPairDtId:
  2486. case kRecordDtId:
  2487. vp = _cmDataAllocNode(parent,tid);
  2488. break;
  2489. default:
  2490. _cmDataSetError(kVarArgErrDtRC);
  2491. break;
  2492. }
  2493. *vpp = vp;
  2494. return rc;
  2495. }
  2496. cmData_t* _cmDataListParseV(cmData_t* parent, va_list vl )
  2497. {
  2498. cmData_t* p = NULL;
  2499. bool contFl = true;
  2500. while( contFl )
  2501. {
  2502. cmData_t* vp;
  2503. cmDtRC_t rc = _cmDataParseArgV(parent, vl, &vp);
  2504. if(rc != kOkDtRC || cmDataAppendChild(parent,vp)==NULL )
  2505. contFl = false;
  2506. }
  2507. return p;
  2508. }
  2509. cmData_t* cmDataListAllocV(cmData_t* parent, va_list vl )
  2510. {
  2511. cmData_t* p = cmDataListAlloc(parent);
  2512. _cmDataListParseV(p, vl );
  2513. return p;
  2514. }
  2515. cmData_t* cmDataListAllocA(cmData_t* parent, ... )
  2516. {
  2517. va_list vl;
  2518. va_start(vl,parent);
  2519. cmData_t* p = cmDataListAllocV(parent,vl);
  2520. va_end(vl);
  2521. return p;
  2522. }
  2523. cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele )
  2524. {
  2525. assert(p->tid == kListDtId);
  2526. return cmDataAppendChild(p,ele);
  2527. }
  2528. cmData_t* cmDataListAppendEleN(cmData_t* p, cmData_t* ele[], unsigned n )
  2529. {
  2530. assert(p->tid == kListDtId);
  2531. cmData_t* rp = NULL;
  2532. unsigned i;
  2533. for(i=0; i<n; ++i)
  2534. {
  2535. cmData_t* ep = cmDataAppendChild(p,ele[i]);
  2536. if( rp == NULL )
  2537. rp = ep;
  2538. }
  2539. return rp;
  2540. }
  2541. cmDtRC_t cmDataListAppendV( cmData_t* p, va_list vl )
  2542. {
  2543. if( _cmDataListParseV(p, vl ) == NULL )
  2544. return _cmDataErrNo;
  2545. return kOkDtRC;
  2546. }
  2547. cmDtRC_t cmDataListAppend( cmData_t* p, ... )
  2548. {
  2549. va_list vl;
  2550. va_start(vl,p);
  2551. cmDtRC_t rc = cmDataListAppendV(p,vl);
  2552. va_end(vl);
  2553. return rc;
  2554. }
  2555. cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele )
  2556. { return cmDataInsertChild(p,index,ele); }
  2557. cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n )
  2558. {
  2559. unsigned i;
  2560. for(i=0; i<n; ++i)
  2561. cmDataListInsertEle(p,index+i,ele[i]);
  2562. return p;
  2563. }
  2564. //----------------------------------------------------------------------------
  2565. unsigned cmDataRecdCount( const cmData_t* p )
  2566. {
  2567. assert( p->tid == kRecordDtId );
  2568. return cmDataChildCount(p);
  2569. }
  2570. cmData_t* cmDataRecdEle( cmData_t* p, unsigned index )
  2571. {
  2572. assert( p->tid == kRecordDtId );
  2573. cmData_t* cp = cmDataChild(p,index);
  2574. assert( p->tid == kPairDtId );
  2575. return cp;
  2576. }
  2577. cmData_t* cmDataRecdValueFromIndex( cmData_t* p, unsigned index )
  2578. {
  2579. assert( p->tid == kRecordDtId );
  2580. cmData_t* cp = cmDataChild(p,index);
  2581. assert( p->tid == kPairDtId );
  2582. return cmDataPairValue(cp);
  2583. }
  2584. cmData_t* cmDataRecdValueFromId( cmData_t* p, unsigned id )
  2585. {
  2586. assert( p->tid == kRecordDtId );
  2587. cmData_t* cp = p->u.child;
  2588. for(; cp!=NULL; cp=cp->sibling)
  2589. if( cmDataPairKeyId(cp) == id )
  2590. break;
  2591. assert( cp!=NULL && cp->tid==kPairDtId );
  2592. return cmDataPairValue(cp);
  2593. }
  2594. cmData_t* cmDataRecdValueFromLabel( cmData_t* p, const cmChar_t* label )
  2595. {
  2596. assert( p->tid == kRecordDtId );
  2597. cmData_t* cp = p->u.child;
  2598. for(; cp!=NULL; cp=cp->sibling)
  2599. {
  2600. const cmChar_t* lp = cmDataPairKeyLabel(cp);
  2601. if( lp!=NULL && strcmp(lp,label)==0 )
  2602. break;
  2603. }
  2604. assert( cp!=NULL && cp->tid==kPairDtId );
  2605. return cmDataPairValue(cp);
  2606. }
  2607. cmData_t* cmDataRecdKey( cmData_t* p, unsigned index )
  2608. {
  2609. assert( p->tid == kRecordDtId );
  2610. cmData_t* cp = cmDataChild(p,index);
  2611. assert( p->tid == kPairDtId );
  2612. return cmDataPairKey(cp);
  2613. }
  2614. unsigned cmDataRecdKeyId( cmData_t* p, unsigned index )
  2615. {
  2616. cmData_t* kp = cmDataRecdKey(p,index);
  2617. unsigned id = cmInvalidId;
  2618. cmDataGetUInt(kp,&id);
  2619. return id;
  2620. }
  2621. const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index )
  2622. {
  2623. cmData_t* kp = cmDataRecdKey(p,index);
  2624. const cmChar_t* label = NULL;
  2625. cmDataGetConstStr(kp,&label);
  2626. return label;
  2627. }
  2628. cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p )
  2629. {
  2630. _cmDataFree(p);
  2631. p->parent = parent;
  2632. p->tid = kRecordDtId;
  2633. p->flags = 0;
  2634. p->u.child = NULL;
  2635. return p;
  2636. }
  2637. cmData_t* cmDataRecdAlloc(cmData_t* parent)
  2638. { return _cmDataAllocNode(parent,kRecordDtId); }
  2639. cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair )
  2640. {
  2641. assert( p!=NULL && p->tid==kRecordDtId);
  2642. cmDataAppendChild(p,pair);
  2643. return p;
  2644. }
  2645. cmDtRC_t _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl )
  2646. {
  2647. assert( parent != NULL && parent->tid == kRecordDtId );
  2648. bool contFl = true;
  2649. cmDtRC_t rc = kOkDtRC;
  2650. // for each record field
  2651. while( contFl )
  2652. {
  2653. cmData_t* vp = NULL;
  2654. unsigned id = cmInvalidId;
  2655. const cmChar_t* label = NULL;
  2656. // parse the field idenfier
  2657. if( idFl )
  2658. id = va_arg(vl,unsigned); // numeric field identifier
  2659. else
  2660. label = va_arg(vl,const char*); // text field label identifier
  2661. // validate the field identifier
  2662. if( (idFl && id==kInvalidDtId) || (!idFl && label==NULL) )
  2663. break;
  2664. // parse the field data
  2665. if((rc =_cmDataParseArgV( NULL, vl, &vp )) != kOkDtRC )
  2666. {
  2667. contFl = false;
  2668. }
  2669. else
  2670. {
  2671. // create the field pair
  2672. if( idFl )
  2673. cmDataAllocPairId(parent,id,vp);
  2674. else
  2675. cmDataAllocPairLabel(parent,label,vp);
  2676. }
  2677. }
  2678. return rc;
  2679. }
  2680. cmData_t* cmDataRecdAllocLabelV( cmData_t* parent, va_list vl )
  2681. {
  2682. cmData_t* p = cmDataRecdAlloc(parent);
  2683. cmDtRC_t rc = _cmDataRecdParseInputV(p, false, vl );
  2684. if( rc != kOkDtRC )
  2685. {
  2686. cmDataFree(p);
  2687. p = NULL;
  2688. }
  2689. return p;
  2690. }
  2691. cmData_t* cmDataRecdAllocLabelA( cmData_t* parent, ... )
  2692. {
  2693. va_list vl;
  2694. va_start(vl,parent);
  2695. cmData_t* p = cmDataRecdAllocLabelV(parent,vl);
  2696. va_end(vl);
  2697. return p;
  2698. }
  2699. cmData_t* cmDataRecdAllocIdV( cmData_t* parent, va_list vl )
  2700. {
  2701. cmData_t* p = cmDataRecdAlloc(parent);
  2702. cmDtRC_t rc = _cmDataRecdParseInputV(p, true, vl );
  2703. if( rc != kOkDtRC )
  2704. {
  2705. cmDataFree(p);
  2706. p = NULL;
  2707. }
  2708. return p;
  2709. }
  2710. cmData_t* cmDataRecdAllocIdA( cmData_t* parent, ... )
  2711. {
  2712. va_list vl;
  2713. va_start(vl,parent);
  2714. cmData_t* p = cmDataRecdAllocIdV(parent,vl);
  2715. va_end(vl);
  2716. return p;
  2717. }
  2718. cmDtRC_t _cmDataRecdParseV(cmData_t* p, bool idFl, cmErr_t* err, unsigned errRC, va_list vl )
  2719. {
  2720. bool contFl = true;
  2721. cmDtRC_t rc = kOkDtRC;
  2722. while( contFl )
  2723. {
  2724. unsigned id;
  2725. const char* label;
  2726. // parse the field idenfier
  2727. if( idFl )
  2728. id = va_arg(vl,unsigned); // numeric field identifier
  2729. else
  2730. label = va_arg(vl,const char*); // text field label identifier
  2731. // validate the field identifier
  2732. if( (idFl && id==kInvalidDtId) || (!idFl && label==NULL) )
  2733. break;
  2734. cmDataFmtId_t typeId = va_arg(vl,unsigned);
  2735. void* v = va_arg(vl,void*);
  2736. cmData_t* np = NULL;
  2737. bool optFl = cmIsFlag(typeId,kOptArgDtFl);
  2738. cmDtRC_t rc0 = kOkDtRC;
  2739. typeId = cmClrFlag(typeId,kOptArgDtFl);
  2740. if( idFl )
  2741. np = cmDataRecdValueFromLabel( p, label );
  2742. else
  2743. np = cmDataRecdValueFromId( p, id );
  2744. // if the field was not found
  2745. if( np == NULL )
  2746. {
  2747. if(optFl)
  2748. continue;
  2749. if( err != NULL )
  2750. {
  2751. if( idFl )
  2752. cmErrMsg(err,errRC,"The required field (id=%i) was not found.",id);
  2753. else
  2754. cmErrMsg(err,errRC,"The required field '%s' was not found.",cmStringNullGuard(label));
  2755. }
  2756. rc = kMissingFieldDtRC;
  2757. }
  2758. switch(typeId)
  2759. {
  2760. case kNullDtId:
  2761. break;
  2762. case kUCharDtId:
  2763. rc0 = cmDataGetUChar(np,(unsigned char*)v);
  2764. break;
  2765. case kCharDtId:
  2766. rc0 = cmDataGetChar(np,(char*)v);
  2767. break;
  2768. case kUShortDtId:
  2769. rc0 = cmDataGetUShort(np,(unsigned short*)v);
  2770. break;
  2771. case kShortDtId:
  2772. rc0 = cmDataGetShort(np,(short*)v);
  2773. break;
  2774. case kUIntDtId:
  2775. rc0 = cmDataGetUInt(np,(unsigned int*)v);
  2776. break;
  2777. case kIntDtId:
  2778. rc0 = cmDataGetInt(np,(int*)v);
  2779. break;
  2780. case kULongDtId:
  2781. rc0 = cmDataGetULong(np,(unsigned long*)v);
  2782. break;
  2783. case kLongDtId:
  2784. rc0 = cmDataGetLong(np,(long*)v);
  2785. break;
  2786. case kFloatDtId:
  2787. rc0 = cmDataGetFloat(np,(float*)v);
  2788. break;
  2789. case kDoubleDtId:
  2790. rc0 = cmDataGetDouble(np,(double*)v);
  2791. break;
  2792. case kStrDtId:
  2793. rc0 = cmDataGetStr(np,(char**)v);
  2794. break;
  2795. case kConstStrDtId:
  2796. rc0 = cmDataGetConstStr(np,(const char**)v);
  2797. break;
  2798. case kUCharPtrDtId:
  2799. rc0 = cmDataGetUCharPtr(np,(unsigned char**)v);
  2800. break;
  2801. case kCharPtrDtId:
  2802. rc0 = cmDataGetCharPtr(np,(char**)v);
  2803. break;
  2804. case kUShortPtrDtId:
  2805. rc0 = cmDataGetUShortPtr(np,(unsigned short**)v);
  2806. break;
  2807. case kShortPtrDtId:
  2808. rc0 = cmDataGetShortPtr(np,(short**)v);
  2809. break;
  2810. case kUIntPtrDtId:
  2811. rc0 = cmDataGetUIntPtr(np,(unsigned int**)v);
  2812. break;
  2813. case kIntPtrDtId:
  2814. rc0 = cmDataGetIntPtr(np,(int**)v);
  2815. break;
  2816. case kULongPtrDtId:
  2817. rc0 = cmDataGetULongPtr(np,(unsigned long**)v);
  2818. break;
  2819. case kLongPtrDtId:
  2820. rc0 = cmDataGetLongPtr(np,(long**)v);
  2821. break;
  2822. case kFloatPtrDtId:
  2823. rc0 = cmDataGetFloatPtr(np,(float**)v);
  2824. break;
  2825. case kDoublePtrDtId:
  2826. rc0 = cmDataGetDoublePtr(np,(double**)v);
  2827. break;
  2828. case kVoidPtrDtId:
  2829. rc0 = cmDataGetVoidPtr(np,(void**)v);
  2830. break;
  2831. case kListDtId:
  2832. case kPairDtId:
  2833. case kRecordDtId:
  2834. if( np->tid != typeId )
  2835. rc0 = _cmDataSetError(kCvtErrDtRC);
  2836. else
  2837. *(cmData_t**)v = np;
  2838. break;
  2839. default:
  2840. rc0 = _cmDataSetError(kVarArgErrDtRC);
  2841. assert(0);
  2842. }
  2843. if( rc0 != kOkDtRC && err!=NULL)
  2844. {
  2845. if( idFl )
  2846. cmErrMsg(err,errRC,"Unable to convert field (id=%i) to requested type.",id);
  2847. else
  2848. cmErrMsg(err,errRC,"Unable to convert field '%s' to requisted type.",cmStringNullGuard(label));
  2849. rc = rc0;
  2850. }
  2851. }
  2852. return rc;
  2853. }
  2854. cmDtRC_t cmDataRecdParseLabelV(cmData_t* p, cmErr_t* err, unsigned errRC, va_list vl )
  2855. { return _cmDataRecdParseV(p,false,err,errRC,vl); }
  2856. cmDtRC_t cmDataRecdParseLabel(cmData_t* p, cmErr_t* err, unsigned errRC, ... )
  2857. {
  2858. va_list vl;
  2859. va_start(vl,errRC);
  2860. cmDtRC_t rc = cmDataRecdParseLabelV(p,err,errRC,vl);
  2861. va_end(vl);
  2862. return rc;
  2863. }
  2864. cmDtRC_t cmDataRecdParseIdV(cmData_t* p, cmErr_t* err, unsigned errRC, va_list vl )
  2865. { return _cmDataRecdParseV(p,true,err,errRC,vl); }
  2866. cmDtRC_t cmDataRecdParseId(cmData_t* p, cmErr_t* err, unsigned errRC, ... )
  2867. {
  2868. va_list vl;
  2869. va_start(vl,errRC);
  2870. cmDtRC_t rc = cmDataRecdParseIdV(p,err,errRC,vl);
  2871. va_end(vl);
  2872. return rc;
  2873. }
  2874. //============================================================================
  2875. //============================================================================
  2876. //============================================================================
  2877. unsigned _cmDataSerializeNodeByteCount( const cmData_t* p )
  2878. {
  2879. unsigned n = 0;
  2880. // all serialized data ele's begin with a cmDataFmtId_t
  2881. n += sizeof(cmDataFmtId_t);
  2882. // arrays then have a count of bytes and structures have a child count
  2883. if( cmDataIsPtr(p) || cmDataIsStruct(p) )
  2884. n += sizeof(unsigned);
  2885. // then the data itself takes a variable number of bytes
  2886. n += _cmDataByteCount(p);
  2887. return n;
  2888. }
  2889. unsigned cmDataSerializeByteCount( const cmData_t* p )
  2890. {
  2891. unsigned bn = 0;
  2892. // if this data type has a child then calculate it's size
  2893. if( kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId && p->u.child != NULL )
  2894. bn = cmDataSerializeByteCount(p->u.child);
  2895. // if this data type has siblings get their type
  2896. cmData_t* dp = p->u.child;
  2897. for(; dp != NULL; dp=dp->sibling )
  2898. bn += cmDataSerializeByteCount(dp->sibling);
  2899. //
  2900. return bn + _cmDataSerializeNodeByteCount(p);
  2901. }
  2902. char* _cmDataSerializeWriteArray( cmData_t* np, char* dp, const char* ep )
  2903. {
  2904. unsigned byteCnt = _cmDataByteCount(np);
  2905. *((unsigned*)dp) = byteCnt;
  2906. dp += sizeof(unsigned);
  2907. memcpy(dp,np->u.vp,byteCnt);
  2908. dp += byteCnt;
  2909. return dp;
  2910. }
  2911. char* _cmDataSerializeWriteStruct( cmData_t* np, char* dp, const char* ep )
  2912. {
  2913. *((unsigned*)dp) = cmDataChildCount(np);
  2914. dp += sizeof(unsigned);
  2915. return dp;
  2916. }
  2917. char* _cmDataSerializeWrite( cmData_t* np, char* dp, const char* ep )
  2918. {
  2919. assert( dp + _cmDataSerializeNodeByteCount(np) <= ep );
  2920. *((cmDataFmtId_t*)dp) = np->tid;
  2921. dp += sizeof(cmDataFmtId_t);
  2922. switch( np->tid )
  2923. {
  2924. case kNullDtId: break;
  2925. case kUCharDtId: *((unsigned char*)dp) = cmDataUChar(np); dp+=sizeof(unsigned char); break;
  2926. case kCharDtId: *((char*)dp) = cmDataChar(np); dp+=sizeof(char); break;
  2927. case kUShortDtId: *((unsigned short*)dp) = cmDataUShort(np); dp+=sizeof(unsigned short); break;
  2928. case kShortDtId: *((short*)dp) = cmDataShort(np); dp+=sizeof(short); break;
  2929. case kUIntDtId: *((unsigned int*)dp) = cmDataUInt(np); dp+=sizeof(unsigned int); break;
  2930. case kIntDtId: *((int*)dp) = cmDataInt(np); dp+=sizeof(int); break;
  2931. case kULongDtId: *((unsigned long*)dp) = cmDataULong(np); dp+=sizeof(unsigned long); break;
  2932. case kLongDtId: *((long*)dp) = cmDataLong(np); dp+=sizeof(long); break;
  2933. case kFloatDtId: *((float*)dp) = cmDataFloat(np); dp+=sizeof(float); break;
  2934. case kDoubleDtId: *((double*)dp) = cmDataDouble(np); dp+=sizeof(double); break;
  2935. case kStrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2936. case kConstStrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2937. case kUCharPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2938. case kCharPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2939. case kUShortPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2940. case kShortPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2941. case kUIntPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2942. case kIntPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2943. case kULongPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2944. case kLongPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2945. case kFloatPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2946. case kDoublePtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2947. case kVoidPtrDtId: dp = _cmDataSerializeWriteArray(np,dp,ep); break;
  2948. case kListDtId: dp = _cmDataSerializeWriteStruct(np,dp,ep); break;
  2949. case kPairDtId: dp = _cmDataSerializeWriteStruct(np,dp,ep); break;
  2950. case kRecordDtId: dp = _cmDataSerializeWriteStruct(np,dp,ep); break;
  2951. default:
  2952. { assert(0); }
  2953. }
  2954. return dp;
  2955. }
  2956. char* _cmDataSerialize( const cmData_t* p, char* buf, const char* ep )
  2957. {
  2958. /*
  2959. buf = _cmDataSerializeWrite(p,buf,ep);
  2960. // if this data type has a child then write the child
  2961. if( kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId && p->u.child != NULL )
  2962. buf = _cmDataSerialize(p->u.child,buf,ep);
  2963. // if this data type has siblings then write sibings
  2964. cmData_t* dp = p->u.child;
  2965. for(; dp != NULL; dp=dp->sibling )
  2966. buf = cmDataSerialize(dp->sibling,buf,ep);
  2967. return buf;
  2968. */
  2969. return NULL;
  2970. }
  2971. cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt )
  2972. {
  2973. /*
  2974. const char* ep = (char*)p + bufByteCnt;
  2975. buf = _cmDataSerialize(p,buf,bufByteCnt);
  2976. assert( buf <= ep );
  2977. */
  2978. return kOkDtRC;
  2979. }
  2980. cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp )
  2981. {
  2982. return kOkDtRC;
  2983. }
  2984. //============================================================================
  2985. //============================================================================
  2986. //============================================================================
  2987. enum
  2988. {
  2989. kLCurlyLexTId = kUserLexTId + 1,
  2990. kRCurlyLexTId,
  2991. kLParenLexTId,
  2992. kRParenLexTId,
  2993. kLBrackLexTId,
  2994. kRBrackLexTId,
  2995. kColonLexTId,
  2996. kCommaLexTId,
  2997. };
  2998. typedef struct
  2999. {
  3000. unsigned id;
  3001. const cmChar_t* label;
  3002. } cmDtToken_t;
  3003. cmDtToken_t _cmDtTokenArray[] =
  3004. {
  3005. { kLCurlyLexTId, "{" },
  3006. { kRCurlyLexTId, "}" },
  3007. { kLBrackLexTId, "[" },
  3008. { kRBrackLexTId, "]" },
  3009. { kLParenLexTId, "(" },
  3010. { kRParenLexTId, ")" },
  3011. { kColonLexTId, ":" },
  3012. { kCommaLexTId, "," },
  3013. { kErrorLexTId,""}
  3014. };
  3015. typedef struct
  3016. {
  3017. cmErr_t err;
  3018. cmLexH lexH;
  3019. cmStackH_t stH;
  3020. } cmDataParser_t;
  3021. cmDataParserH_t cmDataParserNullHandle = cmSTATIC_NULL_HANDLE;
  3022. cmDataParser_t* _cmDataParserHandleToPtr( cmDataParserH_t h )
  3023. {
  3024. cmDataParser_t* p = (cmDataParser_t*)h.h;
  3025. assert( p!= NULL );
  3026. return p;
  3027. }
  3028. cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p )
  3029. {
  3030. if( cmLexFinal(&p->lexH) != kOkLexRC )
  3031. cmErrMsg(&p->err,kLexFailDtRC,"Lexer release failed.");
  3032. if( cmStackFree(&p->stH) != kOkStRC )
  3033. cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack release failed.");
  3034. cmMemFree(p);
  3035. return kOkDtRC;
  3036. }
  3037. cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp )
  3038. {
  3039. cmDtRC_t rc;
  3040. unsigned i;
  3041. if((rc = cmDataParserDestroy(hp)) != kOkDtRC )
  3042. return rc;
  3043. cmDataParser_t* p = cmMemAllocZ(cmDataParser_t,1);
  3044. cmErrSetup(&p->err,&ctx->rpt,"Data Parser");
  3045. if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,&ctx->rpt))==false)
  3046. {
  3047. rc = cmErrMsg(&p->err, kLexFailDtRC, "The data object parser lexer create failed.");
  3048. goto errLabel;
  3049. }
  3050. for(i=0; _cmDtTokenArray[i].id != kErrorLexTId; ++i)
  3051. if( cmLexRegisterToken(p->lexH, _cmDtTokenArray[i].id, _cmDtTokenArray[i].label) != kOkLexRC )
  3052. {
  3053. rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",_cmDtTokenArray[i].label);
  3054. goto errLabel;
  3055. }
  3056. if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmData_t*)) != kOkStRC )
  3057. {
  3058. rc = cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack create failed.");
  3059. goto errLabel;
  3060. }
  3061. hp->h = p;
  3062. errLabel:
  3063. if( rc != kOkDtRC )
  3064. _cmDataParserDestroy(p);
  3065. return kOkDtRC;
  3066. }
  3067. cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp )
  3068. {
  3069. cmDtRC_t rc=kOkDtRC;
  3070. if( hp==NULL || cmDataParserIsValid(*hp)==false )
  3071. return rc;
  3072. cmDataParser_t* p = _cmDataParserHandleToPtr(*hp);
  3073. if((rc = _cmDataParserDestroy(p)) != kOkDtRC )
  3074. return rc;
  3075. hp->h = NULL;
  3076. return kOkDtRC;
  3077. }
  3078. bool cmDataParserIsValid( cmDataParserH_t h )
  3079. { return h.h != NULL; }
  3080. // {
  3081. // id0 : scalar_value
  3082. // id1 : ( heterogenous, array, value )
  3083. // id2 : [ homogeneous array values ]
  3084. // id3 :
  3085. // }
  3086. // flags describing the expected next token
  3087. enum
  3088. {
  3089. kValueExpFl = 0x01,
  3090. kIdExpFl = 0x02,
  3091. kColonExpFl = 0x04,
  3092. kCommaExpFl = 0x08
  3093. };
  3094. typedef struct
  3095. {
  3096. cmData_t* dp;
  3097. } cmDataStEle_t;
  3098. typedef struct
  3099. {
  3100. cmDataParser_t* p;
  3101. cmData_t* cnp;
  3102. unsigned flags;
  3103. cmChar_t* tmpStr;
  3104. unsigned arrayCnt;
  3105. void* arrayMem;
  3106. } cmDataParserCtx_t;
  3107. cmDtRC_t _cmDpSyntaxErrV( cmDataParserCtx_t* c, const cmChar_t* fmt, va_list vl )
  3108. {
  3109. cmChar_t* s0 = NULL;
  3110. cmChar_t* s1 = NULL;
  3111. s0 = cmTsVPrintfP(s0,fmt,vl);
  3112. s1 = cmMemAllocStrN(cmLexTokenText(c->p->lexH),cmLexTokenCharCount(c->p->lexH));
  3113. 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));
  3114. cmMemFree(s0);
  3115. cmMemFree(s1);
  3116. return rc;
  3117. }
  3118. cmDtRC_t _cmDpSyntaxErr( cmDataParserCtx_t* c, const cmChar_t* fmt, ... )
  3119. {
  3120. va_list vl;
  3121. va_start(vl,fmt);
  3122. cmDtRC_t rc = _cmDpSyntaxErrV(c,fmt,vl);
  3123. va_end(vl);
  3124. return rc;
  3125. }
  3126. cmDtRC_t _cmDpPopStack( cmDataParserCtx_t* c, cmData_t** pp )
  3127. {
  3128. const void* vp;
  3129. if((vp = cmStackTop(c->p->stH)) == NULL )
  3130. return _cmDpSyntaxErr(c,"Stack underflow.");
  3131. if( cmStackPop(c->p->stH,1) != kOkStRC )
  3132. return _cmDpSyntaxErr(c,"Stack pop failed.");
  3133. *pp = *(cmData_t**)vp;
  3134. //printf("pop: %p\n",*pp);
  3135. return kOkDtRC;
  3136. }
  3137. cmDtRC_t _cmDpPushStack( cmDataParserCtx_t* c, cmData_t* np )
  3138. {
  3139. //printf("push:%p\n",np);
  3140. // store the current node
  3141. if( cmStackPush(c->p->stH, &np, 1 ) != kOkStRC )
  3142. return _cmDpSyntaxErr(c,"Parser stack push failed.");
  3143. return kOkDtRC;
  3144. }
  3145. cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned eleByteCnt, unsigned tid )
  3146. {
  3147. if( c->cnp->tid == kVoidPtrDtId )
  3148. c->cnp->tid = tid;
  3149. else
  3150. if( c->cnp->tid != tid )
  3151. return _cmDpSyntaxErr(c,"Mixed types were detected in an array list.");
  3152. unsigned newByteCnt = (c->cnp->cnt+1)*eleByteCnt;
  3153. char* vp = cmMemResizeP(char, c->cnp->u.vp, newByteCnt);
  3154. memcpy(vp + c->cnp->cnt*eleByteCnt,dp,eleByteCnt);
  3155. c->cnp->u.vp = vp;
  3156. c->cnp->cnt += 1;
  3157. c->flags = kValueExpFl | kCommaExpFl;
  3158. return kOkDtRC;
  3159. }
  3160. cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c )
  3161. {
  3162. cmDtRC_t rc = kOkDtRC;
  3163. assert( c->cnp->tid == kRecordDtId );
  3164. // create a pair with a 'null' value which will be replaced when the pair's value is parsed
  3165. cmData_t* nnp = cmDataAllocNull(NULL);
  3166. cmData_t* pnp = cmDataAllocPairLabelN( c->cnp, cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH), nnp );
  3167. // store the current node
  3168. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  3169. return rc;
  3170. // make the new pair the current node
  3171. c->cnp = pnp;
  3172. // pair openings must be followed by a colon.
  3173. c->flags = kColonExpFl;
  3174. return rc;
  3175. }
  3176. cmDtRC_t _cmDataParserClosePair( cmDataParserCtx_t* c )
  3177. {
  3178. cmDtRC_t rc;
  3179. // make the pair's parent record the current node
  3180. if((rc = _cmDpPopStack(c, &c->cnp )) != kOkDtRC )
  3181. return rc;
  3182. // pairs only occur in records
  3183. if( c->cnp->tid != kRecordDtId )
  3184. return _cmDpSyntaxErr(c,"A 'pair' end was found outside of a 'record'.");
  3185. // pairs must be followed by id's or comma's
  3186. c->flags = kIdExpFl | kCommaExpFl;
  3187. return rc;
  3188. }
  3189. cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* typeLabel )
  3190. {
  3191. assert( np != NULL );
  3192. cmDtRC_t rc = kOkDtRC;
  3193. switch( c->cnp->tid )
  3194. {
  3195. case kPairDtId:
  3196. // assign the new node as the value of the pair
  3197. cmDataPairSetValue(c->cnp,np);
  3198. // close the values parent pair
  3199. rc = _cmDataParserClosePair(c);
  3200. break;
  3201. case kListDtId:
  3202. cmDataAppendChild(c->cnp,np);
  3203. c->flags = kValueExpFl;
  3204. break;
  3205. default:
  3206. rc = _cmDpSyntaxErr(c,"A '%s' value was found outside of a valid container.",typeLabel);
  3207. // Free the new data node because it was not attached and will
  3208. // otherwise be lost
  3209. cmDataFree(np);
  3210. }
  3211. c->flags |= kCommaExpFl;
  3212. return rc;
  3213. }
  3214. cmDtRC_t _cmDataParserReal( cmDataParserCtx_t* c )
  3215. {
  3216. cmDtRC_t rc = kOkDtRC;
  3217. bool floatFl = cmLexTokenIsSinglePrecision(c->p->lexH);
  3218. double dval;
  3219. float fval;
  3220. if( floatFl )
  3221. fval = cmLexTokenFloat(c->p->lexH);
  3222. else
  3223. dval = cmLexTokenDouble(c->p->lexH);
  3224. if( cmDataIsPtr(c->cnp) )
  3225. {
  3226. if( floatFl )
  3227. rc = _cmDpStoreArrayEle(c,&fval,sizeof(fval),kFloatPtrDtId);
  3228. else
  3229. rc = _cmDpStoreArrayEle(c,&dval,sizeof(dval),kDoublePtrDtId);
  3230. }
  3231. else
  3232. {
  3233. cmData_t* np = floatFl ? cmDataAllocFloat(NULL,fval) : cmDataAllocDouble(NULL,dval);
  3234. rc = _cmDpStoreValue(c,np,"real");
  3235. }
  3236. return rc;
  3237. }
  3238. cmDtRC_t _cmDataParserInt( cmDataParserCtx_t* c )
  3239. {
  3240. cmDtRC_t rc = kOkDtRC;
  3241. int val = cmLexTokenInt(c->p->lexH);
  3242. bool unsignedFl = cmLexTokenIsUnsigned(c->p->lexH);
  3243. if( cmDataIsPtr(c->cnp) )
  3244. rc = _cmDpStoreArrayEle(c,&val,sizeof(val),unsignedFl ? kUIntPtrDtId : kIntPtrDtId);
  3245. else
  3246. {
  3247. cmData_t* np = unsignedFl ? cmDataAllocUInt(NULL,val) : cmDataAllocInt(NULL,val);
  3248. rc = _cmDpStoreValue(c,np,"int");
  3249. }
  3250. return rc;
  3251. }
  3252. cmDtRC_t _cmDataParserString( cmDataParserCtx_t* c )
  3253. {
  3254. // if we are expecting a pair label
  3255. if( cmIsFlag(c->flags,kIdExpFl) )
  3256. return _cmDataParserOpenPair(c);
  3257. // otherwise a 'value' must be expected
  3258. if( cmIsNotFlag(c->flags,kValueExpFl) )
  3259. return _cmDpSyntaxErr(c,"Unexpected string.");
  3260. cmData_t* np = cmDataConstStrAllocN(NULL,cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH));
  3261. return _cmDpStoreValue(c,np,"string");
  3262. }
  3263. cmDtRC_t _cmDataParserOpenRecd( cmDataParserCtx_t* c )
  3264. {
  3265. cmDtRC_t rc = kOkDtRC;
  3266. // records are values - so we must be expecting a value
  3267. if( cmIsFlag(c->flags,kValueExpFl) == false )
  3268. return _cmDpSyntaxErr(c,"Unexpected '{'.");
  3269. // store the current node
  3270. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  3271. return rc;
  3272. // alloc a new record and make it the current node
  3273. if( (c->cnp = cmDataRecdAlloc(NULL)) == NULL )
  3274. return _cmDpSyntaxErr(c,"'recd' allocate failed.");
  3275. // new records must be followed by an id token.
  3276. c->flags = kIdExpFl;
  3277. return rc;
  3278. }
  3279. cmDtRC_t _cmDataParserCloseContainer( cmDataParserCtx_t* c, const cmChar_t* typeLabelStr )
  3280. {
  3281. cmDtRC_t rc;
  3282. cmData_t* np = c->cnp;
  3283. // make the parent node the new current node
  3284. if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
  3285. return rc;
  3286. return _cmDpStoreValue(c,np,typeLabelStr);
  3287. }
  3288. cmDtRC_t _cmDataParserCloseRecd( cmDataParserCtx_t* c )
  3289. {
  3290. assert( c->cnp->tid == kRecordDtId );
  3291. return _cmDataParserCloseContainer(c,"record");
  3292. }
  3293. cmDtRC_t _cmDataParserOpenList( cmDataParserCtx_t* c )
  3294. {
  3295. cmDtRC_t rc = kOkDtRC;
  3296. // lists are values - so we must be expecting a value
  3297. if( cmIsFlag(c->flags,kValueExpFl) == false )
  3298. return _cmDpSyntaxErr(c,"Unexpected '('.");
  3299. // store the current node
  3300. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  3301. return rc;
  3302. // create a new list
  3303. if( (c->cnp = cmDataListAlloc(NULL)) == NULL )
  3304. return _cmDpSyntaxErr(c,"'list' allocate failed.");
  3305. // new lists must be followed by a value
  3306. c->flags = kValueExpFl;
  3307. return rc;
  3308. }
  3309. cmDtRC_t _cmDataParserCloseList( cmDataParserCtx_t* c )
  3310. {
  3311. assert( c->cnp->tid == kListDtId );
  3312. return _cmDataParserCloseContainer(c,"list");
  3313. }
  3314. cmDtRC_t _cmDataParserOpenArray( cmDataParserCtx_t* c )
  3315. {
  3316. cmDtRC_t rc = kOkDtRC;
  3317. // arrays are values - so we must be expecting a value
  3318. if( cmIsFlag(c->flags,kValueExpFl) == false )
  3319. return _cmDpSyntaxErr(c,"Unexpected '('.");
  3320. // store the current node
  3321. if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC )
  3322. return rc;
  3323. // create a new array
  3324. if( (c->cnp = cmDataVoidAllocPtr(NULL, NULL, 0 )) == NULL )
  3325. return _cmDpSyntaxErr(c,"'array' allocate failed.");
  3326. // new arrays must be followed by a value
  3327. c->flags = kValueExpFl;
  3328. return rc;
  3329. }
  3330. cmDtRC_t _cmDataParserCloseArray( cmDataParserCtx_t* c )
  3331. {
  3332. assert( cmDataIsPtr(c->cnp) );
  3333. return _cmDataParserCloseContainer(c,"array");
  3334. }
  3335. cmDtRC_t _cmDataParserOnColon( cmDataParserCtx_t* c )
  3336. {
  3337. // colons only follow field identifiers and are always followed by values.
  3338. if( cmIsFlag(c->flags,kColonExpFl) == false )
  3339. return _cmDpSyntaxErr(c,"Unexpected colon.");
  3340. c->flags = kValueExpFl;
  3341. return kOkDtRC;
  3342. }
  3343. cmDtRC_t _cmDataParserOnComma( cmDataParserCtx_t* c )
  3344. {
  3345. // comma's may be found in three places:
  3346. // 1) following field values
  3347. // 2) between list values
  3348. // 3) between array values
  3349. // comma's are always followed by values
  3350. if( cmIsFlag(c->flags,kCommaExpFl) == false )
  3351. return _cmDpSyntaxErr(c, "Unexpected comma.");
  3352. c->flags = kValueExpFl;
  3353. return kOkDtRC;
  3354. }
  3355. cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp )
  3356. {
  3357. cmDtRC_t rc = kOkDtRC;
  3358. cmDataParser_t* p = _cmDataParserHandleToPtr(h);
  3359. unsigned tokenId;
  3360. cmDataParserCtx_t ctx;
  3361. cmData_t* root = cmDataRecdAlloc(NULL);
  3362. ctx.cnp = root;
  3363. ctx.p = p;
  3364. ctx.flags = kIdExpFl;
  3365. if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC )
  3366. return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset.");
  3367. cmStackClear(p->stH,false);
  3368. while(rc==kOkDtRC && (tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId )
  3369. {
  3370. switch(tokenId)
  3371. {
  3372. case kRealLexTId: // real number (contains a decimal point or is in scientific notation)
  3373. rc = _cmDataParserReal(&ctx);
  3374. break;
  3375. case kIntLexTId: // decimal integer
  3376. case kHexLexTId: // hexidecimal integer
  3377. rc = _cmDataParserInt(&ctx);
  3378. break;
  3379. case kIdentLexTId: // identifiers are treated as strings
  3380. case kQStrLexTId: // quoted string
  3381. rc = _cmDataParserString(&ctx);
  3382. break;
  3383. case kLCurlyLexTId: // a new record is starting
  3384. rc = _cmDataParserOpenRecd(&ctx);
  3385. break;
  3386. case kRCurlyLexTId: // the current record is finished
  3387. rc = _cmDataParserCloseRecd(&ctx);
  3388. break;
  3389. case kLParenLexTId: // a list is starting
  3390. rc = _cmDataParserOpenList(&ctx);
  3391. break;
  3392. case kRParenLexTId: // a list is finished
  3393. rc = _cmDataParserCloseList(&ctx);
  3394. break;
  3395. case kLBrackLexTId: // an array is starting
  3396. rc = _cmDataParserOpenArray(&ctx);
  3397. break;
  3398. case kRBrackLexTId: // an array is ending
  3399. rc = _cmDataParserCloseArray(&ctx);
  3400. break;
  3401. case kColonLexTId: // the previous id was a field id
  3402. rc = _cmDataParserOnColon(&ctx);
  3403. break;
  3404. case kCommaLexTId: // comma sep. for array or fields
  3405. rc = _cmDataParserOnComma(&ctx);
  3406. break;
  3407. case kBlockCmtLexTId: // block comment
  3408. case kLineCmtLexTId: // line comment
  3409. case kErrorLexTId: // the lexer was unable to identify the current token
  3410. case kUnknownLexTId: // the token is of an unknown type (only used when kReturnUnknownLexFl is set)
  3411. case kEofLexTId: // the lexer reached the end of input
  3412. case kSpaceLexTId: // white space
  3413. {
  3414. 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));
  3415. goto errLabel;
  3416. }
  3417. }
  3418. }
  3419. errLabel:
  3420. if( rc == kOkDtRC )
  3421. *pp = ctx.cnp;
  3422. else
  3423. {
  3424. if( ctx.cnp != root )
  3425. cmDataUnlinkAndFree(ctx.cnp);
  3426. cmDataUnlinkAndFree(root);
  3427. }
  3428. return rc;
  3429. }
  3430. //============================================================================
  3431. //============================================================================
  3432. //============================================================================
  3433. #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)
  3434. void _cmDataPrintIndent( cmRpt_t* rpt, unsigned indent )
  3435. {
  3436. unsigned j=0;
  3437. for(; j<indent; ++j)
  3438. cmRptPrintf(rpt," ");
  3439. }
  3440. void _cmDataPrint( const cmData_t* p, cmRpt_t* rpt, unsigned indent )
  3441. {
  3442. cmData_t* cp;
  3443. //_cmDataPrintIndent(rpt,indent);
  3444. switch(p->tid)
  3445. {
  3446. case kNullDtId: cmRptPrintf(rpt,"<null>"); break;
  3447. case kUCharDtId: cmRptPrintf(rpt,"%c ",cmDataUChar(p)); break;
  3448. case kCharDtId: cmRptPrintf(rpt,"%c ",cmDataChar(p)); break;
  3449. case kUShortDtId: cmRptPrintf(rpt,"%i ",cmDataUShort(p)); break;
  3450. case kShortDtId: cmRptPrintf(rpt,"%i ",cmDataShort(p)); break;
  3451. case kUIntDtId: cmRptPrintf(rpt,"%i ",cmDataUInt(p)); break;
  3452. case kIntDtId: cmRptPrintf(rpt,"%i ",cmDataInt(p)); break;
  3453. case kULongDtId: cmRptPrintf(rpt,"%i ",cmDataULong(p)); break;
  3454. case kLongDtId: cmRptPrintf(rpt,"%i ",cmDataLong(p)); break;
  3455. case kFloatDtId: cmRptPrintf(rpt,"%f ",cmDataFloat(p)); break;
  3456. case kDoubleDtId: cmRptPrintf(rpt,"%f ",cmDataDouble(p)); break;
  3457. case kStrDtId: cmRptPrintf(rpt,"%s ",cmDataStr(p)); break;
  3458. case kConstStrDtId: cmRptPrintf(rpt,"%s ",cmDataConstStr(p)); break;
  3459. case kUCharPtrDtId: parr(rpt,"%c ",cmDataUCharPtr(p), p->cnt); break;
  3460. case kCharPtrDtId: parr(rpt,"%c ",cmDataCharPtr(p), p->cnt); break;
  3461. case kUShortPtrDtId: parr(rpt,"%i ",cmDataUShortPtr(p),p->cnt); break;
  3462. case kShortPtrDtId: parr(rpt,"%i ",cmDataShortPtr(p), p->cnt); break;
  3463. case kUIntPtrDtId: parr(rpt,"%i ",cmDataUIntPtr(p), p->cnt); break;
  3464. case kIntPtrDtId: parr(rpt,"%i ",cmDataIntPtr(p), p->cnt); break;
  3465. case kULongPtrDtId: parr(rpt,"%i ",cmDataULongPtr(p), p->cnt); break;
  3466. case kLongPtrDtId: parr(rpt,"%i ",cmDataLongPtr(p), p->cnt); break;
  3467. case kFloatPtrDtId: parr(rpt,"%f ",cmDataFloatPtr(p), p->cnt); break;
  3468. case kDoublePtrDtId: parr(rpt,"%f ",cmDataDoublePtr(p),p->cnt); break;
  3469. case kVoidPtrDtId: cmRptPrintf(rpt,"<void:%i>",p->cnt); break;
  3470. case kPairDtId:
  3471. _cmDataPrint(p->u.child,rpt,indent);
  3472. cmRptPrintf(rpt," : ");
  3473. _cmDataPrint(p->u.child->sibling,rpt,indent);
  3474. cmRptPrintf(rpt,"\n");
  3475. break;
  3476. case kListDtId:
  3477. cmRptPrintf(rpt,"(\n");
  3478. indent += 2;
  3479. cp = p->u.child;
  3480. for(; cp!=NULL; cp=cp->sibling)
  3481. {
  3482. _cmDataPrintIndent(rpt,indent);
  3483. _cmDataPrint(cp,rpt,indent);
  3484. cmRptPrintf(rpt,"\n");
  3485. }
  3486. indent -= 2;
  3487. _cmDataPrintIndent(rpt,indent);
  3488. cmRptPrintf(rpt,")\n");
  3489. break;
  3490. case kRecordDtId:
  3491. cmRptPrintf(rpt,"{\n");
  3492. indent += 2;
  3493. cp = p->u.child;
  3494. for(; cp!=NULL; cp=cp->sibling)
  3495. {
  3496. _cmDataPrintIndent(rpt,indent);
  3497. _cmDataPrint(cp,rpt, indent);
  3498. }
  3499. indent -= 2;
  3500. _cmDataPrintIndent(rpt,indent);
  3501. cmRptPrintf(rpt,"}\n");
  3502. break;
  3503. default:
  3504. break;
  3505. }
  3506. }
  3507. void cmDataPrint( const cmData_t* p, cmRpt_t* rpt )
  3508. { _cmDataPrint(p,rpt,0); }
  3509. cmDtRC_t cmDataParserTest( cmCtx_t* ctx )
  3510. {
  3511. cmDtRC_t rc = kOkDtRC;
  3512. cmDataParserH_t h = cmDataParserNullHandle;
  3513. cmErr_t err;
  3514. cmData_t* dp = NULL;
  3515. const cmChar_t text[] =
  3516. {
  3517. //0 1 2 3
  3518. //0123456789012345678901234567890123
  3519. "f0:1.23 f1:\"hey\" f2:( a b c ) f3:[ 0f 1f 2f ]"
  3520. //"f0:1.23 f1:\"hey\""
  3521. };
  3522. cmErrSetup(&err,&ctx->rpt,"Data Parser Tester");
  3523. if((rc = cmDataParserCreate(ctx, &h )) != kOkDtRC )
  3524. {
  3525. rc = cmErrMsg(&err,rc,"Data parser create failed.");
  3526. goto errLabel;
  3527. }
  3528. if( cmDataParserExec(h,text,&dp) != kOkDtRC )
  3529. rc = cmErrMsg(&err,rc,"Data parser exec failed.");
  3530. else
  3531. if( dp != NULL )
  3532. cmDataPrint(dp,&ctx->rpt);
  3533. errLabel:
  3534. if( cmDataParserDestroy( &h ) != kOkDtRC )
  3535. {
  3536. rc = cmErrMsg(&err,rc,"Data parser destroy failed.");
  3537. goto errLabel;
  3538. }
  3539. cmDataFree(dp);
  3540. return rc;
  3541. }
  3542. void cmDataTest( cmCtx_t* ctx )
  3543. {
  3544. float farr[] = { 1.23, 45.6, 7.89 };
  3545. cmDataParserTest(ctx);
  3546. return;
  3547. cmData_t* d0 = cmDataRecdAllocLabelA(NULL,
  3548. "name",kConstStrDtId,"This is a string.",
  3549. "id", kUIntDtId, 21,
  3550. "real",kFloatDtId, 1.23,
  3551. "arr", kFloatPtrDtId, farr, 3,
  3552. NULL);
  3553. cmDataPrint(d0,&ctx->rpt);
  3554. cmDataFree(d0);
  3555. cmData_t* d1 = cmDataListAllocA(NULL,
  3556. kUIntDtId, 53,
  3557. kStrDtId, "Blah blah",
  3558. kFloatPtrDtId, farr, 3,
  3559. kInvalidDtId );
  3560. cmDataPrint(d1,&ctx->rpt);
  3561. cmDataFree(d1);
  3562. cmRptPrintf(&ctx->rpt,"Done!.\n");
  3563. }
  3564. #endif