rtlfield.cpp 152 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "platform.h"
  14. #include <math.h>
  15. #include <stdio.h>
  16. #include <atomic>
  17. #include <algorithm>
  18. #include "jmisc.hpp"
  19. #include "jlib.hpp"
  20. #include "eclhelper.hpp"
  21. #include "eclrtl_imp.hpp"
  22. #include "rtlfield.hpp"
  23. #include "rtlds_imp.hpp"
  24. #include "rtlrecord.hpp"
  25. #include "rtlkey.hpp"
  26. #include "nbcd.hpp"
  27. #include "rtlqstr.ipp"
  28. static const char * queryXPath(const RtlFieldInfo * field)
  29. {
  30. const char * xpath = field->xpath;
  31. if (xpath)
  32. {
  33. const char * sep = strchr(xpath, xpathCompoundSeparatorChar);
  34. if (!sep)
  35. return xpath;
  36. return sep+1;
  37. }
  38. return field->name;
  39. }
  40. static const char * queryScalarXPath(const RtlFieldInfo * field)
  41. {
  42. if (field->hasNonScalarXpath())
  43. return field->name;
  44. return queryXPath(field);
  45. }
  46. static bool hasOuterXPath(const RtlFieldInfo * field)
  47. {
  48. const char * xpath = field->xpath;
  49. assertex(xpath);
  50. return (*xpath != xpathCompoundSeparatorChar);
  51. }
  52. static void queryNestedOuterXPath(StringAttr & ret, const RtlFieldInfo * field)
  53. {
  54. const char * xpath = field->xpath;
  55. assertex(xpath);
  56. const char * sep = strchr(xpath, xpathCompoundSeparatorChar);
  57. assertex(sep);
  58. ret.set(xpath, (size32_t)(sep-xpath));
  59. }
  60. inline const char * queryName(const RtlFieldInfo * field) { return field ? field->name : nullptr; }
  61. //-------------------------------------------------------------------------------------------------------------------
  62. static bool incrementBuffer(byte *buf, size32_t size)
  63. {
  64. int i = size;
  65. while (i--)
  66. {
  67. buf[i]++;
  68. if (buf[i]!=0)
  69. return true;
  70. }
  71. return false;
  72. }
  73. static bool decrementBuffer(byte *buf, size32_t size)
  74. {
  75. int i = size;
  76. while (i--)
  77. {
  78. buf[i]--;
  79. if (buf[i]!=0xff)
  80. return true;
  81. }
  82. return false;
  83. }
  84. //-------------------------------------------------------------------------------------------------------------------
  85. class DummyFieldProcessor : public CInterfaceOf<IFieldProcessor>
  86. {
  87. public:
  88. virtual void processString(unsigned len, const char *value, const RtlFieldInfo * field) {}
  89. virtual void processBool(bool value, const RtlFieldInfo * field) {}
  90. virtual void processData(unsigned len, const void *value, const RtlFieldInfo * field) {}
  91. virtual void processInt(__int64 value, const RtlFieldInfo * field) {}
  92. virtual void processUInt(unsigned __int64 value, const RtlFieldInfo * field) {}
  93. virtual void processReal(double value, const RtlFieldInfo * field) {}
  94. virtual void processDecimal(const void *value, unsigned digits, unsigned precision, const RtlFieldInfo * field) {}
  95. virtual void processUDecimal(const void *value, unsigned digits, unsigned precision, const RtlFieldInfo * field) {}
  96. virtual void processUnicode(unsigned len, const UChar *value, const RtlFieldInfo * field) {}
  97. virtual void processQString(unsigned len, const char *value, const RtlFieldInfo * field) {}
  98. virtual void processUtf8(unsigned len, const char *value, const RtlFieldInfo * field) {}
  99. virtual bool processBeginSet(const RtlFieldInfo * field, unsigned numElements, bool isAll, const byte *data) { return false; }
  100. virtual bool processBeginDataset(const RtlFieldInfo * field, unsigned numRows) { return true; }
  101. virtual bool processBeginRow(const RtlFieldInfo * field) { return true; }
  102. virtual void processEndSet(const RtlFieldInfo * field) {}
  103. virtual void processEndDataset(const RtlFieldInfo * field) {}
  104. virtual void processEndRow(const RtlFieldInfo * field) {}
  105. };
  106. //-------------------------------------------------------------------------------------------------------------------
  107. size32_t ECLRTL_API getMinSize(const RtlFieldInfo * const * fields)
  108. {
  109. size32_t minSize = 0;
  110. for(;;)
  111. {
  112. const RtlFieldInfo * cur = *fields;
  113. if (!cur)
  114. return minSize;
  115. minSize += cur->type->getMinSize();
  116. fields++;
  117. }
  118. }
  119. //-------------------------------------------------------------------------------------------------------------------
  120. size32_t RtlTypeInfoBase::getMinSize() const
  121. {
  122. return length;
  123. }
  124. size32_t RtlTypeInfoBase::size(const byte * self, const byte * selfrow) const
  125. {
  126. return length;
  127. }
  128. size32_t RtlTypeInfoBase::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  129. {
  130. rtlFailUnexpected();
  131. return 0;
  132. }
  133. size32_t RtlTypeInfoBase::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & out) const
  134. {
  135. rtlFailUnexpected();
  136. return 0;
  137. }
  138. size32_t RtlTypeInfoBase::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  139. {
  140. rtlFailUnexpected();
  141. return 0;
  142. }
  143. size32_t RtlTypeInfoBase::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
  144. {
  145. if (field->initializer && !isVirtualInitializer(field->initializer))
  146. {
  147. size32_t initSize = size((const byte *) field->initializer, nullptr);
  148. builder.ensureCapacity(offset+initSize, queryName(field));
  149. memcpy(builder.getSelf()+offset, field->initializer, initSize);
  150. return offset+initSize;
  151. }
  152. else
  153. {
  154. // This code covers a lot (though not all) of the derived cases
  155. size32_t initSize = getMinSize();
  156. builder.ensureCapacity(offset+initSize, queryName(field));
  157. memset(builder.getSelf() + offset, 0, initSize);
  158. return offset + initSize;
  159. }
  160. }
  161. size32_t RtlTypeInfoBase::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  162. {
  163. size32_t newLen;
  164. rtlDataAttr temp;
  165. rtlInt8ToStrX(newLen, temp.refstr(), val);
  166. return buildString(builder, offset, field, newLen, temp.getstr());
  167. }
  168. size32_t RtlTypeInfoBase::buildReal(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, double val) const
  169. {
  170. size32_t newLen;
  171. rtlDataAttr temp;
  172. rtlRealToStrX(newLen, temp.refstr(), val);
  173. return buildString(builder, offset, field, newLen, temp.getstr());
  174. }
  175. double RtlTypeInfoBase::getReal(const void * ptr) const
  176. {
  177. size32_t len;
  178. rtlDataAttr value;
  179. getString(len, value.refstr(), ptr);
  180. return rtlStrToReal(len, value.getstr());
  181. }
  182. bool RtlTypeInfoBase::equivalent(const RtlTypeInfo *to) const
  183. {
  184. if (to==this)
  185. return true;
  186. if (!to)
  187. return false;
  188. if (to->length != length || to->fieldType != fieldType)
  189. return false;
  190. if (queryLocale())
  191. {
  192. // do we permit a locale difference?
  193. }
  194. auto child = queryChildType();
  195. if (child && !child->equivalent(to->queryChildType()))
  196. return false;
  197. auto fields = queryFields();
  198. if (fields)
  199. {
  200. auto tofields = to->queryFields();
  201. if (!tofields)
  202. return false; // Should never happen
  203. for (unsigned idx = 0; fields[idx]; idx++)
  204. {
  205. if (!fields[idx]->equivalent(tofields[idx]))
  206. return false;
  207. }
  208. }
  209. return true;
  210. }
  211. static bool strequivalent(const char *name1, const char *name2)
  212. {
  213. if (name1)
  214. return name2 && streq(name1, name2);
  215. else
  216. return name2==nullptr;
  217. }
  218. bool RtlFieldInfo::equivalent(const RtlFieldInfo *to) const
  219. {
  220. if (to==this)
  221. return true;
  222. if (!to)
  223. return false;
  224. if (!strequivalent(name, to->name))
  225. return false;
  226. if (!strequivalent(xpath, to->xpath))
  227. return false;
  228. if (!type->equivalent(to->type))
  229. return false;
  230. // Initializer differences can be ignored
  231. if (flags != to->flags)
  232. return false;
  233. return true;
  234. }
  235. const char * RtlTypeInfoBase::queryLocale() const
  236. {
  237. return NULL;
  238. }
  239. bool RtlTypeInfoBase::isScalar() const
  240. {
  241. return true;
  242. }
  243. const RtlFieldInfo * const * RtlTypeInfoBase::queryFields() const
  244. {
  245. return NULL;
  246. }
  247. const RtlTypeInfo * RtlTypeInfoBase::queryChildType() const
  248. {
  249. return NULL;
  250. }
  251. const IFieldFilter * RtlTypeInfoBase::queryFilter() const
  252. {
  253. return nullptr;
  254. }
  255. size32_t RtlTypeInfoBase::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  256. {
  257. size32_t thisSize = size(nullptr, nullptr);
  258. byte * dest = builder.ensureCapacity(offset + thisSize, nullptr) + offset;
  259. in.read(thisSize, dest);
  260. return offset + thisSize;
  261. }
  262. void RtlTypeInfoBase::readAhead(IRowPrefetcherSource & in) const
  263. {
  264. size32_t thisSize = size(nullptr, nullptr);
  265. in.skip(thisSize);
  266. }
  267. size32_t RtlTypeInfoBase::buildUtf8ViaString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  268. {
  269. size32_t newLen;
  270. rtlDataAttr temp;
  271. rtlUtf8ToStrX(newLen, temp.refstr(), len, value);
  272. return buildString(builder, offset, field, newLen, temp.getstr());
  273. }
  274. void RtlTypeInfoBase::getUtf8ViaString(size32_t & resultLen, char * & result, const void * ptr) const
  275. {
  276. size32_t newLen;
  277. rtlDataAttr temp;
  278. getString(newLen, temp.refstr(), ptr);
  279. rtlStrToUtf8X(resultLen, result, newLen, temp.getstr());
  280. }
  281. int RtlTypeInfoBase::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  282. {
  283. throwUnexpected();
  284. }
  285. void RtlTypeInfoBase::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  286. {
  287. byte *dst = (byte *) buffer;
  288. size32_t minSize = getMinSize();
  289. if (value)
  290. {
  291. assertex(isFixedSize() || (inclusive && (subLength == MatchFullString)));
  292. size32_t copySize;
  293. if (subLength != MatchFullString)
  294. {
  295. if (isFixedSize())
  296. {
  297. //For a substring comparison, clear the bytes after subLength - eventually they should never be compared
  298. //but currently the index code uses memcmp() so they need to be initialised
  299. unsigned copyLen = std::min(length, subLength);
  300. copySize = copyLen;
  301. memcpy(dst, value, copySize);
  302. memset(dst+copySize, fill, minSize-copySize);
  303. }
  304. else
  305. {
  306. assertex(inclusive);
  307. size32_t copyLen = std::min(rtlReadSize32t(value), subLength);
  308. copySize = copyLen;
  309. *(size32_t *)buffer = copyLen;
  310. memcpy(dst + sizeof(size32_t), value + sizeof(size32_t), copySize);
  311. }
  312. }
  313. else
  314. {
  315. copySize = size(value, nullptr);
  316. memcpy(dst, value, copySize);
  317. }
  318. if (!inclusive)
  319. {
  320. if (fill == 0)
  321. incrementBuffer(dst, copySize);
  322. else
  323. decrementBuffer(dst, copySize);
  324. }
  325. }
  326. else
  327. {
  328. //Generally cannot work for variable length fields - since always possible to create a larger value
  329. //Default does not work for real types, or variable length signed integers
  330. assertex((fill == 0) || isFixedSize());
  331. memset(dst, fill, minSize);
  332. }
  333. }
  334. void RtlTypeInfoBase::setLowBound(void * buffer, const byte * value, size32_t subLength, bool inclusive) const
  335. {
  336. setBound(buffer, value, subLength, 0, inclusive);
  337. }
  338. void RtlTypeInfoBase::setHighBound(void * buffer, const byte * value, size32_t subLength, bool inclusive) const
  339. {
  340. setBound(buffer, value, subLength, 0xff, inclusive);
  341. }
  342. //-------------------------------------------------------------------------------------------------------------------
  343. size32_t RtlBoolTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  344. {
  345. builder.ensureCapacity(sizeof(bool)+offset, queryName(field));
  346. bool val = source.getBooleanResult(field);
  347. * (bool *) (builder.getSelf() + offset) = val;
  348. offset += sizeof(bool);
  349. return offset;
  350. }
  351. size32_t RtlBoolTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  352. {
  353. builder.ensureCapacity(sizeof(bool)+offset, queryName(field));
  354. * (bool *) (builder.getSelf() + offset) = val != 0;
  355. offset += sizeof(bool);
  356. return offset;
  357. }
  358. size32_t RtlBoolTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  359. {
  360. return buildInt(builder, offset, field, rtlStrToBool(len, value));
  361. }
  362. size32_t RtlBoolTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  363. {
  364. size32_t size = rtlUtf8Length(len, value);
  365. return buildInt(builder, offset, field, rtlStrToBool(size, value));
  366. }
  367. size32_t RtlBoolTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  368. {
  369. target.processBool(*(const bool *)self, field);
  370. return sizeof(bool);
  371. }
  372. size32_t RtlBoolTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  373. {
  374. target.outputBool(*(const bool *)self, queryScalarXPath(field));
  375. return sizeof(bool);
  376. }
  377. void RtlBoolTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  378. {
  379. const bool * cast = static_cast<const bool *>(ptr);
  380. rtlBoolToStrX(resultLen, result, *cast);
  381. }
  382. void RtlBoolTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  383. {
  384. getString(resultLen, result, ptr);
  385. }
  386. __int64 RtlBoolTypeInfo::getInt(const void * ptr) const
  387. {
  388. const bool * cast = static_cast<const bool *>(ptr);
  389. return (__int64)*cast;
  390. }
  391. bool RtlBoolTypeInfo::getBool(const void * ptr) const
  392. {
  393. const bool * cast = static_cast<const bool *>(ptr);
  394. return *cast;
  395. }
  396. int RtlBoolTypeInfo::compare(const byte * left, const byte * right) const
  397. {
  398. bool leftValue = getBool(left);
  399. bool rightValue = getBool (right);
  400. return (!leftValue && rightValue) ? -1 : (leftValue && !rightValue) ? +1 : 0;
  401. }
  402. unsigned RtlBoolTypeInfo::hash(const byte *self, unsigned inhash) const
  403. {
  404. __int64 val = getInt(self);
  405. return rtlHash32Data8(&val, inhash);
  406. }
  407. //-------------------------------------------------------------------------------------------------------------------
  408. double RtlRealTypeInfo::value(const void * self) const
  409. {
  410. if (length == 4)
  411. return *(const float *)self;
  412. return *(const double *)self;
  413. }
  414. size32_t RtlRealTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  415. {
  416. double val = source.getRealResult(field);
  417. return buildReal(builder, offset, field, val);
  418. }
  419. size32_t RtlRealTypeInfo::buildReal(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, double val) const
  420. {
  421. byte *dest = builder.ensureCapacity(length+offset, queryName(field)) + offset;
  422. if (length == 4)
  423. *(float *) dest = (float) val;
  424. else
  425. *(double *) dest = val;
  426. offset += length;
  427. return offset;
  428. }
  429. size32_t RtlRealTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  430. {
  431. return buildReal(builder, offset, field, rtlStrToReal(len, value));
  432. }
  433. size32_t RtlRealTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  434. {
  435. size32_t size = rtlUtf8Length(len, value);
  436. return buildReal(builder, offset, field, rtlStrToReal(size, value));
  437. }
  438. size32_t RtlRealTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  439. {
  440. target.processReal(value(self), field);
  441. return length;
  442. }
  443. size32_t RtlRealTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  444. {
  445. target.outputReal(value(self), queryScalarXPath(field));
  446. return length;
  447. }
  448. void RtlRealTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  449. {
  450. double num = value(ptr);
  451. rtlRealToStrX(resultLen, result, num);
  452. }
  453. void RtlRealTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  454. {
  455. getString(resultLen, result, ptr);
  456. }
  457. __int64 RtlRealTypeInfo::getInt(const void * ptr) const
  458. {
  459. double num = value(ptr);
  460. return (__int64)num;
  461. }
  462. double RtlRealTypeInfo::getReal(const void * ptr) const
  463. {
  464. return value(ptr);
  465. }
  466. int RtlRealTypeInfo::compare(const byte * left, const byte * right) const
  467. {
  468. double leftValue = getReal(left);
  469. double rightValue = getReal(right);
  470. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  471. }
  472. unsigned RtlRealTypeInfo::hash(const byte *self, unsigned inhash) const
  473. {
  474. double val = getReal(self);
  475. return rtlHash32Data8(&val, inhash);
  476. }
  477. void RtlRealTypeInfo::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  478. {
  479. assertex(subLength == MatchFullString);
  480. double dvalue;
  481. float fvalue;
  482. if (value)
  483. {
  484. assertex(inclusive);
  485. }
  486. else
  487. {
  488. dvalue = rtlCreateRealInf();
  489. if (fill == 0)
  490. dvalue = -dvalue;
  491. if (length == 4)
  492. {
  493. fvalue = dvalue;
  494. value = reinterpret_cast<const byte *>(&fvalue);
  495. }
  496. else
  497. value = reinterpret_cast<const byte *>(&dvalue);
  498. }
  499. memcpy(buffer, value, length);
  500. }
  501. //-------------------------------------------------------------------------------------------------------------------
  502. size32_t RtlIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  503. {
  504. builder.ensureCapacity(length+offset, queryName(field));
  505. __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  506. rtlWriteInt(builder.getSelf() + offset, val, length);
  507. offset += length;
  508. return offset;
  509. }
  510. size32_t RtlIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  511. {
  512. builder.ensureCapacity(length+offset, queryName(field));
  513. rtlWriteInt(builder.getSelf() + offset, val, length);
  514. offset += length;
  515. return offset;
  516. }
  517. size32_t RtlIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  518. {
  519. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  520. }
  521. size32_t RtlIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  522. {
  523. size32_t size = rtlUtf8Length(len, value);
  524. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  525. }
  526. size32_t RtlIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  527. {
  528. if (isUnsigned())
  529. target.processUInt(rtlReadUInt(self, length), field);
  530. else
  531. target.processInt(rtlReadInt(self, length), field);
  532. return length;
  533. }
  534. size32_t RtlIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  535. {
  536. if (isUnsigned())
  537. target.outputUInt(rtlReadUInt(self, length), length, queryScalarXPath(field));
  538. else
  539. target.outputInt(rtlReadInt(self, length), length, queryScalarXPath(field));
  540. return length;
  541. }
  542. void RtlIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  543. {
  544. if (isUnsigned())
  545. rtlUInt8ToStrX(resultLen, result, rtlReadUInt(ptr, length));
  546. else
  547. rtlInt8ToStrX(resultLen, result, rtlReadInt(ptr, length));
  548. }
  549. void RtlIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  550. {
  551. getString(resultLen, result, ptr);
  552. }
  553. __int64 RtlIntTypeInfo::getInt(const void * ptr) const
  554. {
  555. if (isUnsigned())
  556. return rtlReadUInt(ptr, length);
  557. else
  558. return rtlReadInt(ptr, length);
  559. }
  560. double RtlIntTypeInfo::getReal(const void * ptr) const
  561. {
  562. if (isUnsigned())
  563. return (double) rtlReadUInt(ptr, length);
  564. else
  565. return (double) rtlReadInt(ptr, length);
  566. }
  567. int RtlIntTypeInfo::compare(const byte * left, const byte * right) const
  568. {
  569. if (isUnsigned())
  570. {
  571. unsigned __int64 leftValue = rtlReadUInt(left, length);
  572. unsigned __int64 rightValue = rtlReadUInt(right, length);
  573. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  574. }
  575. else
  576. {
  577. __int64 leftValue = rtlReadInt(left, length);
  578. __int64 rightValue = rtlReadInt(right, length);
  579. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  580. }
  581. }
  582. bool RtlIntTypeInfo::canMemCmp() const
  583. {
  584. #if __BYTE_ORDER == __LITTLE_ENDIAN
  585. return false;
  586. #else
  587. return isUnsigned();
  588. #endif
  589. }
  590. unsigned RtlIntTypeInfo::hash(const byte *self, unsigned inhash) const
  591. {
  592. __int64 val = getInt(self);
  593. return rtlHash32Data8(&val, inhash);
  594. }
  595. bool RtlIntTypeInfo::canTruncate() const
  596. {
  597. #if __BYTE_ORDER == __LITTLE_ENDIAN
  598. return true;
  599. #else
  600. return false;
  601. #endif
  602. }
  603. bool RtlIntTypeInfo::canExtend(char &fillChar) const
  604. {
  605. #if __BYTE_ORDER == __LITTLE_ENDIAN
  606. fillChar = 0;
  607. return true;
  608. #else
  609. return false;
  610. #endif
  611. }
  612. //-------------------------------------------------------------------------------------------------------------------
  613. size32_t RtlBlobTypeInfo::getMinSize() const
  614. {
  615. return sizeof(offset_t);
  616. }
  617. size32_t RtlBlobTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  618. {
  619. throwUnexpected(); // This is only expected to be used for reading at present
  620. }
  621. size32_t RtlBlobTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  622. {
  623. throwUnexpected(); // This is only expected to be used for reading at present
  624. }
  625. size32_t RtlBlobTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  626. {
  627. throwUnexpected(); // This is only expected to be used for reading at present
  628. }
  629. size32_t RtlBlobTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  630. {
  631. throwUnexpected(); // This is only expected to be used for reading at present
  632. }
  633. size32_t RtlBlobTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  634. {
  635. UNIMPLEMENTED;
  636. }
  637. size32_t RtlBlobTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  638. {
  639. UNIMPLEMENTED;
  640. }
  641. void RtlBlobTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  642. {
  643. UNIMPLEMENTED;
  644. }
  645. void RtlBlobTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  646. {
  647. UNIMPLEMENTED;
  648. }
  649. __int64 RtlBlobTypeInfo::getInt(const void * ptr) const
  650. {
  651. return *(offset_t *) ptr;
  652. }
  653. double RtlBlobTypeInfo::getReal(const void * ptr) const
  654. {
  655. UNIMPLEMENTED;
  656. }
  657. bool RtlBlobTypeInfo::canTruncate() const
  658. {
  659. return false;
  660. }
  661. bool RtlBlobTypeInfo::canExtend(char &fillChar) const
  662. {
  663. return false;
  664. }
  665. int RtlBlobTypeInfo::compare(const byte * left, const byte * right) const
  666. {
  667. UNIMPLEMENTED;
  668. }
  669. unsigned RtlBlobTypeInfo::hash(const byte *self, unsigned inhash) const
  670. {
  671. UNIMPLEMENTED;
  672. }
  673. //-------------------------------------------------------------------------------------------------------------------
  674. size32_t RtlSwapIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  675. {
  676. builder.ensureCapacity(length+offset, queryName(field));
  677. __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  678. // NOTE - we assume that the value returned from the source is NOT already a swapped int - source doesn't know that we are going to store it swapped
  679. rtlWriteSwapInt(builder.getSelf() + offset, val, length);
  680. offset += length;
  681. return offset;
  682. }
  683. size32_t RtlSwapIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  684. {
  685. builder.ensureCapacity(length+offset, queryName(field));
  686. rtlWriteSwapInt(builder.getSelf() + offset, val, length);
  687. offset += length;
  688. return offset;
  689. }
  690. size32_t RtlSwapIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  691. {
  692. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  693. }
  694. size32_t RtlSwapIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  695. {
  696. size32_t size = rtlUtf8Length(len, value);
  697. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  698. }
  699. size32_t RtlSwapIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  700. {
  701. if (isUnsigned())
  702. target.processUInt(rtlReadSwapUInt(self, length), field);
  703. else
  704. target.processInt(rtlReadSwapInt(self, length), field);
  705. return length;
  706. }
  707. size32_t RtlSwapIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  708. {
  709. if (isUnsigned())
  710. target.outputUInt(rtlReadSwapUInt(self, length), length, queryScalarXPath(field));
  711. else
  712. target.outputInt(rtlReadSwapInt(self, length), length, queryScalarXPath(field));
  713. return length;
  714. }
  715. void RtlSwapIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  716. {
  717. if (isUnsigned())
  718. rtlUInt8ToStrX(resultLen, result, rtlReadSwapUInt(ptr, length));
  719. else
  720. rtlInt8ToStrX(resultLen, result, rtlReadSwapInt(ptr, length));
  721. }
  722. void RtlSwapIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  723. {
  724. getString(resultLen, result, ptr);
  725. }
  726. __int64 RtlSwapIntTypeInfo::getInt(const void * ptr) const
  727. {
  728. if (isUnsigned())
  729. return rtlReadSwapUInt(ptr, length);
  730. else
  731. return rtlReadSwapInt(ptr, length);
  732. }
  733. double RtlSwapIntTypeInfo::getReal(const void * ptr) const
  734. {
  735. if (isUnsigned())
  736. return (double) rtlReadSwapUInt(ptr, length);
  737. else
  738. return (double) (rtlReadSwapInt(ptr, length));
  739. }
  740. int RtlSwapIntTypeInfo::compare(const byte * left, const byte * right) const
  741. {
  742. if (isUnsigned())
  743. {
  744. unsigned __int64 leftValue = rtlReadSwapUInt(left, length);
  745. unsigned __int64 rightValue = rtlReadSwapUInt(right, length);
  746. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  747. }
  748. else
  749. {
  750. __int64 leftValue = rtlReadSwapInt(left, length);
  751. __int64 rightValue = rtlReadSwapInt(right, length);
  752. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  753. }
  754. }
  755. bool RtlSwapIntTypeInfo::canMemCmp() const
  756. {
  757. #if __BYTE_ORDER == __LITTLE_ENDIAN
  758. return isUnsigned();
  759. #else
  760. return false;
  761. #endif
  762. }
  763. unsigned RtlSwapIntTypeInfo::hash(const byte *self, unsigned inhash) const
  764. {
  765. __int64 val = getInt(self);
  766. return rtlHash32Data8(&val, inhash);
  767. }
  768. bool RtlSwapIntTypeInfo::canTruncate() const
  769. {
  770. #if __BYTE_ORDER == __LITTLE_ENDIAN
  771. return false;
  772. #else
  773. return true;
  774. #endif
  775. }
  776. bool RtlSwapIntTypeInfo::canExtend(char &fillChar) const
  777. {
  778. #if __BYTE_ORDER == __LITTLE_ENDIAN
  779. return false;
  780. #else
  781. fillChar = 0;
  782. return true;
  783. #endif
  784. }
  785. //-------------------------------------------------------------------------------------------------------------------
  786. size32_t RtlKeyedIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  787. {
  788. __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  789. return buildInt(builder, offset, field, val);
  790. }
  791. size32_t RtlKeyedIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  792. {
  793. builder.ensureCapacity(length+offset, queryName(field));
  794. if (isUnsigned())
  795. #if __BYTE_ORDER == __LITTLE_ENDIAN
  796. rtlWriteSwapInt(builder.getSelf() + offset, val, length);
  797. #else
  798. rtlWriteInt(builder.getSelf() + offset, val, length);
  799. #endif
  800. else
  801. #if __BYTE_ORDER == __LITTLE_ENDIAN
  802. rtlWriteSwapInt(builder.getSelf() + offset, addBias(val, length), length);
  803. #else
  804. rtlWriteInt(builder.getSelf() + offset, addBias(val, length), length);
  805. #endif
  806. offset += length;
  807. return offset;
  808. }
  809. size32_t RtlKeyedIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  810. {
  811. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  812. }
  813. size32_t RtlKeyedIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  814. {
  815. size32_t size = rtlUtf8Length(len, value);
  816. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  817. }
  818. size32_t RtlKeyedIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  819. {
  820. if (isUnsigned())
  821. target.processUInt(getUInt(self), field);
  822. else
  823. target.processInt(getInt(self), field);
  824. return length;
  825. }
  826. size32_t RtlKeyedIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  827. {
  828. if (isUnsigned())
  829. target.outputUInt(getUInt(self), length, queryScalarXPath(field));
  830. else
  831. target.outputInt(getInt(self), length, queryScalarXPath(field));
  832. return length;
  833. }
  834. void RtlKeyedIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  835. {
  836. if (isUnsigned())
  837. rtlUInt8ToStrX(resultLen, result, getUInt(ptr));
  838. else
  839. rtlInt8ToStrX(resultLen, result, getInt(ptr));
  840. }
  841. void RtlKeyedIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  842. {
  843. getString(resultLen, result, ptr);
  844. }
  845. __int64 RtlKeyedIntTypeInfo::getInt(const void * ptr) const
  846. {
  847. #if __BYTE_ORDER == __LITTLE_ENDIAN
  848. if (isUnsigned())
  849. return rtlReadSwapUInt(ptr, length);
  850. else
  851. return removeBias(rtlReadSwapUInt(ptr, length), length);
  852. #else
  853. if (isUnsigned())
  854. return rtlReadUInt(ptr, length);
  855. else
  856. return removeBias(rtlReadInt(ptr, length), length);
  857. #endif
  858. }
  859. double RtlKeyedIntTypeInfo::getReal(const void * ptr) const
  860. {
  861. if (isUnsigned())
  862. return (double) getUInt(ptr);
  863. else
  864. return (double) getInt(ptr);
  865. }
  866. int RtlKeyedIntTypeInfo::compare(const byte * left, const byte * right) const
  867. {
  868. // The whole point of biased ints is that we can do this:
  869. return memcmp(left, right, length);
  870. }
  871. unsigned RtlKeyedIntTypeInfo::hash(const byte *self, unsigned inhash) const
  872. {
  873. __int64 val = getInt(self);
  874. return rtlHash32Data8(&val, inhash);
  875. }
  876. unsigned __int64 RtlKeyedIntTypeInfo::addBias(__int64 value, unsigned length)
  877. {
  878. return value + ((unsigned __int64)1 << (length*8-1));
  879. }
  880. __int64 RtlKeyedIntTypeInfo::removeBias(unsigned __int64 value, unsigned length)
  881. {
  882. return value - ((unsigned __int64)1 << (length*8-1));
  883. }
  884. const RtlTypeInfo * RtlKeyedIntTypeInfo::queryChildType() const
  885. {
  886. return child;
  887. }
  888. //-------------------------------------------------------------------------------------------------------------------
  889. size32_t RtlPackedIntTypeInfo::getMinSize() const
  890. {
  891. return 1;
  892. }
  893. size32_t RtlPackedIntTypeInfo::size(const byte * self, const byte * selfrow) const
  894. {
  895. return rtlGetPackedSize(self);
  896. }
  897. size32_t RtlPackedIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  898. {
  899. __int64 value = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  900. return buildInt(builder, offset, field, value);
  901. }
  902. size32_t RtlPackedIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  903. {
  904. size32_t sizeInBytes = rtlGetPackedSize(&val);
  905. builder.ensureCapacity(sizeInBytes+offset, queryName(field));
  906. rtlSetPackedUnsigned(builder.getSelf() + offset, val);
  907. offset += sizeInBytes;
  908. return offset;
  909. }
  910. size32_t RtlPackedIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  911. {
  912. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  913. }
  914. size32_t RtlPackedIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  915. {
  916. size32_t size = rtlUtf8Length(len, value);
  917. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  918. }
  919. size32_t RtlPackedIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  920. {
  921. if (isUnsigned())
  922. target.processUInt(rtlGetPackedUnsigned(self), field);
  923. else
  924. target.processInt(rtlGetPackedSigned(self), field);
  925. return rtlGetPackedSize(self);
  926. }
  927. size32_t RtlPackedIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  928. {
  929. size32_t fieldsize = rtlGetPackedSize(self);
  930. if (isUnsigned())
  931. target.outputUInt(rtlGetPackedUnsigned(self), fieldsize, queryScalarXPath(field));
  932. else
  933. target.outputInt(rtlGetPackedSigned(self), fieldsize, queryScalarXPath(field));
  934. return fieldsize;
  935. }
  936. size32_t RtlPackedIntTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  937. {
  938. char temp[9];
  939. size32_t size = in.readPackedInt(temp);
  940. byte * dest = builder.ensureCapacity(offset + size, nullptr) + offset;
  941. memcpy(dest, temp, size);
  942. return offset + size;
  943. }
  944. void RtlPackedIntTypeInfo::readAhead(IRowPrefetcherSource & in) const
  945. {
  946. in.skipPackedInt();
  947. }
  948. void RtlPackedIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  949. {
  950. if (isUnsigned())
  951. rtlUInt8ToStrX(resultLen, result, rtlGetPackedUnsigned(ptr));
  952. else
  953. rtlInt8ToStrX(resultLen, result, rtlGetPackedSigned(ptr));
  954. }
  955. void RtlPackedIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  956. {
  957. getString(resultLen, result, ptr);
  958. }
  959. __int64 RtlPackedIntTypeInfo::getInt(const void * ptr) const
  960. {
  961. if (isUnsigned())
  962. return rtlGetPackedUnsigned(ptr);
  963. else
  964. return rtlGetPackedSigned(ptr);
  965. }
  966. double RtlPackedIntTypeInfo::getReal(const void * ptr) const
  967. {
  968. if (isUnsigned())
  969. return (double) rtlGetPackedUnsigned(ptr);
  970. else
  971. return (double) rtlGetPackedSigned(ptr);
  972. }
  973. int RtlPackedIntTypeInfo::compare(const byte * left, const byte * right) const
  974. {
  975. if (isUnsigned())
  976. {
  977. unsigned __int64 leftValue = rtlGetPackedUnsigned(left);
  978. unsigned __int64 rightValue = rtlGetPackedUnsigned(right);
  979. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  980. }
  981. else
  982. {
  983. __int64 leftValue = rtlGetPackedSigned(left);
  984. __int64 rightValue = rtlGetPackedSigned(right);
  985. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  986. }
  987. }
  988. unsigned RtlPackedIntTypeInfo::hash(const byte *self, unsigned inhash) const
  989. {
  990. __int64 val = getInt(self);
  991. return rtlHash32Data8(&val, inhash);
  992. }
  993. //-------------------------------------------------------------------------------------------------------------------
  994. size32_t RtlStringTypeInfo::getMinSize() const
  995. {
  996. if (isFixedSize())
  997. return length;
  998. return sizeof(size32_t);
  999. }
  1000. size32_t RtlStringTypeInfo::size(const byte * self, const byte * selfrow) const
  1001. {
  1002. if (isFixedSize())
  1003. return length;
  1004. return sizeof(size32_t) + rtlReadSize32t(self);
  1005. }
  1006. size32_t RtlStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1007. {
  1008. size32_t size;
  1009. rtlDataAttr value;
  1010. source.getStringResult(field, size, value.refstr());
  1011. return buildString(builder, offset, field, size, value.getstr());
  1012. }
  1013. size32_t RtlStringTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  1014. {
  1015. if (!isFixedSize())
  1016. {
  1017. builder.ensureCapacity(offset+size+sizeof(size32_t), queryName(field));
  1018. byte *dest = builder.getSelf()+offset;
  1019. rtlWriteInt4(dest, size);
  1020. // NOTE - it has been the subject of debate whether we should convert the incoming data to EBCDIC, or expect the IFieldSource to have already returned ebcdic
  1021. // In order to be symmetrical with the passing of ecl data to a IFieldProcessor the former interpretation is preferred.
  1022. // Expecting source.getStringResult to somehow "know" that EBCDIC was expected seems odd.
  1023. if (isEbcdic())
  1024. rtlStrToEStr(size, (char *) dest+sizeof(size32_t), size, (char *)value);
  1025. else
  1026. memcpy_iflen(dest+sizeof(size32_t), value, size);
  1027. offset += size+sizeof(size32_t);
  1028. }
  1029. else
  1030. {
  1031. builder.ensureCapacity(offset+length, queryName(field));
  1032. byte *dest = builder.getSelf()+offset;
  1033. if (isEbcdic())
  1034. rtlStrToEStr(length, (char *) dest, size, (char *) value);
  1035. else
  1036. rtlStrToStr(length, dest, size, value);
  1037. offset += length;
  1038. }
  1039. return offset;
  1040. }
  1041. size32_t RtlStringTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
  1042. {
  1043. if (isEbcdic())
  1044. return buildUtf8ViaString(builder, offset, field, codepoints, value);
  1045. if (!isFixedSize())
  1046. {
  1047. builder.ensureCapacity(offset+codepoints+sizeof(size32_t), queryName(field));
  1048. char *dest = (char *) builder.getSelf()+offset;
  1049. rtlWriteInt4(dest, codepoints);
  1050. rtlUtf8ToStr(codepoints, dest+sizeof(size32_t), codepoints, value);
  1051. offset += codepoints+sizeof(size32_t);
  1052. }
  1053. else
  1054. {
  1055. builder.ensureCapacity(offset+length, queryName(field));
  1056. char *dest = (char *) builder.getSelf()+offset;
  1057. rtlUtf8ToStr(length, dest, codepoints, value);
  1058. offset += length;
  1059. }
  1060. return offset;
  1061. }
  1062. size32_t RtlStringTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
  1063. {
  1064. if (field->initializer || !isFixedSize())
  1065. return RtlTypeInfoBase::buildNull(builder, offset, field);
  1066. else
  1067. {
  1068. builder.ensureCapacity(offset+length, queryName(field));
  1069. memset(builder.getSelf()+offset, isEbcdic() ? 0x40 : ' ', length);
  1070. return offset + length;
  1071. }
  1072. }
  1073. size32_t RtlStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1074. {
  1075. const char * str = reinterpret_cast<const char *>(self);
  1076. unsigned thisLength;
  1077. unsigned thisSize;
  1078. if (isFixedSize())
  1079. {
  1080. thisLength = length;
  1081. thisSize = thisLength;
  1082. }
  1083. else
  1084. {
  1085. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1086. thisLength = rtlReadSize32t(self);
  1087. thisSize = sizeof(size32_t) + thisLength;
  1088. }
  1089. if (isEbcdic())
  1090. {
  1091. unsigned lenAscii;
  1092. rtlDataAttr ascii;
  1093. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  1094. target.processString(lenAscii, ascii.getstr(), field);
  1095. }
  1096. else
  1097. {
  1098. target.processString(thisLength, str, field);
  1099. }
  1100. return thisSize;
  1101. }
  1102. size32_t RtlStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1103. {
  1104. const char * str = reinterpret_cast<const char *>(self);
  1105. unsigned thisLength;
  1106. unsigned thisSize;
  1107. if (isFixedSize())
  1108. {
  1109. thisLength = length;
  1110. thisSize = thisLength;
  1111. }
  1112. else
  1113. {
  1114. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1115. thisLength = rtlReadSize32t(self);
  1116. thisSize = sizeof(size32_t) + thisLength;
  1117. }
  1118. if (isEbcdic())
  1119. {
  1120. unsigned lenAscii;
  1121. rtlDataAttr ascii;
  1122. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  1123. target.outputString(lenAscii, ascii.getstr(), queryScalarXPath(field));
  1124. }
  1125. else
  1126. {
  1127. target.outputString(thisLength, str, queryScalarXPath(field));
  1128. }
  1129. return thisSize;
  1130. }
  1131. size32_t RtlStringTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  1132. {
  1133. if (isFixedSize())
  1134. {
  1135. size32_t size = length;
  1136. byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
  1137. in.read(size, dest);
  1138. offset += size;
  1139. }
  1140. else
  1141. {
  1142. size32_t size = in.readSize();
  1143. byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
  1144. rtlWriteSize32t(dest, size);
  1145. in.read(size, dest + sizeof(size32_t));
  1146. offset += sizeof(size32_t)+size;
  1147. }
  1148. return offset;
  1149. }
  1150. void RtlStringTypeInfo::readAhead(IRowPrefetcherSource & in) const
  1151. {
  1152. if (isFixedSize())
  1153. {
  1154. in.skip(length);
  1155. }
  1156. else
  1157. {
  1158. size32_t thisLength = in.readSize();
  1159. in.skip(thisLength);
  1160. }
  1161. }
  1162. void RtlStringTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  1163. {
  1164. if (isFixedSize())
  1165. {
  1166. if (isEbcdic())
  1167. return rtlEStrToStrX(resultLen, result, length, (const char *)ptr);
  1168. else
  1169. return rtlStrToStrX(resultLen, result, length, (const char *)ptr);
  1170. }
  1171. else
  1172. {
  1173. size32_t len = rtlReadSize32t(ptr);
  1174. if (isEbcdic())
  1175. return rtlEStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1176. else
  1177. return rtlStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1178. }
  1179. }
  1180. void RtlStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1181. {
  1182. if (isEbcdic())
  1183. {
  1184. getUtf8ViaString(resultLen, result, ptr);
  1185. return;
  1186. }
  1187. if (isFixedSize())
  1188. {
  1189. return rtlStrToUtf8X(resultLen, result, length, (const char *)ptr);
  1190. }
  1191. else
  1192. {
  1193. size32_t len = rtlReadSize32t(ptr);
  1194. return rtlStrToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1195. }
  1196. }
  1197. __int64 RtlStringTypeInfo::getInt(const void * ptr) const
  1198. {
  1199. //Utf8 output is the same as string output, so avoid the intermediate translation
  1200. if (isFixedSize())
  1201. return rtlStrToInt8(length, (const char *)ptr);
  1202. size32_t len = rtlReadSize32t(ptr);
  1203. return rtlStrToInt8(len, (const char *)ptr + sizeof(size32_t));
  1204. }
  1205. int RtlStringTypeInfo::compare(const byte * left, const byte * right) const
  1206. {
  1207. if (isFixedSize())
  1208. return memcmp(left, right, length);
  1209. else if (isEbcdic())
  1210. {
  1211. // Logically this should be
  1212. // if (isFixedSize())
  1213. // return rtlCompareEStrEStr(length, (const char *)left, length, (const char *)right);
  1214. // but that's the same as a memcmp if lengths match
  1215. size32_t lenLeft = rtlReadSize32t(left);
  1216. size32_t lenRight = rtlReadSize32t(right);
  1217. return rtlCompareEStrEStr(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
  1218. }
  1219. else
  1220. {
  1221. // Logically this should be
  1222. // if (isFixedSize())
  1223. // return rtlCompareStrStr(length, (const char *)left, length, (const char *)right); // Actually this is a memcmp
  1224. // but that's the same as a memcmp if lengths match
  1225. size32_t lenLeft = rtlReadSize32t(left);
  1226. size32_t lenRight = rtlReadSize32t(right);
  1227. return rtlCompareStrStr(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
  1228. }
  1229. }
  1230. int RtlStringTypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  1231. {
  1232. if (isFixedSize())
  1233. {
  1234. lenLeft = std::min(lenLeft, length);
  1235. lenRight = std::min(lenRight, length);
  1236. if (isEbcdic())
  1237. return rtlCompareEStrEStr(lenLeft, (const char *)left, lenRight, (const char *)right);
  1238. else
  1239. return rtlCompareStrStr(lenLeft, (const char *)left, lenRight, (const char *)right);
  1240. }
  1241. else
  1242. {
  1243. size32_t maxLeft = rtlReadSize32t(left);
  1244. size32_t maxRight = rtlReadSize32t(right);
  1245. if (isEbcdic())
  1246. return rtlCompareEStrEStr(std::min(lenLeft, maxLeft), (const char *)left + sizeof(size32_t), std::min(lenRight, maxRight), (const char *)right + sizeof(size32_t));
  1247. else
  1248. return rtlCompareStrStr(std::min(lenLeft, maxLeft), (const char *)left + sizeof(size32_t), std::min(lenRight, maxRight), (const char *)right + sizeof(size32_t));
  1249. }
  1250. }
  1251. bool RtlStringTypeInfo::canMemCmp() const
  1252. {
  1253. return isFixedSize();
  1254. }
  1255. unsigned RtlStringTypeInfo::hash(const byte * self, unsigned inhash) const
  1256. {
  1257. size32_t len;
  1258. if (isFixedSize())
  1259. len = length;
  1260. else
  1261. {
  1262. len = rtlReadSize32t(self);
  1263. self += sizeof(size32_t);
  1264. }
  1265. return rtlHash32Data(rtlTrimStrLen(len, (const char *) self), self, inhash);
  1266. }
  1267. bool RtlStringTypeInfo::canExtend(char &fillChar) const
  1268. {
  1269. if (isFixedSize())
  1270. {
  1271. fillChar = isEbcdic() ? 0x40 : ' ';
  1272. return true;
  1273. }
  1274. return false;
  1275. }
  1276. //-------------------------------------------------------------------------------------------------------------------
  1277. size32_t RtlDataTypeInfo::getMinSize() const
  1278. {
  1279. if (isFixedSize())
  1280. return length;
  1281. return sizeof(size32_t);
  1282. }
  1283. size32_t RtlDataTypeInfo::size(const byte * self, const byte * selfrow) const
  1284. {
  1285. if (isFixedSize())
  1286. return length;
  1287. return sizeof(size32_t) + rtlReadSize32t(self);
  1288. }
  1289. size32_t RtlDataTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1290. {
  1291. size32_t size;
  1292. rtlDataAttr value;
  1293. source.getDataResult(field, size, value.refdata());
  1294. return buildString(builder, offset, field, size, value.getstr());
  1295. }
  1296. size32_t RtlDataTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  1297. {
  1298. if (!isFixedSize())
  1299. {
  1300. builder.ensureCapacity(offset+size+sizeof(size32_t), queryName(field));
  1301. byte *dest = builder.getSelf()+offset;
  1302. rtlWriteInt4(dest, size);
  1303. memcpy_iflen(dest+sizeof(size32_t), value, size);
  1304. offset += size+sizeof(size32_t);
  1305. }
  1306. else
  1307. {
  1308. builder.ensureCapacity(offset+length, queryName(field));
  1309. byte *dest = builder.getSelf()+offset;
  1310. rtlDataToData(length, dest, size, value);
  1311. offset += length;
  1312. }
  1313. return offset;
  1314. }
  1315. size32_t RtlDataTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
  1316. {
  1317. return buildUtf8ViaString(builder, offset, field, codepoints, value);
  1318. }
  1319. size32_t RtlDataTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1320. {
  1321. const char * str = reinterpret_cast<const char *>(self);
  1322. unsigned thisLength;
  1323. unsigned thisSize;
  1324. if (isFixedSize())
  1325. {
  1326. thisLength = length;
  1327. thisSize = thisLength;
  1328. }
  1329. else
  1330. {
  1331. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1332. thisLength = rtlReadSize32t(self);
  1333. thisSize = sizeof(size32_t) + thisLength;
  1334. }
  1335. target.processData(thisLength, str, field);
  1336. return thisSize;
  1337. }
  1338. size32_t RtlDataTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1339. {
  1340. const char * str = reinterpret_cast<const char *>(self);
  1341. unsigned thisLength;
  1342. unsigned thisSize;
  1343. if (isFixedSize())
  1344. {
  1345. thisLength = length;
  1346. thisSize = thisLength;
  1347. }
  1348. else
  1349. {
  1350. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1351. thisLength = rtlReadSize32t(self);
  1352. thisSize = sizeof(size32_t) + thisLength;
  1353. }
  1354. target.outputData(thisLength, str, queryScalarXPath(field));
  1355. return thisSize;
  1356. }
  1357. size32_t RtlDataTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  1358. {
  1359. if (isFixedSize())
  1360. {
  1361. size32_t size = length;
  1362. byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
  1363. in.read(size, dest);
  1364. offset += size;
  1365. }
  1366. else
  1367. {
  1368. size32_t size = in.readSize();
  1369. byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
  1370. rtlWriteSize32t(dest, size);
  1371. in.read(size, dest + sizeof(size32_t));
  1372. offset += sizeof(size32_t)+size;
  1373. }
  1374. return offset;
  1375. }
  1376. void RtlDataTypeInfo::readAhead(IRowPrefetcherSource & in) const
  1377. {
  1378. if (isFixedSize())
  1379. {
  1380. in.skip(length);
  1381. }
  1382. else
  1383. {
  1384. size32_t thisLength = in.readSize();
  1385. in.skip(thisLength);
  1386. }
  1387. }
  1388. void RtlDataTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  1389. {
  1390. if (isFixedSize())
  1391. {
  1392. return rtlStrToStrX(resultLen, result, length, (const char *)ptr);
  1393. }
  1394. else
  1395. {
  1396. size32_t len = rtlReadSize32t(ptr);
  1397. return rtlStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1398. }
  1399. }
  1400. void RtlDataTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1401. {
  1402. if (isFixedSize())
  1403. {
  1404. return rtlStrToUtf8X(resultLen, result, length, (const char *)ptr);
  1405. }
  1406. else
  1407. {
  1408. size32_t len = rtlReadSize32t(ptr);
  1409. return rtlStrToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1410. }
  1411. }
  1412. __int64 RtlDataTypeInfo::getInt(const void * ptr) const
  1413. {
  1414. //Utf8 output is the same as string output, so avoid the intermediate translation
  1415. if (isFixedSize())
  1416. return rtlStrToInt8(length, (const char *)ptr);
  1417. size32_t len = rtlReadSize32t(ptr);
  1418. return rtlStrToInt8(len, (const char *)ptr + sizeof(size32_t));
  1419. }
  1420. int RtlDataTypeInfo::compare(const byte * left, const byte * right) const
  1421. {
  1422. if (isFixedSize())
  1423. // Logically this should be return rtlCompareDataData(length, (const char *)left, length, (const char *)right);
  1424. // but that acts as a memcmp if lengths match
  1425. return memcmp(left, right, length);
  1426. size32_t lenLeft = rtlReadSize32t(left);
  1427. size32_t lenRight = rtlReadSize32t(right);
  1428. return rtlCompareDataData(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
  1429. }
  1430. int RtlDataTypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  1431. {
  1432. if (isFixedSize())
  1433. {
  1434. lenLeft = std::min(lenLeft, length);
  1435. lenRight = std::min(lenRight, length);
  1436. return rtlCompareDataData(lenLeft, (const char *)left, lenRight, (const char *)right);
  1437. }
  1438. else
  1439. {
  1440. size32_t maxLeft = rtlReadSize32t(left);
  1441. size32_t maxRight = rtlReadSize32t(right);
  1442. lenLeft = std::min(lenLeft, maxLeft);
  1443. lenRight = std::min(lenRight, maxRight);
  1444. return rtlCompareDataData(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
  1445. }
  1446. }
  1447. bool RtlDataTypeInfo::canMemCmp() const
  1448. {
  1449. return isFixedSize();
  1450. }
  1451. unsigned RtlDataTypeInfo::hash(const byte *self, unsigned inhash) const
  1452. {
  1453. size32_t len;
  1454. if (isFixedSize())
  1455. len = length;
  1456. else
  1457. {
  1458. len = rtlReadSize32t(self);
  1459. self += sizeof(size32_t);
  1460. }
  1461. return rtlHash32Data(len, self, inhash);
  1462. }
  1463. bool RtlDataTypeInfo::canExtend(char &fillChar) const
  1464. {
  1465. if (isFixedSize())
  1466. {
  1467. fillChar = 0;
  1468. return true;
  1469. }
  1470. return false;
  1471. }
  1472. //-------------------------------------------------------------------------------------------------------------------
  1473. size32_t RtlVarStringTypeInfo::getMinSize() const
  1474. {
  1475. if (isFixedSize())
  1476. return length+1;
  1477. return 1;
  1478. }
  1479. size32_t RtlVarStringTypeInfo::size(const byte * self, const byte * selfrow) const
  1480. {
  1481. if (isFixedSize())
  1482. return length + 1;
  1483. const char * str = reinterpret_cast<const char *>(self);
  1484. return (size32_t)strlen(str)+1;
  1485. }
  1486. size32_t RtlVarStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1487. {
  1488. size32_t size;
  1489. rtlDataAttr value;
  1490. source.getStringResult(field, size, value.refstr());
  1491. return buildString(builder, offset, field, size, value.getstr());
  1492. }
  1493. size32_t RtlVarStringTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  1494. {
  1495. if (!isFixedSize())
  1496. {
  1497. builder.ensureCapacity(offset+size+1, queryName(field));
  1498. // See notes re EBCDIC conversion in RtlStringTypeInfo code
  1499. byte *dest = builder.getSelf()+offset;
  1500. if (isEbcdic())
  1501. rtlStrToEStr(size, (char *) dest, size, (char *)value);
  1502. else
  1503. memcpy_iflen(dest, value, size);
  1504. dest[size] = '\0';
  1505. offset += size+1;
  1506. }
  1507. else
  1508. {
  1509. builder.ensureCapacity(offset+length+1, queryName(field));
  1510. byte *dest = builder.getSelf()+offset;
  1511. if (isEbcdic())
  1512. rtlEStrToVStr(length+1, dest, size, value);
  1513. else
  1514. rtlStrToVStr(length+1, dest, size, value);
  1515. offset += length+1;
  1516. }
  1517. return offset;
  1518. }
  1519. size32_t RtlVarStringTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
  1520. {
  1521. return buildUtf8ViaString(builder, offset, field, codepoints, value);
  1522. }
  1523. size32_t RtlVarStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1524. {
  1525. const char * str = reinterpret_cast<const char *>(self);
  1526. unsigned thisLength = (size32_t)strlen(str);
  1527. unsigned thisSize;
  1528. if (isFixedSize())
  1529. thisSize = length+1;
  1530. else
  1531. thisSize = thisLength+1;
  1532. if (isEbcdic())
  1533. {
  1534. unsigned lenAscii;
  1535. rtlDataAttr ascii;
  1536. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  1537. target.processString(lenAscii, ascii.getstr(), field);
  1538. }
  1539. else
  1540. target.processString(thisLength, str, field);
  1541. return thisSize;
  1542. }
  1543. size32_t RtlVarStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1544. {
  1545. const char * str = reinterpret_cast<const char *>(self);
  1546. unsigned thisLength = (size32_t)strlen(str);
  1547. unsigned thisSize;
  1548. if (isFixedSize())
  1549. thisSize = length+1;
  1550. else
  1551. thisSize = thisLength+1;
  1552. if (isEbcdic())
  1553. {
  1554. unsigned lenAscii;
  1555. rtlDataAttr ascii;
  1556. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  1557. target.outputString(lenAscii, ascii.getstr(), queryScalarXPath(field));
  1558. }
  1559. else
  1560. target.outputString(thisLength, str, queryScalarXPath(field));
  1561. return thisSize;
  1562. }
  1563. size32_t RtlVarStringTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  1564. {
  1565. if (isFixedSize())
  1566. {
  1567. size32_t size = length+1;
  1568. byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
  1569. in.read(size, dest);
  1570. return offset + size;
  1571. }
  1572. else
  1573. return offset + in.readVStr(builder, offset, offset);
  1574. }
  1575. void RtlVarStringTypeInfo::readAhead(IRowPrefetcherSource & in) const
  1576. {
  1577. if (isFixedSize())
  1578. {
  1579. in.skip(length+1);
  1580. }
  1581. else
  1582. {
  1583. in.skipVStr();
  1584. }
  1585. }
  1586. void RtlVarStringTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  1587. {
  1588. const char * str = (const char *)ptr;
  1589. return rtlStrToStrX(resultLen, result, strlen(str), str);
  1590. }
  1591. void RtlVarStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1592. {
  1593. const char * str = (const char *)ptr;
  1594. return rtlStrToUtf8X(resultLen, result, strlen(str), str);
  1595. }
  1596. __int64 RtlVarStringTypeInfo::getInt(const void * ptr) const
  1597. {
  1598. const char * str = (const char *)ptr;
  1599. return rtlVStrToInt8(str);
  1600. }
  1601. int RtlVarStringTypeInfo::compare(const byte * left, const byte * right) const
  1602. {
  1603. if (isEbcdic())
  1604. {
  1605. const char * leftValue = (const char *)left;
  1606. const char * rightValue = (const char *)right;
  1607. return rtlCompareEStrEStr(strlen(leftValue), leftValue, strlen(rightValue), rightValue);
  1608. }
  1609. return rtlCompareVStrVStr((const char *)left, (const char *)right);
  1610. }
  1611. int RtlVarStringTypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  1612. {
  1613. size32_t maxLeft = strlen((const char *)left);
  1614. size32_t maxRight = strlen((const char *)right);
  1615. lenLeft = std::min(lenLeft, maxLeft);
  1616. lenRight = std::min(lenRight, maxRight);
  1617. if (isEbcdic())
  1618. return rtlCompareEStrEStr(lenLeft, (const char *)left, lenRight, (const char *)right);
  1619. else
  1620. return rtlCompareStrStr(lenLeft, (const char *)left, lenRight, (const char *)right);
  1621. }
  1622. void RtlVarStringTypeInfo::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  1623. {
  1624. //Do not support substring matching or non-exclusive bounds.
  1625. //They could possibly be implemented by copying a varstring at maxlength padded with spaces.
  1626. if ((subLength != MatchFullString) || !inclusive)
  1627. UNIMPLEMENTED_X("RtlVarStringTypeInfo::setBound");
  1628. RtlTypeInfoBase::setBound(buffer, value, subLength, fill, inclusive);
  1629. }
  1630. unsigned RtlVarStringTypeInfo::hash(const byte * self, unsigned inhash) const
  1631. {
  1632. return rtlHash32VStr((const char *) self, inhash);
  1633. }
  1634. bool RtlVarStringTypeInfo::canExtend(char &fillChar) const
  1635. {
  1636. if (isFixedSize())
  1637. {
  1638. fillChar = 0;
  1639. return true;
  1640. }
  1641. return false;
  1642. }
  1643. //-------------------------------------------------------------------------------------------------------------------
  1644. size32_t RtlQStringTypeInfo::getMinSize() const
  1645. {
  1646. if (isFixedSize())
  1647. return rtlQStrSize(length);
  1648. return sizeof(size32_t);
  1649. }
  1650. size32_t RtlQStringTypeInfo::size(const byte * self, const byte * selfrow) const
  1651. {
  1652. if (isFixedSize())
  1653. return rtlQStrSize(length);
  1654. return sizeof(size32_t) + rtlQStrSize(rtlReadSize32t(self));
  1655. }
  1656. size32_t RtlQStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1657. {
  1658. size32_t size;
  1659. rtlDataAttr value;
  1660. source.getStringResult(field, size, value.refstr());
  1661. return buildString(builder, offset, field, size, value.getstr());
  1662. }
  1663. size32_t RtlQStringTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  1664. {
  1665. if (!isFixedSize())
  1666. {
  1667. size32_t sizeInBytes = rtlQStrSize(size) + sizeof(size32_t);
  1668. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  1669. byte *dest = builder.getSelf()+offset;
  1670. rtlWriteInt4(dest, size);
  1671. rtlStrToQStr(size, (char *) dest+sizeof(size32_t), size, value);
  1672. offset += sizeInBytes;
  1673. }
  1674. else
  1675. {
  1676. size32_t sizeInBytes = rtlQStrSize(length);
  1677. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  1678. byte *dest = builder.getSelf()+offset;
  1679. rtlStrToQStr(length, (char *) dest, size, value);
  1680. offset += sizeInBytes;
  1681. }
  1682. return offset;
  1683. }
  1684. size32_t RtlQStringTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
  1685. {
  1686. return buildUtf8ViaString(builder, offset, field, codepoints, value);
  1687. }
  1688. size32_t RtlQStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1689. {
  1690. const char * str = reinterpret_cast<const char *>(self);
  1691. unsigned thisLength;
  1692. unsigned thisSize;
  1693. if (isFixedSize())
  1694. {
  1695. thisLength = length;
  1696. thisSize = rtlQStrSize(thisLength);
  1697. }
  1698. else
  1699. {
  1700. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1701. thisLength = rtlReadSize32t(self);
  1702. thisSize = sizeof(size32_t) + rtlQStrSize(thisLength);
  1703. }
  1704. target.processQString(thisLength, str, field);
  1705. return thisSize;
  1706. }
  1707. size32_t RtlQStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1708. {
  1709. const char * str = reinterpret_cast<const char *>(self);
  1710. unsigned thisLength;
  1711. unsigned thisSize;
  1712. if (isFixedSize())
  1713. {
  1714. thisLength = length;
  1715. thisSize = rtlQStrSize(thisLength);
  1716. }
  1717. else
  1718. {
  1719. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1720. thisLength = rtlReadSize32t(self);
  1721. thisSize = sizeof(size32_t) + rtlQStrSize(thisLength);
  1722. }
  1723. target.outputQString(thisLength, str, queryScalarXPath(field));
  1724. return thisSize;
  1725. }
  1726. size32_t RtlQStringTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  1727. {
  1728. if (isFixedSize())
  1729. {
  1730. size32_t size = rtlQStrSize(length);
  1731. byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
  1732. in.read(size, dest);
  1733. offset += size;
  1734. }
  1735. else
  1736. {
  1737. size32_t thisLength = in.readSize();
  1738. size32_t size = rtlQStrSize(thisLength);
  1739. byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
  1740. rtlWriteSize32t(dest, thisLength);
  1741. in.read(size, dest + sizeof(size32_t));
  1742. offset += sizeof(size32_t)+size;
  1743. }
  1744. return offset;
  1745. }
  1746. void RtlQStringTypeInfo::readAhead(IRowPrefetcherSource & in) const
  1747. {
  1748. if (isFixedSize())
  1749. {
  1750. size32_t size = rtlQStrSize(length);
  1751. in.skip(size);
  1752. }
  1753. else
  1754. {
  1755. size32_t thisLength = in.readSize();
  1756. size32_t size = rtlQStrSize(thisLength);
  1757. in.skip(size);
  1758. }
  1759. }
  1760. void RtlQStringTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  1761. {
  1762. if (isFixedSize())
  1763. {
  1764. return rtlQStrToStrX(resultLen, result, length, (const char *)ptr);
  1765. }
  1766. else
  1767. {
  1768. size32_t len = rtlReadSize32t(ptr);
  1769. return rtlQStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1770. }
  1771. }
  1772. void RtlQStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1773. {
  1774. //NOTE: QStrings cannot contain non-string characters, so converting to str is the same as utf8
  1775. getString(resultLen, result, ptr);
  1776. }
  1777. __int64 RtlQStringTypeInfo::getInt(const void * ptr) const
  1778. {
  1779. size32_t lenTemp;
  1780. rtlDataAttr temp;
  1781. getUtf8(lenTemp, temp.refstr(), ptr);
  1782. return rtlStrToInt8(lenTemp, temp.getstr());
  1783. }
  1784. int RtlQStringTypeInfo::compare(const byte * left, const byte * right) const
  1785. {
  1786. if (isFixedSize())
  1787. // Logically this should be return rtlCompareQStrQStr(length, left, length, right);
  1788. // but that acts as a memcmp if lengths match
  1789. return memcmp(left, right, rtlQStrSize(length));
  1790. size32_t lenLeft = rtlReadSize32t(left);
  1791. size32_t lenRight = rtlReadSize32t(right);
  1792. return rtlCompareQStrQStr(lenLeft, left + sizeof(size32_t), lenRight, right + sizeof(size32_t));
  1793. }
  1794. int RtlQStringTypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  1795. {
  1796. if (isFixedSize())
  1797. {
  1798. lenLeft = std::min(lenLeft, length);
  1799. lenRight = std::min(lenRight, length);
  1800. return rtlSafeCompareQStrQStr(lenLeft, (const char *)left, lenRight, (const char *)right);
  1801. }
  1802. else
  1803. {
  1804. size32_t maxLeft = rtlReadSize32t(left);
  1805. size32_t maxRight = rtlReadSize32t(right);
  1806. lenLeft = std::min(lenLeft, maxLeft);
  1807. lenRight = std::min(lenRight, maxRight);
  1808. return rtlSafeCompareQStrQStr(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
  1809. }
  1810. }
  1811. void RtlQStringTypeInfo::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  1812. {
  1813. byte *dst = (byte *) buffer;
  1814. size32_t minSize = getMinSize();
  1815. if (value)
  1816. {
  1817. //Eventually the comparison code should not ever use non inclusive, or compare characters after subLength
  1818. //Until then this code needs to fill the rest of the string with the correct fill character and
  1819. //increment the appropriate qcharacter
  1820. size32_t copyLen;
  1821. if (isFixedSize())
  1822. {
  1823. //For a substring comparison, the bytes after subLength will eventually never be compared - but index currently does
  1824. copyLen = std::min(length, subLength);
  1825. rtlQStrToQStr(length, (char *)buffer, copyLen, (const char *)value);
  1826. if (fill != 0)
  1827. {
  1828. for (unsigned i=copyLen; i < length; i++)
  1829. setQChar(dst, i, 0x3F);
  1830. }
  1831. else if (copyLen != length)
  1832. setQChar(dst, copyLen, 0); // work around a bug copying qstrings of the same size, but different lengths
  1833. }
  1834. else
  1835. {
  1836. copyLen = std::min(rtlReadSize32t(value), subLength);
  1837. size32_t copySize = size(value, nullptr);
  1838. memcpy(dst, value, copySize);
  1839. }
  1840. if (!inclusive)
  1841. {
  1842. if (fill == 0)
  1843. incrementQString(dst, copyLen);
  1844. else
  1845. decrementQString(dst, copyLen);
  1846. }
  1847. }
  1848. else
  1849. {
  1850. assertex((fill == 0) || isFixedSize());
  1851. memset(dst, fill, minSize);
  1852. }
  1853. }
  1854. bool RtlQStringTypeInfo::canMemCmp() const
  1855. {
  1856. return isFixedSize();
  1857. }
  1858. unsigned RtlQStringTypeInfo::hash(const byte * self, unsigned inhash) const
  1859. {
  1860. rtlDataAttr val;
  1861. unsigned len;
  1862. getString(len, val.refstr(), self);
  1863. return rtlHash32Data(rtlTrimStrLen(len, val.getstr()), val.getstr(), inhash);
  1864. }
  1865. bool RtlQStringTypeInfo::canExtend(char &fillChar) const
  1866. {
  1867. if (isFixedSize())
  1868. {
  1869. fillChar = 0;
  1870. return true;
  1871. }
  1872. return false;
  1873. }
  1874. //-------------------------------------------------------------------------------------------------------------------
  1875. size32_t RtlDecimalTypeInfo::calcSize() const
  1876. {
  1877. if (isUnsigned())
  1878. return (getDecimalDigits()+1)/2;
  1879. return (getDecimalDigits()+2)/2;
  1880. }
  1881. size32_t RtlDecimalTypeInfo::getMinSize() const
  1882. {
  1883. return calcSize();
  1884. }
  1885. size32_t RtlDecimalTypeInfo::size(const byte * self, const byte * selfrow) const
  1886. {
  1887. return calcSize();
  1888. }
  1889. size32_t RtlDecimalTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1890. {
  1891. Decimal value;
  1892. source.getDecimalResult(field, value);
  1893. size32_t sizeInBytes = calcSize();
  1894. builder.ensureCapacity(sizeInBytes+offset, queryName(field));
  1895. if (isUnsigned())
  1896. value.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  1897. else
  1898. value.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  1899. offset += sizeInBytes;
  1900. return offset;
  1901. }
  1902. size32_t RtlDecimalTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
  1903. {
  1904. if (field->initializer)
  1905. return RtlTypeInfoBase::buildNull(builder, offset, field);
  1906. Decimal value;
  1907. size32_t sizeInBytes = calcSize();
  1908. builder.ensureCapacity(sizeInBytes+offset, queryName(field));
  1909. if (isUnsigned())
  1910. value.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  1911. else
  1912. value.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  1913. offset += sizeInBytes;
  1914. return offset;
  1915. }
  1916. size32_t RtlDecimalTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  1917. {
  1918. Decimal dvalue;
  1919. dvalue.setString(len, value);
  1920. size32_t sizeInBytes = calcSize();
  1921. builder.ensureCapacity(sizeInBytes+offset, queryName(field));
  1922. if (isUnsigned())
  1923. dvalue.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  1924. else
  1925. dvalue.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  1926. offset += sizeInBytes;
  1927. return offset;
  1928. }
  1929. size32_t RtlDecimalTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  1930. {
  1931. size32_t size = rtlUtf8Length(len, value);
  1932. return buildString(builder, offset, field, size, value);
  1933. }
  1934. size32_t RtlDecimalTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1935. {
  1936. size32_t thisSize = calcSize();
  1937. if (isUnsigned())
  1938. target.processUDecimal(self, thisSize, getDecimalPrecision(), field);
  1939. else
  1940. target.processDecimal(self, thisSize, getDecimalPrecision(), field);
  1941. return thisSize;
  1942. }
  1943. size32_t RtlDecimalTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1944. {
  1945. size32_t thisSize = calcSize();
  1946. if (isUnsigned())
  1947. target.outputUDecimal(self, thisSize, getDecimalPrecision(), queryScalarXPath(field));
  1948. else
  1949. target.outputDecimal(self, thisSize, getDecimalPrecision(), queryScalarXPath(field));
  1950. return thisSize;
  1951. }
  1952. void RtlDecimalTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  1953. {
  1954. Decimal temp;
  1955. size32_t sizeInBytes = calcSize();
  1956. if (isUnsigned())
  1957. temp.setUDecimal(sizeInBytes, getDecimalPrecision(), ptr);
  1958. else
  1959. temp.setDecimal(sizeInBytes, getDecimalPrecision(), ptr);
  1960. temp.getStringX(resultLen, result);
  1961. }
  1962. void RtlDecimalTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1963. {
  1964. getString(resultLen, result, ptr);
  1965. }
  1966. __int64 RtlDecimalTypeInfo::getInt(const void * ptr) const
  1967. {
  1968. Decimal temp;
  1969. size32_t sizeInBytes = calcSize();
  1970. if (isUnsigned())
  1971. temp.setUDecimal(sizeInBytes, getDecimalPrecision(), ptr);
  1972. else
  1973. temp.setDecimal(sizeInBytes, getDecimalPrecision(), ptr);
  1974. return temp.getInt64();
  1975. }
  1976. double RtlDecimalTypeInfo::getReal(const void * ptr) const
  1977. {
  1978. Decimal temp;
  1979. size32_t sizeInBytes = calcSize();
  1980. if (isUnsigned())
  1981. temp.setUDecimal(sizeInBytes, getDecimalPrecision(), ptr);
  1982. else
  1983. temp.setDecimal(sizeInBytes, getDecimalPrecision(), ptr);
  1984. return temp.getReal();
  1985. }
  1986. int RtlDecimalTypeInfo::compare(const byte * left, const byte * right) const
  1987. {
  1988. if (isUnsigned())
  1989. return decCompareUDecimal(calcSize(), left, right);
  1990. else
  1991. return decCompareDecimal(calcSize(), left, right);
  1992. }
  1993. unsigned RtlDecimalTypeInfo::hash(const byte * self, unsigned inhash) const
  1994. {
  1995. return rtlHash32Data(calcSize(), self, inhash);
  1996. }
  1997. //-------------------------------------------------------------------------------------------------------------------
  1998. size32_t RtlCharTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1999. {
  2000. throwUnexpected(); // Can't have a field of type char
  2001. }
  2002. size32_t RtlCharTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  2003. {
  2004. rtlFailUnexpected();
  2005. }
  2006. size32_t RtlCharTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  2007. {
  2008. return buildUtf8ViaString(builder, offset, field, len, value);
  2009. }
  2010. size32_t RtlCharTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  2011. {
  2012. const char * str = reinterpret_cast<const char *>(self);
  2013. char c;
  2014. if (isEbcdic())
  2015. rtlEStrToStr(1, &c, 1, str);
  2016. else
  2017. c = *str;
  2018. target.processString(1, &c, field);
  2019. return 1;
  2020. }
  2021. size32_t RtlCharTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  2022. {
  2023. const char * str = reinterpret_cast<const char *>(self);
  2024. char c;
  2025. if (isEbcdic())
  2026. rtlEStrToStr(1, &c, 1, str);
  2027. else
  2028. c = *str;
  2029. target.outputString(1, &c, queryScalarXPath(field));
  2030. return 1;
  2031. }
  2032. void RtlCharTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  2033. {
  2034. const char * str = (const char *)ptr;
  2035. return rtlStrToStrX(resultLen, result, 1, str);
  2036. }
  2037. void RtlCharTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  2038. {
  2039. const char * str = (const char *)ptr;
  2040. return rtlStrToUtf8X(resultLen, result, 1, str);
  2041. }
  2042. __int64 RtlCharTypeInfo::getInt(const void * ptr) const
  2043. {
  2044. const char * str = (const char *)ptr;
  2045. return rtlStrToInt8(1, str);
  2046. }
  2047. int RtlCharTypeInfo::compare(const byte * left, const byte * right) const
  2048. {
  2049. if (isEbcdic())
  2050. return rtlCompareEStrEStr(1, (const char *)left, 1, (const char *)right);
  2051. else
  2052. return rtlCompareStrStr(1, (const char *)left, 1, (const char *)right);
  2053. }
  2054. unsigned RtlCharTypeInfo::hash(const byte * self, unsigned inhash) const
  2055. {
  2056. return rtlHash32Data(1, self, inhash); // MORE - should we trim?
  2057. }
  2058. //-------------------------------------------------------------------------------------------------------------------
  2059. size32_t RtlUnicodeTypeInfo::getMinSize() const
  2060. {
  2061. if (isFixedSize())
  2062. return length * sizeof(UChar);
  2063. return sizeof(size32_t);
  2064. }
  2065. size32_t RtlUnicodeTypeInfo::size(const byte * self, const byte * selfrow) const
  2066. {
  2067. if (isFixedSize())
  2068. return length * sizeof(UChar);
  2069. return sizeof(size32_t) + rtlReadSize32t(self) * sizeof(UChar);
  2070. }
  2071. size32_t RtlUnicodeTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  2072. {
  2073. size32_t sizeInChars;
  2074. UChar *value;
  2075. source.getUnicodeResult(field, sizeInChars, value);
  2076. if (!isFixedSize())
  2077. {
  2078. size32_t sizeInBytes = sizeInChars * sizeof(UChar);
  2079. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
  2080. byte *dest = builder.getSelf()+offset;
  2081. rtlWriteInt4(dest, sizeInChars); // NOTE - in chars!
  2082. memcpy_iflen(dest+sizeof(size32_t), value, sizeInBytes);
  2083. offset += sizeInBytes+sizeof(size32_t);
  2084. }
  2085. else
  2086. {
  2087. size32_t sizeInBytes = length * sizeof(UChar);
  2088. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2089. byte *dest = builder.getSelf()+offset;
  2090. rtlUnicodeToUnicode(length, (UChar *) dest, sizeInChars, value);
  2091. offset += sizeInBytes;
  2092. }
  2093. rtlFree(value);
  2094. return offset;
  2095. }
  2096. size32_t RtlUnicodeTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
  2097. {
  2098. if (field->initializer || !isFixedSize())
  2099. return RtlTypeInfoBase::buildNull(builder, offset, field);
  2100. else
  2101. {
  2102. size32_t sizeInBytes = length * sizeof(UChar);
  2103. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2104. byte *dest = builder.getSelf()+offset;
  2105. rtlUnicodeToUnicode(length, (UChar *) dest, 0, nullptr);
  2106. return offset + sizeInBytes;
  2107. }
  2108. }
  2109. size32_t RtlUnicodeTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
  2110. {
  2111. if (!isFixedSize())
  2112. {
  2113. size32_t sizeInBytes = sizeInChars * sizeof(UChar);
  2114. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
  2115. byte *dest = builder.getSelf()+offset;
  2116. rtlWriteInt4(dest, sizeInChars); // NOTE - in chars!
  2117. rtlUtf8ToUnicode(sizeInChars, (UChar *) (dest+sizeof(size32_t)), sizeInChars, value);
  2118. offset += sizeInBytes+sizeof(size32_t);
  2119. }
  2120. else
  2121. {
  2122. size32_t sizeInBytes = length * sizeof(UChar);
  2123. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2124. byte *dest = builder.getSelf()+offset;
  2125. rtlUtf8ToUnicode(length, (UChar *) dest, sizeInChars, value);
  2126. offset += sizeInBytes;
  2127. }
  2128. return offset;
  2129. }
  2130. size32_t RtlUnicodeTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
  2131. {
  2132. if (!isFixedSize())
  2133. {
  2134. size32_t sizeInBytes = sizeInChars * sizeof(UChar);
  2135. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
  2136. byte *dest = builder.getSelf()+offset;
  2137. rtlWriteSize32t(dest, sizeInChars); // NOTE - in chars!
  2138. rtlStrToUnicode(sizeInChars, (UChar *) (dest+sizeof(size32_t)), sizeInChars, value);
  2139. offset += sizeInBytes+sizeof(size32_t);
  2140. }
  2141. else
  2142. {
  2143. size32_t sizeInBytes = length * sizeof(UChar);
  2144. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2145. byte *dest = builder.getSelf()+offset;
  2146. rtlStrToUnicode(length, (UChar *) dest, sizeInChars, value);
  2147. offset += sizeInBytes;
  2148. }
  2149. return offset;
  2150. }
  2151. size32_t RtlUnicodeTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  2152. {
  2153. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  2154. unsigned thisLength;
  2155. unsigned thisSize;
  2156. if (isFixedSize())
  2157. {
  2158. thisLength = length;
  2159. thisSize = thisLength * sizeof(UChar);
  2160. }
  2161. else
  2162. {
  2163. ustr = reinterpret_cast<const UChar *>(self + sizeof(size32_t));
  2164. thisLength = rtlReadSize32t(self);
  2165. thisSize = sizeof(size32_t) + thisLength * sizeof(UChar);
  2166. }
  2167. target.processUnicode(thisLength, ustr, field);
  2168. return thisSize;
  2169. }
  2170. size32_t RtlUnicodeTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  2171. {
  2172. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  2173. unsigned thisLength;
  2174. unsigned thisSize;
  2175. if (isFixedSize())
  2176. {
  2177. thisLength = length;
  2178. thisSize = thisLength * sizeof(UChar);
  2179. }
  2180. else
  2181. {
  2182. ustr = reinterpret_cast<const UChar *>(self + sizeof(size32_t));
  2183. thisLength = rtlReadSize32t(self);
  2184. thisSize = sizeof(size32_t) + thisLength * sizeof(UChar);
  2185. }
  2186. target.outputUnicode(thisLength, ustr, queryScalarXPath(field));
  2187. return thisSize;
  2188. }
  2189. size32_t RtlUnicodeTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  2190. {
  2191. if (isFixedSize())
  2192. {
  2193. size32_t size = length * sizeof(UChar);
  2194. byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
  2195. in.read(size, dest);
  2196. offset += size;
  2197. }
  2198. else
  2199. {
  2200. size32_t thisLength = in.readSize();
  2201. size32_t size = thisLength * sizeof(UChar);
  2202. byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
  2203. rtlWriteSize32t(dest, thisLength);
  2204. in.read(size, dest + sizeof(size32_t));
  2205. offset += sizeof(size32_t)+size;
  2206. }
  2207. return offset;
  2208. }
  2209. void RtlUnicodeTypeInfo::readAhead(IRowPrefetcherSource & in) const
  2210. {
  2211. if (isFixedSize())
  2212. {
  2213. size32_t size = length * sizeof(UChar);
  2214. in.skip(size);
  2215. }
  2216. else
  2217. {
  2218. size32_t thisLength = in.readSize();
  2219. size32_t size = thisLength * sizeof(UChar);
  2220. in.skip(size);
  2221. }
  2222. }
  2223. void RtlUnicodeTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  2224. {
  2225. if (isFixedSize())
  2226. {
  2227. return rtlUnicodeToStrX(resultLen, result, length, (const UChar *)ptr);
  2228. }
  2229. else
  2230. {
  2231. size32_t len = rtlReadSize32t(ptr);
  2232. const char * str = (const char *)ptr + sizeof(size32_t);
  2233. return rtlUnicodeToStrX(resultLen, result, len, (const UChar *)str);
  2234. }
  2235. }
  2236. void RtlUnicodeTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  2237. {
  2238. if (isFixedSize())
  2239. {
  2240. return rtlUnicodeToUtf8X(resultLen, result, length, (const UChar *)ptr);
  2241. }
  2242. else
  2243. {
  2244. size32_t len = rtlReadSize32t(ptr);
  2245. const char * str = (const char *)ptr + sizeof(size32_t);
  2246. return rtlUnicodeToUtf8X(resultLen, result, len, (const UChar *)str);
  2247. }
  2248. }
  2249. __int64 RtlUnicodeTypeInfo::getInt(const void * ptr) const
  2250. {
  2251. //Utf8 output is the same as string output, so avoid the intermediate translation
  2252. if (isFixedSize())
  2253. return rtlUnicodeToInt8(length, (const UChar *)ptr);
  2254. size32_t len = rtlReadSize32t(ptr);
  2255. const char * str = (const char *)ptr + sizeof(size32_t);
  2256. return rtlUnicodeToInt8(len, (const UChar *)str);
  2257. }
  2258. int RtlUnicodeTypeInfo::compare(const byte * left, const byte * right) const
  2259. {
  2260. if (isFixedSize())
  2261. return rtlCompareUnicodeUnicode(length, (const UChar *)left, length, (const UChar *)right, locale);
  2262. size32_t lenLeft = rtlReadSize32t(left);
  2263. size32_t lenRight = rtlReadSize32t(right);
  2264. const UChar * valueLeft = reinterpret_cast<const UChar *>(left + sizeof(size32_t));
  2265. const UChar * valueRight = reinterpret_cast<const UChar *>(right + sizeof(size32_t));
  2266. return rtlCompareUnicodeUnicode(lenLeft, valueLeft, lenRight, valueRight, locale);
  2267. }
  2268. int RtlUnicodeTypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  2269. {
  2270. if (isFixedSize())
  2271. {
  2272. lenLeft = std::min(lenLeft, length);
  2273. lenRight = std::min(lenRight, length);
  2274. return rtlCompareUnicodeUnicode(lenLeft, (const UChar *)left, lenRight, (const UChar *)right, locale);
  2275. }
  2276. else
  2277. {
  2278. size32_t maxLeft = rtlReadSize32t(left);
  2279. size32_t maxRight = rtlReadSize32t(right);
  2280. lenLeft = std::min(lenLeft, maxLeft);
  2281. lenRight = std::min(lenRight, maxRight);
  2282. return rtlCompareUnicodeUnicode(lenLeft, (const UChar *)(left + sizeof(size32_t)), lenRight, (const UChar *)(right + sizeof(size32_t)), locale);
  2283. }
  2284. }
  2285. void RtlUnicodeTypeInfo::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  2286. {
  2287. byte *dst = (byte *) buffer;
  2288. size32_t minSize = getMinSize();
  2289. if (value)
  2290. {
  2291. assertex(inclusive);
  2292. if (subLength != MatchFullString)
  2293. {
  2294. if (isFixedSize())
  2295. {
  2296. //Only support a lower bound for unicode substrings - filled with spaces
  2297. assertex(fill == 0);
  2298. //For a substring comparison, the bytes after subLength will eventually never be compared - but index currently does
  2299. size32_t copyLen = std::min(length, subLength);
  2300. rtlUnicodeToUnicode(length, (UChar *)buffer, copyLen, (const UChar *)value);
  2301. }
  2302. else
  2303. {
  2304. size32_t copyLen = std::min(rtlReadSize32t(value), subLength);
  2305. size32_t copySize = copyLen * sizeof(UChar);
  2306. *(size32_t *)buffer = copyLen;
  2307. memcpy(dst + sizeof(size32_t), value + sizeof(size32_t), copySize);
  2308. }
  2309. }
  2310. else
  2311. {
  2312. size32_t copySize = size(value, nullptr);
  2313. memcpy(dst, value, copySize);
  2314. }
  2315. }
  2316. else
  2317. {
  2318. //Generally cannot work for variable length fields - since always possible to create a larger value
  2319. //Default does not work for real types, or variable length signed integers
  2320. assertex(fill == 0);
  2321. memset(dst, fill, minSize);
  2322. }
  2323. }
  2324. unsigned RtlUnicodeTypeInfo::hash(const byte * self, unsigned inhash) const
  2325. {
  2326. size32_t len;
  2327. if (isFixedSize())
  2328. len = length;
  2329. else
  2330. {
  2331. len = rtlReadSize32t(self);
  2332. self += sizeof(size32_t);
  2333. }
  2334. const UChar * uself = reinterpret_cast<const UChar *>(self);
  2335. return rtlHash32Unicode(rtlTrimUnicodeStrLen(len, uself), uself, inhash);
  2336. }
  2337. //-------------------------------------------------------------------------------------------------------------------
  2338. size32_t RtlVarUnicodeTypeInfo::getMinSize() const
  2339. {
  2340. if (isFixedSize())
  2341. return (length+1) * sizeof(UChar);
  2342. return sizeof(UChar);
  2343. }
  2344. size32_t RtlVarUnicodeTypeInfo::size(const byte * self, const byte * selfrow) const
  2345. {
  2346. if (isFixedSize())
  2347. return (length+1) * sizeof(UChar);
  2348. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  2349. return (rtlUnicodeStrlen(ustr)+1) * sizeof(UChar);
  2350. }
  2351. size32_t RtlVarUnicodeTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  2352. {
  2353. size32_t sizeInChars;
  2354. UChar *value;
  2355. source.getUnicodeResult(field, sizeInChars, value);
  2356. if (!isFixedSize())
  2357. {
  2358. size32_t sizeInBytes = (sizeInChars+1) * sizeof(UChar);
  2359. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2360. UChar *dest = (UChar *) (builder.getSelf()+offset);
  2361. memcpy_iflen(dest, value, sizeInBytes - sizeof(UChar));
  2362. dest[sizeInChars] = 0;
  2363. offset += sizeInBytes;
  2364. }
  2365. else
  2366. {
  2367. size32_t sizeInBytes = (length+1) * sizeof(UChar);
  2368. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2369. byte *dest = builder.getSelf()+offset;
  2370. rtlUnicodeToVUnicode(length+1, (UChar *) dest, sizeInChars, value);
  2371. offset += sizeInBytes;
  2372. }
  2373. rtlFree(value);
  2374. return offset;
  2375. }
  2376. size32_t RtlVarUnicodeTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
  2377. {
  2378. size32_t usize;
  2379. rtlDataAttr uvalue;
  2380. rtlUtf8ToUnicodeX(usize, uvalue.refustr(), sizeInChars, value);
  2381. if (!isFixedSize())
  2382. {
  2383. size32_t sizeInBytes = (usize+1) * sizeof(UChar);
  2384. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2385. UChar *dest = (UChar *) (builder.getSelf()+offset);
  2386. memcpy_iflen(dest, uvalue.getustr(), sizeInBytes - sizeof(UChar));
  2387. dest[usize] = 0;
  2388. offset += sizeInBytes;
  2389. }
  2390. else
  2391. {
  2392. size32_t sizeInBytes = (length+1) * sizeof(UChar);
  2393. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2394. byte *dest = builder.getSelf()+offset;
  2395. rtlUnicodeToVUnicode(length+1, (UChar *) dest, usize, uvalue.getustr());
  2396. offset += sizeInBytes;
  2397. }
  2398. return offset;
  2399. }
  2400. size32_t RtlVarUnicodeTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
  2401. {
  2402. size32_t lengthTarget;
  2403. if (!isFixedSize())
  2404. {
  2405. lengthTarget = (sizeInChars + 1);
  2406. }
  2407. else
  2408. {
  2409. lengthTarget = (length + 1);
  2410. }
  2411. size32_t sizeTarget = lengthTarget * sizeof(UChar);
  2412. builder.ensureCapacity(offset+sizeTarget, queryName(field));
  2413. byte *dest = builder.getSelf()+offset;
  2414. rtlStrToVUnicode(lengthTarget, (UChar *) dest, sizeInChars, value);
  2415. offset += sizeTarget;
  2416. return offset;
  2417. }
  2418. size32_t RtlVarUnicodeTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  2419. {
  2420. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  2421. unsigned thisLength = rtlUnicodeStrlen(ustr);
  2422. unsigned thisSize;
  2423. if (isFixedSize())
  2424. thisSize = (length + 1) * sizeof(UChar);
  2425. else
  2426. thisSize = (thisLength + 1) * sizeof(UChar);
  2427. target.processUnicode(thisLength, ustr, field);
  2428. return thisSize;
  2429. }
  2430. size32_t RtlVarUnicodeTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  2431. {
  2432. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  2433. unsigned thisLength = rtlUnicodeStrlen(ustr);
  2434. unsigned thisSize;
  2435. if (isFixedSize())
  2436. thisSize = (length + 1) * sizeof(UChar);
  2437. else
  2438. thisSize = (thisLength + 1) * sizeof(UChar);
  2439. target.outputUnicode(thisLength, ustr, queryScalarXPath(field));
  2440. return thisSize;
  2441. }
  2442. size32_t RtlVarUnicodeTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  2443. {
  2444. if (isFixedSize())
  2445. {
  2446. size32_t size = (length+1)*sizeof(UChar);
  2447. byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
  2448. in.read(size, dest);
  2449. return offset + size;
  2450. }
  2451. else
  2452. return offset + in.readVUni(builder, offset, offset);
  2453. }
  2454. void RtlVarUnicodeTypeInfo::readAhead(IRowPrefetcherSource & in) const
  2455. {
  2456. if (isFixedSize())
  2457. {
  2458. size32_t size = (length+1)*sizeof(UChar);
  2459. in.skip(size);
  2460. }
  2461. else
  2462. {
  2463. in.skipVUni();
  2464. }
  2465. }
  2466. void RtlVarUnicodeTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  2467. {
  2468. const UChar * str = (const UChar *)ptr;
  2469. rtlUnicodeToStrX(resultLen, result, rtlUnicodeStrlen(str), str);
  2470. }
  2471. void RtlVarUnicodeTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  2472. {
  2473. const UChar * str = (const UChar *)ptr;
  2474. rtlUnicodeToUtf8X(resultLen, result, rtlUnicodeStrlen(str), str);
  2475. }
  2476. __int64 RtlVarUnicodeTypeInfo::getInt(const void * ptr) const
  2477. {
  2478. const UChar * str = (const UChar *)ptr;
  2479. return rtlUnicodeToInt8(rtlUnicodeStrlen(str), str);
  2480. }
  2481. int RtlVarUnicodeTypeInfo::compare(const byte * left, const byte * right) const
  2482. {
  2483. const UChar * valueLeft = reinterpret_cast<const UChar *>(left);
  2484. const UChar * valueRight = reinterpret_cast<const UChar *>(right);
  2485. size32_t lenLeft = rtlUnicodeStrlen(valueLeft);
  2486. size32_t lenRight = rtlUnicodeStrlen(valueRight);
  2487. return rtlCompareUnicodeUnicode(lenLeft, valueLeft, lenRight, valueRight, locale);
  2488. }
  2489. int RtlVarUnicodeTypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  2490. {
  2491. size32_t maxLeft = rtlUnicodeStrlen((const UChar *)left);
  2492. size32_t maxRight = rtlUnicodeStrlen((const UChar *)right);
  2493. lenLeft = std::min(lenLeft, maxLeft);
  2494. lenRight = std::min(lenRight, maxRight);
  2495. return rtlCompareUnicodeUnicode(lenLeft, (const UChar *)left, lenRight, (const UChar *)right, locale);
  2496. }
  2497. void RtlVarUnicodeTypeInfo::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  2498. {
  2499. byte *dst = (byte *) buffer;
  2500. size32_t minSize = getMinSize();
  2501. if (value)
  2502. {
  2503. assertex(inclusive);
  2504. if (subLength != MatchFullString)
  2505. {
  2506. UNIMPLEMENTED_X("VarUnicode::setBound(substring)");
  2507. }
  2508. else
  2509. {
  2510. size32_t copySize = size(value, nullptr);
  2511. memcpy(dst, value, copySize);
  2512. }
  2513. }
  2514. else
  2515. {
  2516. //Generally cannot work for variable length fields - since always possible to create a larger value
  2517. //Default does not work for real types, or variable length signed integers
  2518. assertex(fill == 0);
  2519. memset(dst, fill, minSize);
  2520. }
  2521. }
  2522. unsigned RtlVarUnicodeTypeInfo::hash(const byte * _self, unsigned inhash) const
  2523. {
  2524. const UChar * self = reinterpret_cast<const UChar *>(_self);
  2525. return rtlHash32VUnicode(self, inhash);
  2526. }
  2527. //-------------------------------------------------------------------------------------------------------------------
  2528. size32_t RtlUtf8TypeInfo::getMinSize() const
  2529. {
  2530. return sizeof(size32_t);
  2531. }
  2532. size32_t RtlUtf8TypeInfo::size(const byte * self, const byte * selfrow) const
  2533. {
  2534. assertex(!isFixedSize());
  2535. return sizeof(size32_t) + rtlUtf8Size(rtlReadSize32t(self), self+sizeof(unsigned));
  2536. }
  2537. size32_t RtlUtf8TypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  2538. {
  2539. size32_t sizeInChars;
  2540. rtlDataAttr value;
  2541. source.getUTF8Result(field, sizeInChars, value.refstr());
  2542. return buildUtf8(builder, offset, field, sizeInChars, value.getstr());
  2543. }
  2544. size32_t RtlUtf8TypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
  2545. {
  2546. size32_t sizeInBytes = rtlUtf8Size(sizeInChars, value);
  2547. assertex(!isFixedSize());
  2548. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
  2549. byte *dest = builder.getSelf()+offset;
  2550. rtlWriteSize32t(dest, sizeInChars); // NOTE - in chars!
  2551. memcpy_iflen(dest+sizeof(size32_t), value, sizeInBytes);
  2552. return offset + sizeInBytes+sizeof(size32_t);
  2553. }
  2554. size32_t RtlUtf8TypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
  2555. {
  2556. assertex(!isFixedSize());
  2557. //MORE: The target size could be precalculated - which would avoid creating a temporary
  2558. size32_t tempLen;
  2559. rtlDataAttr temp;
  2560. rtlStrToUtf8X(tempLen, temp.refstr(), sizeInChars, value);
  2561. size32_t sizeInBytes = rtlUtf8Size(tempLen, temp.getstr());
  2562. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
  2563. byte *dest = builder.getSelf()+offset;
  2564. rtlWriteSize32t(dest, sizeInChars); // NOTE - in chars!
  2565. memcpy_iflen((dest+sizeof(size32_t)), temp.getstr(), sizeInBytes);
  2566. return offset + sizeInBytes+sizeof(size32_t);
  2567. }
  2568. size32_t RtlUtf8TypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  2569. {
  2570. assertex(!isFixedSize());
  2571. const char * str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  2572. unsigned thisLength = rtlReadSize32t(self);
  2573. unsigned thisSize = sizeof(size32_t) + rtlUtf8Size(thisLength, str);
  2574. target.processUtf8(thisLength, str, field);
  2575. return thisSize;
  2576. }
  2577. size32_t RtlUtf8TypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  2578. {
  2579. assertex(!isFixedSize());
  2580. const char * str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  2581. unsigned thisLength = rtlReadSize32t(self);
  2582. unsigned thisSize = sizeof(size32_t) + rtlUtf8Size(thisLength, str);
  2583. target.outputUtf8(thisLength, str, queryScalarXPath(field));
  2584. return thisSize;
  2585. }
  2586. size32_t RtlUtf8TypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  2587. {
  2588. assertex(!isFixedSize());
  2589. size32_t thisLength = in.readSize();
  2590. size32_t size = in.readUtf8(builder, offset + sizeof(size32_t), offset + sizeof(size32_t), thisLength);
  2591. rtlWriteSize32t(builder.getSelf() + offset, thisLength);
  2592. return offset + sizeof(size32_t) + size;
  2593. }
  2594. void RtlUtf8TypeInfo::readAhead(IRowPrefetcherSource & in) const
  2595. {
  2596. assertex(!isFixedSize());
  2597. size32_t thisLength = in.readSize();
  2598. in.skipUtf8(thisLength);
  2599. }
  2600. void RtlUtf8TypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  2601. {
  2602. if (isFixedSize())
  2603. {
  2604. rtlUtf8ToStrX(resultLen, result, length, (const char *)ptr);
  2605. }
  2606. else
  2607. {
  2608. size32_t len = rtlReadSize32t(ptr);
  2609. rtlUtf8ToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  2610. }
  2611. }
  2612. void RtlUtf8TypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  2613. {
  2614. if (isFixedSize())
  2615. {
  2616. rtlUtf8ToUtf8X(resultLen, result, length, (const char *)ptr);
  2617. }
  2618. else
  2619. {
  2620. size32_t len = rtlReadSize32t(ptr);
  2621. rtlUtf8ToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  2622. }
  2623. }
  2624. __int64 RtlUtf8TypeInfo::getInt(const void * ptr) const
  2625. {
  2626. //Utf8 output is the same as string output, so avoid the intermediate translation
  2627. if (isFixedSize())
  2628. return rtlUtf8ToInt(length, (const char *)ptr);
  2629. size32_t len = rtlReadSize32t(ptr);
  2630. return rtlUtf8ToInt(len, (const char *)ptr + sizeof(size32_t));
  2631. }
  2632. int RtlUtf8TypeInfo::compare(const byte * left, const byte * right) const
  2633. {
  2634. assertex(!isFixedSize());
  2635. size32_t lenLeft = rtlReadSize32t(left);
  2636. size32_t lenRight = rtlReadSize32t(right);
  2637. const char * valueLeft = reinterpret_cast<const char *>(left) + sizeof(size32_t);
  2638. const char * valueRight = reinterpret_cast<const char *>(right) + sizeof(size32_t);
  2639. return rtlCompareUtf8Utf8(lenLeft, valueLeft, lenRight, valueRight, locale);
  2640. }
  2641. int RtlUtf8TypeInfo::compareRange(size32_t lenLeft, const byte * left, size32_t lenRight, const byte * right) const
  2642. {
  2643. size32_t maxLeft = rtlReadSize32t(left);
  2644. size32_t maxRight = rtlReadSize32t(right);
  2645. lenLeft = std::min(lenLeft, maxLeft);
  2646. lenRight = std::min(lenRight, maxRight);
  2647. return rtlCompareUtf8Utf8(lenLeft, (const char *)(left + sizeof(size32_t)), lenRight, (const char *)(right + sizeof(size32_t)), locale);
  2648. }
  2649. void RtlUtf8TypeInfo::setBound(void * buffer, const byte * value, size32_t subLength, byte fill, bool inclusive) const
  2650. {
  2651. assertex(!isFixedSize());
  2652. byte *dst = (byte *) buffer;
  2653. size32_t minSize = getMinSize();
  2654. if (value)
  2655. {
  2656. assertex(inclusive);
  2657. if (subLength != MatchFullString)
  2658. {
  2659. //Note: Only variable length utf8 is supported by the system
  2660. size32_t copyLen = std::min(rtlReadSize32t(value), subLength);
  2661. size32_t copySize = rtlUtf8Size(copyLen, value + sizeof(size32_t));
  2662. *(size32_t *)buffer = copyLen;
  2663. memcpy(dst + sizeof(size32_t), value + sizeof(size32_t), copySize);
  2664. }
  2665. else
  2666. {
  2667. size32_t copySize = size(value, nullptr);
  2668. memcpy(dst, value, copySize);
  2669. }
  2670. }
  2671. else
  2672. {
  2673. //Generally cannot work for variable length fields - since always possible to create a larger value
  2674. //Default does not work for real types, or variable length signed integers
  2675. assertex(fill == 0);
  2676. memset_iflen(dst, fill, minSize);
  2677. }
  2678. }
  2679. unsigned RtlUtf8TypeInfo::hash(const byte * self, unsigned inhash) const
  2680. {
  2681. assertex(!isFixedSize());
  2682. size32_t len = rtlReadSize32t(self);
  2683. const char * uself = reinterpret_cast<const char *>(self + sizeof(size32_t));
  2684. return rtlHash32Utf8(rtlTrimUtf8StrLen(len, uself), uself,inhash);
  2685. }
  2686. //-------------------------------------------------------------------------------------------------------------------
  2687. inline size32_t sizeFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow)
  2688. {
  2689. unsigned offset = 0;
  2690. for (;;)
  2691. {
  2692. const RtlFieldInfo * child = *cur;
  2693. if (!child)
  2694. break;
  2695. offset += child->size(self+offset, selfrow);
  2696. cur++;
  2697. }
  2698. return offset;
  2699. }
  2700. static size32_t processFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow, IFieldProcessor & target)
  2701. {
  2702. unsigned offset = 0;
  2703. for (;;)
  2704. {
  2705. const RtlFieldInfo * child = *cur;
  2706. if (!child)
  2707. break;
  2708. child->process(self+offset, selfrow, target);
  2709. offset += child->size(self+offset, selfrow);
  2710. cur++;
  2711. }
  2712. return offset;
  2713. }
  2714. static size32_t buildFields(const RtlFieldInfo * const * cur, ARowBuilder &builder, size32_t offset, IFieldSource &source)
  2715. {
  2716. for (;;)
  2717. {
  2718. const RtlFieldInfo * child = *cur;
  2719. if (!child)
  2720. break;
  2721. offset = child->build(builder, offset, source);
  2722. cur++;
  2723. }
  2724. return offset;
  2725. }
  2726. static size32_t toXMLFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow, IXmlWriter & target)
  2727. {
  2728. size32_t offset = 0;
  2729. for (;;)
  2730. {
  2731. const RtlFieldInfo * child = *cur;
  2732. if (!child)
  2733. break;
  2734. size32_t size = child->toXML(self+offset, selfrow, target);
  2735. offset += size;
  2736. cur++;
  2737. }
  2738. return offset;
  2739. }
  2740. static size32_t deserializeFields(const RtlFieldInfo * const * cur, ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset)
  2741. {
  2742. for (;;)
  2743. {
  2744. const RtlFieldInfo * child = *cur;
  2745. if (!child)
  2746. break;
  2747. offset = child->type->deserialize(builder, in, offset);
  2748. cur++;
  2749. }
  2750. return offset;
  2751. }
  2752. static void readAheadFields(const RtlFieldInfo * const * cur, IRowPrefetcherSource & in)
  2753. {
  2754. for (;;)
  2755. {
  2756. const RtlFieldInfo * child = *cur;
  2757. if (!child)
  2758. break;
  2759. child->type->readAhead(in);
  2760. cur++;
  2761. }
  2762. }
  2763. int ECLRTL_API compareFields(const RtlFieldInfo * const * cur, const byte * left, const byte * right, bool excludePayload)
  2764. {
  2765. size32_t leftOffset = 0;
  2766. size32_t rightOffset = 0;
  2767. for (;;)
  2768. {
  2769. const RtlFieldInfo * child = *cur;
  2770. if (!child || (excludePayload && (child->flags & RFTMispayloadfield)))
  2771. return 0;
  2772. auto type = child->type;
  2773. int rc = type->compare(left + leftOffset, right + rightOffset);
  2774. if (rc != 0)
  2775. return rc;
  2776. leftOffset += type->size(left + leftOffset, left);
  2777. rightOffset += type->size(right + rightOffset, right);
  2778. cur++;
  2779. }
  2780. }
  2781. unsigned ECLRTL_API hashFields(const RtlFieldInfo * const * cur, const byte *self, unsigned inhash, bool excludePayload)
  2782. {
  2783. size32_t offset = 0;
  2784. for (;;)
  2785. {
  2786. const RtlFieldInfo * child = *cur;
  2787. if (!child || (excludePayload && (child->flags & RFTMispayloadfield)))
  2788. break;
  2789. auto type = child->type;
  2790. inhash = type->hash(self + offset, inhash);
  2791. offset += type->size(self + offset, self);
  2792. cur++;
  2793. }
  2794. return inhash;
  2795. }
  2796. extern bool ECLRTL_API hasTrailingFileposition(const RtlFieldInfo * const * fields)
  2797. {
  2798. if (!*fields)
  2799. return false;
  2800. while (*fields)
  2801. fields++;
  2802. return (fields[-1]->type->getType() == type_filepos); // note - filepos is created as an RtlSwapIntTypeInfo with type set to type_filepos
  2803. }
  2804. extern bool ECLRTL_API hasTrailingFileposition(const RtlTypeInfo * type)
  2805. {
  2806. switch (type->getType())
  2807. {
  2808. case type_record:
  2809. {
  2810. const RtlRecordTypeInfo * record = static_cast<const RtlRecordTypeInfo *>(type);
  2811. return hasTrailingFileposition(record->fields);
  2812. }
  2813. }
  2814. return false;
  2815. }
  2816. //Does the field list contain a keyed int? We are not interested in fields inside child datasets.
  2817. //And keyed fields cannot exist within ifblocks.
  2818. static bool containsKeyedSignedInt(const RtlFieldInfo * const * fields)
  2819. {
  2820. if (!*fields)
  2821. return false;
  2822. while (*fields)
  2823. {
  2824. const RtlTypeInfo * type = (*fields)->type;
  2825. if (type->getType() == type_keyedint)
  2826. {
  2827. const RtlTypeInfo * baseType = type->queryChildType();
  2828. if (baseType->isSigned() && (baseType->getType() == type_int))
  2829. return true;
  2830. }
  2831. else if (type->getType() == type_record)
  2832. {
  2833. const RtlRecordTypeInfo * record = static_cast<const RtlRecordTypeInfo *>(type);
  2834. if (containsKeyedSignedInt(record->fields))
  2835. return true;
  2836. }
  2837. fields++;
  2838. }
  2839. return false;
  2840. }
  2841. extern bool ECLRTL_API containsKeyedSignedInt(const RtlTypeInfo * type)
  2842. {
  2843. switch (type->getType())
  2844. {
  2845. case type_record:
  2846. {
  2847. const RtlRecordTypeInfo * record = static_cast<const RtlRecordTypeInfo *>(type);
  2848. return containsKeyedSignedInt(record->fields);
  2849. }
  2850. }
  2851. return false;
  2852. }
  2853. //-------------------------------------------------------------------------------------------------------------------
  2854. size32_t RtlRecordTypeInfo::getMinSize() const
  2855. {
  2856. return ::getMinSize(fields);
  2857. }
  2858. size32_t RtlRecordTypeInfo::size(const byte * self, const byte * selfrow) const
  2859. {
  2860. return sizeFields(fields, self, self);
  2861. }
  2862. size32_t RtlRecordTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  2863. {
  2864. if (target.processBeginRow(field))
  2865. {
  2866. unsigned offset = processFields(fields, self, self, target);
  2867. target.processEndRow(field);
  2868. return offset;
  2869. }
  2870. return size(self, selfrow);
  2871. }
  2872. size32_t RtlRecordTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  2873. {
  2874. const char * xpath = queryXPath(field);
  2875. if (*xpath)
  2876. target.outputBeginNested(xpath, false);
  2877. unsigned thisSize = toXMLFields(fields, self, self, target);
  2878. if (*xpath)
  2879. target.outputEndNested(xpath);
  2880. return thisSize;
  2881. }
  2882. size32_t RtlRecordTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  2883. {
  2884. //Will not generally be called because it will have been expanded
  2885. return deserializeFields(fields, builder, in, offset);
  2886. }
  2887. void RtlRecordTypeInfo::readAhead(IRowPrefetcherSource & in) const
  2888. {
  2889. //This could be called if the record contains ifblocks
  2890. in.noteStartChild();
  2891. readAheadFields(fields, in);
  2892. in.noteFinishChild();
  2893. }
  2894. size32_t RtlRecordTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  2895. {
  2896. source.processBeginRow(field);
  2897. offset = buildFields(fields, builder, offset, source);
  2898. source.processEndRow(field);
  2899. return offset;
  2900. }
  2901. size32_t RtlRecordTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
  2902. {
  2903. const RtlFieldInfo * const * cur = fields;
  2904. for (;;)
  2905. {
  2906. const RtlFieldInfo * child = *cur;
  2907. if (!child)
  2908. break;
  2909. offset = child->type->buildNull(builder, offset, child);
  2910. cur++;
  2911. }
  2912. return offset;
  2913. }
  2914. size32_t RtlRecordTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  2915. {
  2916. throwUnexpected();
  2917. }
  2918. size32_t RtlRecordTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  2919. {
  2920. throwUnexpected();
  2921. }
  2922. void RtlRecordTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  2923. {
  2924. resultLen = 0;
  2925. result = nullptr;
  2926. }
  2927. void RtlRecordTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  2928. {
  2929. resultLen = 0;
  2930. result = nullptr;
  2931. }
  2932. __int64 RtlRecordTypeInfo::getInt(const void * ptr) const
  2933. {
  2934. return 0;
  2935. }
  2936. int RtlRecordTypeInfo::compare(const byte * left, const byte * right) const
  2937. {
  2938. return compareFields(fields, left, right);
  2939. }
  2940. unsigned RtlRecordTypeInfo::hash(const byte * self, unsigned inhash) const
  2941. {
  2942. return hashFields(fields, self, inhash);
  2943. }
  2944. //-------------------------------------------------------------------------------------------------------------------
  2945. size32_t RtlCompoundTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  2946. {
  2947. UNIMPLEMENTED;
  2948. }
  2949. size32_t RtlCompoundTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  2950. {
  2951. UNIMPLEMENTED;
  2952. }
  2953. void RtlCompoundTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  2954. {
  2955. //MORE: Should this fail instead?
  2956. resultLen = 0;
  2957. result = nullptr;
  2958. }
  2959. void RtlCompoundTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  2960. {
  2961. //MORE: Should this fail instead?
  2962. resultLen = 0;
  2963. result = nullptr;
  2964. }
  2965. __int64 RtlCompoundTypeInfo::getInt(const void * ptr) const
  2966. {
  2967. //MORE: Should this fail instead?
  2968. return 0;
  2969. }
  2970. //-------------------------------------------------------------------------------------------------------------------
  2971. size32_t RtlSetTypeInfo::getMinSize() const
  2972. {
  2973. return sizeof(bool) + sizeof(size32_t);
  2974. }
  2975. size32_t RtlSetTypeInfo::size(const byte * self, const byte * selfrow) const
  2976. {
  2977. return sizeof(bool) + sizeof(size32_t) + rtlReadSize32t(self + sizeof(bool));
  2978. }
  2979. size32_t RtlSetTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  2980. {
  2981. bool isAll;
  2982. source.processBeginSet(field, isAll);
  2983. size32_t sizeInBytes = sizeof(bool) + sizeof(size32_t);
  2984. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  2985. byte *dest = builder.getSelf()+offset;
  2986. if (isAll)
  2987. {
  2988. * (bool *) dest = true;
  2989. rtlWriteInt4(dest+1, 0);
  2990. offset += sizeInBytes;
  2991. }
  2992. else
  2993. {
  2994. * (bool *) dest = false;
  2995. size32_t newOffset = offset + sizeInBytes;
  2996. RtlFieldStrInfo dummyField("<set element>", NULL, child);
  2997. while (source.processNextSet(field))
  2998. {
  2999. newOffset = child->build(builder, newOffset, &dummyField, source);
  3000. }
  3001. // Go back in and patch the size, remembering it may have moved
  3002. rtlWriteInt4(builder.getSelf()+offset+1, newOffset - (offset+sizeInBytes));
  3003. offset = newOffset;
  3004. }
  3005. source.processEndSet(field);
  3006. return offset;
  3007. }
  3008. size32_t RtlSetTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3009. {
  3010. unsigned offset = sizeof(bool) + sizeof(size32_t);
  3011. unsigned max = offset + rtlReadSize32t(self + sizeof(bool));
  3012. unsigned elements = 0;
  3013. if (!*(bool *)self)
  3014. {
  3015. unsigned tempOffset = sizeof(bool) + sizeof(size32_t);
  3016. if (child->isFixedSize())
  3017. {
  3018. unsigned elemSize = child->size(NULL, NULL);
  3019. elements = (max-offset) / elemSize;
  3020. assert(elements*elemSize == max-offset);
  3021. }
  3022. else
  3023. {
  3024. DummyFieldProcessor dummy;
  3025. while (tempOffset < max)
  3026. {
  3027. tempOffset += child->process(self+tempOffset, selfrow, field, dummy); // NOTE - good thing we can't have a set of sets, or this would recurse
  3028. elements++;
  3029. }
  3030. }
  3031. }
  3032. if (target.processBeginSet(field, elements, *(bool *)self, self+offset))
  3033. {
  3034. while (offset < max)
  3035. {
  3036. offset += child->process(self+offset, selfrow, field, target);
  3037. }
  3038. }
  3039. target.processEndSet(field);
  3040. return max;
  3041. }
  3042. size32_t RtlSetTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3043. {
  3044. unsigned offset = sizeof(bool) + sizeof(size32_t);
  3045. unsigned max = offset + rtlReadSize32t(self + sizeof(bool));
  3046. StringAttr outerTag;
  3047. if (hasOuterXPath(field))
  3048. {
  3049. queryNestedOuterXPath(outerTag, field);
  3050. target.outputBeginNested(outerTag, false);
  3051. }
  3052. if (*(bool *)self)
  3053. target.outputSetAll();
  3054. else
  3055. {
  3056. const char *innerPath = queryXPath(field);
  3057. target.outputBeginArray(innerPath);
  3058. while (offset < max)
  3059. {
  3060. child->toXML(self+offset, selfrow, field, target);
  3061. offset += child->size(self+offset, selfrow);
  3062. }
  3063. target.outputEndArray(innerPath);
  3064. }
  3065. if (outerTag)
  3066. target.outputEndNested(outerTag);
  3067. return max;
  3068. }
  3069. size32_t RtlSetTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  3070. {
  3071. bool isAll;
  3072. in.read(1, &isAll);
  3073. size32_t size = in.readSize();
  3074. byte * dest = builder.ensureCapacity(offset+sizeof(bool)+sizeof(size32_t)+size, nullptr) + offset;
  3075. *dest = isAll;
  3076. rtlWriteSize32t(dest + sizeof(bool), size);
  3077. in.read(size, dest + sizeof(bool) + sizeof(size32_t));
  3078. return offset+sizeof(bool)+sizeof(size32_t)+size;
  3079. }
  3080. void RtlSetTypeInfo::readAhead(IRowPrefetcherSource & in) const
  3081. {
  3082. in.skip(1);
  3083. size32_t thisLength = in.readSize();
  3084. in.skip(thisLength);
  3085. }
  3086. int RtlSetTypeInfo::compare(const byte * left, const byte * right) const
  3087. {
  3088. const bool allLeft = *(const bool *)left;
  3089. const bool allRight = *(const bool *)right;
  3090. if (allLeft || allRight)
  3091. {
  3092. if (allLeft && allRight)
  3093. return 0;
  3094. if (allLeft)
  3095. return +1;
  3096. else
  3097. return -1;
  3098. }
  3099. size32_t sizeLeft = rtlReadSize32t(left + sizeof(bool));
  3100. const byte * ptrLeft = left + sizeof(bool) + sizeof(size32_t);
  3101. size32_t sizeRight = rtlReadSize32t(right + sizeof(bool));
  3102. const byte * ptrRight = right + sizeof(bool) + sizeof(size32_t);
  3103. size32_t offLeft = 0;
  3104. size32_t offRight = 0;
  3105. for (;;)
  3106. {
  3107. if ((offLeft == sizeLeft) || (offRight == sizeRight))
  3108. {
  3109. if ((offLeft == sizeLeft) && (offRight == sizeRight))
  3110. return 0;
  3111. if (offLeft == sizeLeft)
  3112. return -1;
  3113. else
  3114. return +1;
  3115. }
  3116. int rc = child->compare(ptrLeft + offLeft, ptrRight + offRight);
  3117. if (rc != 0)
  3118. return rc;
  3119. offLeft += child->size(ptrLeft + offLeft, ptrLeft + offLeft);
  3120. offRight += child->size(ptrRight + offRight, ptrRight + offRight);
  3121. }
  3122. }
  3123. unsigned RtlSetTypeInfo::hash(const byte * self, unsigned inhash) const
  3124. {
  3125. const bool allLeft = *(const bool *) self;
  3126. self += sizeof(bool);
  3127. if (allLeft)
  3128. {
  3129. // Nothing - this is unfortunate as it means hash(all) and hash([]) are the same...
  3130. // But it matches generated code
  3131. }
  3132. else
  3133. {
  3134. size32_t size = rtlReadSize32t(self);
  3135. self += sizeof(size32_t);
  3136. #if 0
  3137. // This might be the smart way to hash - since it means that the hash depends on the value, not the type,
  3138. // and that things that compare equal will hash equal. But that is not what the code generator does
  3139. for (size32_t offset = 0; offset < size; offset += child->size(self + offset, self + offset))
  3140. {
  3141. inhash = child->hash(self + offset, inhash);
  3142. }
  3143. #else
  3144. inhash = rtlHash32Data(size, self, inhash);
  3145. #endif
  3146. }
  3147. return inhash;
  3148. }
  3149. //-------------------------------------------------------------------------------------------------------------------
  3150. size32_t RtlRowTypeInfo::getMinSize() const
  3151. {
  3152. if (isLinkCounted())
  3153. return sizeof(void *);
  3154. return child->getMinSize();
  3155. }
  3156. size32_t RtlRowTypeInfo::size(const byte * self, const byte * selfrow) const
  3157. {
  3158. if (isLinkCounted())
  3159. return sizeof(void *);
  3160. return child->size(self, selfrow);
  3161. }
  3162. size32_t RtlRowTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3163. {
  3164. if (isLinkCounted())
  3165. {
  3166. const byte * row = *(const byte * *)self;
  3167. if (row)
  3168. child->process(row, row, field, target);
  3169. return sizeof(row);
  3170. }
  3171. return child->process(self, self, field, target);
  3172. }
  3173. size32_t RtlRowTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3174. {
  3175. if (isLinkCounted())
  3176. {
  3177. const byte * row = *(const byte * *)self;
  3178. child->toXML(row, row, field, target);
  3179. return sizeof(row);
  3180. }
  3181. return child->toXML(self, self, field, target);
  3182. }
  3183. size32_t RtlRowTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  3184. {
  3185. //Link counted isn't yet implemented in the code generator
  3186. if (isLinkCounted())
  3187. UNIMPLEMENTED;
  3188. return child->deserialize(builder, in, offset);
  3189. }
  3190. void RtlRowTypeInfo::readAhead(IRowPrefetcherSource & in) const
  3191. {
  3192. return child->readAhead(in);
  3193. }
  3194. int RtlRowTypeInfo::compare(const byte * left, const byte * right) const
  3195. {
  3196. if (isLinkCounted())
  3197. {
  3198. const byte * leftRow = *(const byte * *)left;
  3199. const byte * rightRow = *(const byte * *)right;
  3200. if (leftRow && rightRow)
  3201. return child->compare(leftRow, rightRow);
  3202. if (leftRow)
  3203. return +1;
  3204. if (rightRow)
  3205. return -1;
  3206. return 0;
  3207. }
  3208. return child->compare(left, right);
  3209. }
  3210. unsigned RtlRowTypeInfo::hash(const byte * self, unsigned inhash) const
  3211. {
  3212. if (isLinkCounted())
  3213. {
  3214. const byte * selfRow = *(const byte * *)self;
  3215. if (selfRow)
  3216. inhash = child->hash(selfRow, inhash);
  3217. return inhash;
  3218. }
  3219. return child->hash(self, inhash);
  3220. }
  3221. //-------------------------------------------------------------------------------------------------------------------
  3222. size32_t RtlDatasetTypeInfo::getMinSize() const
  3223. {
  3224. if (isLinkCounted())
  3225. return sizeof(size32_t) + sizeof(void * *);
  3226. return sizeof(size32_t);
  3227. }
  3228. size32_t RtlDatasetTypeInfo::size(const byte * self, const byte * selfrow) const
  3229. {
  3230. if (isLinkCounted())
  3231. return sizeof(size32_t) + sizeof(void * *);
  3232. return sizeof(size32_t) + rtlReadSize32t(self);
  3233. }
  3234. size32_t RtlDatasetTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  3235. {
  3236. source.processBeginDataset(field);
  3237. if (isLinkCounted())
  3238. {
  3239. // a 32-bit record count, and a pointer to an array of record pointers
  3240. size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
  3241. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  3242. size32_t numRows = 0;
  3243. Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
  3244. const byte **childRows = NULL;
  3245. RtlFieldStrInfo dummyField("<nested row>", NULL, child);
  3246. while (source.processNextRow(field))
  3247. {
  3248. RtlDynamicRowBuilder childBuilder(*childAllocator);
  3249. size32_t childLen = child->build(childBuilder, 0, &dummyField, source);
  3250. childRows = childAllocator->appendRowOwn(childRows, ++numRows, (void *) childBuilder.finalizeRowClear(childLen));
  3251. }
  3252. // Go back in and patch the count, remembering it may have moved
  3253. rtlWriteInt4(builder.getSelf()+offset, numRows);
  3254. * ( const void * * ) (builder.getSelf()+offset+sizeof(size32_t)) = childRows;
  3255. offset += sizeInBytes;
  3256. }
  3257. else
  3258. {
  3259. // a 32-bit size, then rows inline
  3260. size32_t sizeInBytes = sizeof(size32_t);
  3261. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  3262. size32_t newOffset = offset + sizeInBytes;
  3263. RtlFieldStrInfo dummyField("<nested row>", NULL, child);
  3264. while (source.processNextRow(field))
  3265. newOffset = child->build(builder, newOffset, &dummyField, source);
  3266. // Go back in and patch the size, remembering it may have moved
  3267. rtlWriteInt4(builder.getSelf()+offset, newOffset - (offset+sizeInBytes));
  3268. offset = newOffset;
  3269. }
  3270. source.processEndDataset(field);
  3271. return offset;
  3272. }
  3273. size32_t RtlDatasetTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3274. {
  3275. if (isLinkCounted())
  3276. {
  3277. size32_t thisCount = rtlReadSize32t(self);
  3278. if (target.processBeginDataset(field, thisCount))
  3279. {
  3280. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  3281. for (unsigned i= 0; i < thisCount; i++)
  3282. {
  3283. const byte * row = rows[i];
  3284. child->process(row, row, field, target);
  3285. }
  3286. target.processEndDataset(field);
  3287. }
  3288. return sizeof(size32_t) + sizeof(void * *);
  3289. }
  3290. else
  3291. {
  3292. unsigned offset = sizeof(size32_t);
  3293. unsigned max = offset + rtlReadSize32t(self);
  3294. unsigned thisCount = 0;
  3295. DummyFieldProcessor dummy;
  3296. while (offset < max)
  3297. {
  3298. offset += child->process(self+offset, self+offset, field, dummy);
  3299. thisCount++;
  3300. }
  3301. offset = sizeof(size32_t);
  3302. if (target.processBeginDataset(field, thisCount))
  3303. {
  3304. while (offset < max)
  3305. {
  3306. offset += child->process(self+offset, self+offset, field, target);
  3307. }
  3308. target.processEndDataset(field);
  3309. }
  3310. return max;
  3311. }
  3312. }
  3313. size32_t RtlDatasetTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3314. {
  3315. StringAttr outerTag;
  3316. if (hasOuterXPath(field))
  3317. {
  3318. queryNestedOuterXPath(outerTag, field);
  3319. target.outputBeginNested(outerTag, false);
  3320. }
  3321. const char *innerPath = queryXPath(field);
  3322. target.outputBeginArray(innerPath);
  3323. unsigned thisSize;
  3324. if (isLinkCounted())
  3325. {
  3326. size32_t thisCount = rtlReadSize32t(self);
  3327. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  3328. for (unsigned i= 0; i < thisCount; i++)
  3329. {
  3330. const byte * row = rows[i];
  3331. if (row)
  3332. child->toXML(row, row, field, target);
  3333. }
  3334. thisSize = sizeof(size32_t) + sizeof(void * *);
  3335. }
  3336. else
  3337. {
  3338. unsigned offset = sizeof(size32_t);
  3339. unsigned max = offset + rtlReadSize32t(self);
  3340. while (offset < max)
  3341. {
  3342. child->toXML(self+offset, self+offset, field, target);
  3343. offset += child->size(self+offset, self+offset);
  3344. }
  3345. thisSize = max;
  3346. }
  3347. target.outputEndArray(innerPath);
  3348. if (outerTag)
  3349. target.outputEndNested(outerTag);
  3350. return thisSize;
  3351. }
  3352. size32_t RtlDatasetTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  3353. {
  3354. const bool canUseMemcpy = true;
  3355. if (canUseMemcpy && !isLinkCounted())
  3356. {
  3357. size32_t size = in.readSize();
  3358. byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
  3359. rtlWriteSize32t(dest, size);
  3360. in.read(size, dest + sizeof(size32_t));
  3361. return offset + sizeof(size32_t) + size;
  3362. }
  3363. else
  3364. {
  3365. if (isLinkCounted())
  3366. {
  3367. //Currently inefficient because it is recreating deserializers and resolving child allocators each time it is called.
  3368. ICodeContext * ctx = nullptr; // Slightly dodgy, but not needed if the child deserializers are also calculated
  3369. unsigned activityId = 0;
  3370. // a 32-bit record count, and a pointer to an hash table with record pointers
  3371. size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
  3372. byte * dest = builder.ensureCapacity(offset+sizeInBytes, nullptr) + offset;
  3373. Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
  3374. Owned<IOutputRowDeserializer> deserializer = childAllocator->queryOutputMeta()->createDiskDeserializer(ctx, activityId);
  3375. rtlDeserializeChildRowset(*(size32_t *)dest, *(const byte * * *)(dest + sizeof(size32_t)), childAllocator, deserializer, in);
  3376. return offset + sizeInBytes;
  3377. }
  3378. else
  3379. {
  3380. size32_t startOffset = offset + sizeof(size32_t);
  3381. size32_t nextOffset = startOffset;
  3382. offset_t endOffset = in.beginNested();
  3383. while (in.finishedNested(endOffset))
  3384. nextOffset = child->deserialize(builder, in, nextOffset);
  3385. rtlWriteSize32t(builder.getSelf() + offset, nextOffset - startOffset);
  3386. return nextOffset;
  3387. }
  3388. }
  3389. }
  3390. void RtlDatasetTypeInfo::readAhead(IRowPrefetcherSource & in) const
  3391. {
  3392. size32_t size = in.readSize();
  3393. in.skip(size);
  3394. }
  3395. int RtlDatasetTypeInfo::compare(const byte * left, const byte * right) const
  3396. {
  3397. if (isLinkCounted())
  3398. {
  3399. const size32_t countLeft = rtlReadSize32t(left);
  3400. const size32_t countRight = rtlReadSize32t(right);
  3401. const byte * * rowsLeft = (const byte * *)((const byte *)left + sizeof(size32_t));
  3402. const byte * * rowsRight = (const byte * *)((const byte *)right + sizeof(size32_t));
  3403. size32_t row = 0;
  3404. for (;;)
  3405. {
  3406. if ((row == countLeft) || (row == countRight))
  3407. {
  3408. if (countLeft == countRight)
  3409. return 0;
  3410. if (row == countLeft)
  3411. return -1;
  3412. else
  3413. return +1;
  3414. }
  3415. int rc = child->compare(rowsLeft[row], rowsRight[row]);
  3416. if (rc != 0)
  3417. return rc;
  3418. row++;
  3419. }
  3420. }
  3421. size32_t lenLeft = rtlReadSize32t(left);
  3422. size32_t lenRight = rtlReadSize32t(right);
  3423. const byte * ptrLeft = left + sizeof(size32_t);
  3424. const byte * ptrRight = right + sizeof(size32_t);
  3425. size32_t offLeft = 0;
  3426. size32_t offRight = 0;
  3427. for (;;)
  3428. {
  3429. if ((offLeft == lenLeft) || (offRight == lenRight))
  3430. {
  3431. if ((offLeft == lenLeft) && (offRight == lenRight))
  3432. return 0;
  3433. if (offLeft == lenLeft)
  3434. return -1;
  3435. else
  3436. return +1;
  3437. }
  3438. int rc = child->compare(ptrLeft + offLeft, ptrRight + offRight);
  3439. if (rc != 0)
  3440. return rc;
  3441. offLeft += child->size(ptrLeft + offLeft, ptrLeft + offLeft);
  3442. offRight += child->size(ptrRight + offRight, ptrRight + offRight);
  3443. }
  3444. }
  3445. unsigned RtlDatasetTypeInfo::hash(const byte * self, unsigned inhash) const
  3446. {
  3447. if (isLinkCounted())
  3448. {
  3449. const size32_t count = rtlReadSize32t(self);
  3450. self += sizeof(size32_t);
  3451. const byte * * rows = (const byte * *) self;
  3452. for (size32_t row = 0; row < count; row++)
  3453. {
  3454. inhash = child->hash(rows[row], inhash);
  3455. }
  3456. }
  3457. else
  3458. {
  3459. size32_t len = rtlReadSize32t(self);
  3460. self += sizeof(size32_t);
  3461. for (size32_t offset = 0; offset < len; offset += child->size(self + offset, self + offset))
  3462. {
  3463. inhash = child->hash(self + offset, inhash);
  3464. }
  3465. }
  3466. return inhash;
  3467. }
  3468. //-------------------------------------------------------------------------------------------------------------------
  3469. size32_t RtlDictionaryTypeInfo::getMinSize() const
  3470. {
  3471. if (isLinkCounted())
  3472. return sizeof(size32_t) + sizeof(void * *);
  3473. return sizeof(size32_t);
  3474. }
  3475. size32_t RtlDictionaryTypeInfo::size(const byte * self, const byte * selfrow) const
  3476. {
  3477. if (isLinkCounted())
  3478. return sizeof(size32_t) + sizeof(void * *);
  3479. return sizeof(size32_t) + rtlReadSize32t(self);
  3480. }
  3481. size32_t RtlDictionaryTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  3482. {
  3483. source.processBeginDataset(field);
  3484. if (isLinkCounted())
  3485. {
  3486. // a 32-bit record count, and a pointer to an hash table with record pointers
  3487. size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
  3488. builder.ensureCapacity(offset+sizeInBytes, queryName(field));
  3489. Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
  3490. CHThorHashLookupInfo hashInfo(*static_cast<const RtlRecordTypeInfo *>(child));
  3491. RtlLinkedDictionaryBuilder dictBuilder(childAllocator, &hashInfo);
  3492. RtlFieldStrInfo dummyField("<nested row>", NULL, child);
  3493. while (source.processNextRow(field))
  3494. {
  3495. RtlDynamicRowBuilder childBuilder(childAllocator);
  3496. size32_t childLen = child->build(childBuilder, 0, &dummyField, source);
  3497. dictBuilder.appendOwn((void *) childBuilder.finalizeRowClear(childLen));
  3498. }
  3499. // Go back in and patch the count
  3500. rtlWriteInt4(builder.getSelf()+offset, dictBuilder.getcount());
  3501. * ( const void * * ) (builder.getSelf()+offset+sizeof(size32_t)) = dictBuilder.linkrows();
  3502. offset += sizeInBytes;
  3503. }
  3504. else
  3505. throwUnexpected(); // And may never be...
  3506. source.processEndDataset(field);
  3507. return offset;
  3508. }
  3509. size32_t RtlDictionaryTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3510. {
  3511. if (isLinkCounted())
  3512. {
  3513. size32_t thisCount = rtlReadSize32t(self);
  3514. if (target.processBeginDataset(field, thisCount))
  3515. {
  3516. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  3517. for (unsigned i= 0; i < thisCount; i++)
  3518. {
  3519. const byte * row = rows[i];
  3520. if (row)
  3521. child->process(row, row, field, target);
  3522. }
  3523. target.processEndDataset(field);
  3524. }
  3525. return sizeof(size32_t) + sizeof(void * *);
  3526. }
  3527. else
  3528. {
  3529. //MORE: We could interpret serialized dictionaries if there was ever a need
  3530. throwUnexpected();
  3531. }
  3532. }
  3533. size32_t RtlDictionaryTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3534. {
  3535. StringAttr outerTag;
  3536. if (hasOuterXPath(field))
  3537. {
  3538. queryNestedOuterXPath(outerTag, field);
  3539. target.outputBeginNested(outerTag, false);
  3540. }
  3541. const char *innerPath = queryXPath(field);
  3542. target.outputBeginArray(innerPath);
  3543. unsigned thisSize;
  3544. if (isLinkCounted())
  3545. {
  3546. size32_t thisCount = rtlReadSize32t(self);
  3547. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  3548. for (unsigned i= 0; i < thisCount; i++)
  3549. {
  3550. const byte * row = rows[i];
  3551. if (row)
  3552. child->toXML(row, row, field, target);
  3553. }
  3554. thisSize = sizeof(size32_t) + sizeof(void * *);
  3555. }
  3556. else
  3557. {
  3558. //MORE: We could interpret serialized dictionaries if there was ever a need
  3559. throwUnexpected();
  3560. }
  3561. target.outputEndArray(innerPath);
  3562. if (outerTag)
  3563. target.outputEndNested(outerTag);
  3564. return thisSize;
  3565. }
  3566. size32_t RtlDictionaryTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  3567. {
  3568. if (isLinkCounted())
  3569. {
  3570. //Currently inefficient because it is recreating deserializers and resolving child allocators each time it is called.
  3571. ICodeContext * ctx = nullptr; // Slightly dodgy, but not needed if the child deserializers are also calculated
  3572. unsigned activityId = 0;
  3573. // a 32-bit record count, and a pointer to an hash table with record pointers
  3574. size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
  3575. byte * dest = builder.ensureCapacity(offset + sizeInBytes, nullptr) + offset;
  3576. Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
  3577. Owned<IOutputRowDeserializer> deserializer = childAllocator->queryOutputMeta()->createDiskDeserializer(ctx, activityId);
  3578. rtlDeserializeChildDictionary(*(size32_t *)dest, *(const byte * * *)(dest + sizeof(size32_t)), childAllocator, deserializer, in);
  3579. return offset + sizeInBytes;
  3580. }
  3581. else
  3582. {
  3583. UNIMPLEMENTED;
  3584. }
  3585. }
  3586. void RtlDictionaryTypeInfo::readAhead(IRowPrefetcherSource & in) const
  3587. {
  3588. size32_t size = in.readSize();
  3589. in.skip(size);
  3590. }
  3591. int RtlDictionaryTypeInfo::compare(const byte * left, const byte * right) const
  3592. {
  3593. if (isLinkCounted())
  3594. {
  3595. const size32_t countLeft = rtlReadSize32t(left);
  3596. const size32_t countRight = rtlReadSize32t(right);
  3597. const byte * * rowsLeft = (const byte * *)((const byte *)left + sizeof(size32_t));
  3598. const byte * * rowsRight = (const byte * *)((const byte *)right + sizeof(size32_t));
  3599. size32_t leftRow = 0;
  3600. size32_t rightRow = 0;
  3601. for (;;)
  3602. {
  3603. //Dictionaries are compared as datasets => skip until the first non-null entry
  3604. while ((leftRow != countLeft) && !rowsLeft[leftRow])
  3605. leftRow++;
  3606. while ((rightRow != countRight) && !rowsRight[rightRow])
  3607. rightRow++;
  3608. if ((leftRow == countLeft) || (rightRow == countRight))
  3609. {
  3610. if ((leftRow == countLeft) && (rightRow == countRight))
  3611. return 0;
  3612. if (leftRow == countLeft)
  3613. return -1;
  3614. else
  3615. return +1;
  3616. }
  3617. int rc = child->compare(rowsLeft[leftRow], rowsRight[rightRow]);
  3618. if (rc != 0)
  3619. return rc;
  3620. leftRow++;
  3621. rightRow++;
  3622. }
  3623. }
  3624. else
  3625. {
  3626. //Non LCR dictionaries are not supported.
  3627. throwUnexpected();
  3628. }
  3629. }
  3630. unsigned RtlDictionaryTypeInfo::hash(const byte * self, unsigned inhash) const
  3631. {
  3632. if (isLinkCounted())
  3633. {
  3634. const size32_t count = rtlReadSize32t(self);
  3635. self += sizeof(size32_t);
  3636. const byte * * rows = (const byte * *) self;
  3637. size32_t row = 0;
  3638. for (;;)
  3639. {
  3640. //Dictionaries are compared as datasets => skip until the first non-null entry
  3641. while ((row != count) && !rows[row])
  3642. row++;
  3643. if (row == count)
  3644. break;
  3645. inhash = child->hash(rows[row], inhash);
  3646. row++;
  3647. }
  3648. }
  3649. else
  3650. {
  3651. //Non LCR dictionaries are not supported.
  3652. throwUnexpected();
  3653. }
  3654. return inhash;
  3655. }
  3656. //-------------------------------------------------------------------------------------------------------------------
  3657. size32_t RtlIfBlockTypeInfo::getMinSize() const
  3658. {
  3659. return 0;
  3660. }
  3661. size32_t RtlIfBlockTypeInfo::size(const byte * self, const byte * selfrow) const
  3662. {
  3663. if (getCondition(selfrow))
  3664. return sizeFields(fields, self, selfrow);
  3665. return 0;
  3666. }
  3667. size32_t RtlIfBlockTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  3668. {
  3669. throwUnexpected();
  3670. }
  3671. size32_t RtlIfBlockTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  3672. {
  3673. throwUnexpected();
  3674. }
  3675. size32_t RtlIfBlockTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3676. {
  3677. if (getCondition(selfrow))
  3678. return processFields(fields, self, selfrow, target);
  3679. return 0;
  3680. }
  3681. size32_t RtlIfBlockTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3682. {
  3683. if (getCondition(selfrow))
  3684. return toXMLFields(fields, self, selfrow, target);
  3685. return 0;
  3686. }
  3687. size32_t RtlIfBlockTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  3688. {
  3689. if (getCondition(builder.getSelf()))
  3690. return deserializeFields(fields, builder, in, offset);
  3691. return offset;
  3692. }
  3693. void RtlIfBlockTypeInfo::readAhead(IRowPrefetcherSource & in) const
  3694. {
  3695. if (getCondition(in.querySelf()))
  3696. readAheadFields(fields, in);
  3697. }
  3698. void RtlIfBlockTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  3699. {
  3700. //MORE: Should this fail instead?
  3701. resultLen = 0;
  3702. result = nullptr;
  3703. }
  3704. void RtlIfBlockTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  3705. {
  3706. //MORE: Should this fail instead?
  3707. resultLen = 0;
  3708. result = nullptr;
  3709. }
  3710. __int64 RtlIfBlockTypeInfo::getInt(const void * ptr) const
  3711. {
  3712. //MORE: Should this fail instead?
  3713. return 0;
  3714. }
  3715. int RtlIfBlockTypeInfo::compare(const byte * left, const byte * right) const
  3716. {
  3717. bool includeLeft = getCondition(left);
  3718. bool includeRight = getCondition(right);
  3719. if (includeLeft && includeRight)
  3720. return compareFields(fields, left, right);
  3721. //If the fields are all blank then this isn't actually correct, but that is unlikely to be a problem
  3722. if (includeLeft)
  3723. return +1;
  3724. else if (includeRight)
  3725. return -1;
  3726. else
  3727. return 0;
  3728. }
  3729. unsigned RtlIfBlockTypeInfo::hash(const byte * self, unsigned inhash) const
  3730. {
  3731. bool included = getCondition(self);
  3732. if (included)
  3733. inhash = hashFields(fields, self, inhash);
  3734. return inhash;
  3735. }
  3736. bool RtlComplexIfBlockTypeInfo::getCondition(const RtlRow & selfrow) const
  3737. {
  3738. //Call the function in the derived class that evaluates the test condition
  3739. return getCondition(selfrow.queryRow());
  3740. }
  3741. static CriticalSection ifcs;
  3742. RtlSerialIfBlockTypeInfo::~RtlSerialIfBlockTypeInfo()
  3743. {
  3744. ::Release(filter);
  3745. delete parentRecord;
  3746. }
  3747. void RtlSerialIfBlockTypeInfo::doCleanup() const
  3748. {
  3749. delete parentRecord;
  3750. parentRecord = nullptr;
  3751. ::Release(filter);
  3752. filter = nullptr;
  3753. RtlIfBlockTypeInfo::doCleanup();
  3754. }
  3755. bool RtlSerialIfBlockTypeInfo::getCondition(const byte * selfrow) const
  3756. {
  3757. const IFieldFilter * filter = resolveCondition();
  3758. RtlDynRow row(*parentRecord, nullptr);
  3759. //Can only expand offset for fields up to and including this if block - otherwise it will call getCondition() again...
  3760. row.setRow(selfrow, numPrevFields);
  3761. return filter->matches(row);
  3762. }
  3763. bool RtlSerialIfBlockTypeInfo::getCondition(const RtlRow & selfrow) const
  3764. {
  3765. return resolveCondition()->matches(selfrow);
  3766. }
  3767. const IFieldFilter * RtlSerialIfBlockTypeInfo::queryFilter() const
  3768. {
  3769. return resolveCondition();
  3770. }
  3771. const IFieldFilter * RtlSerialIfBlockTypeInfo::resolveCondition() const
  3772. {
  3773. //The following cast is a hack to avoid <atomic> being included from the header
  3774. //if parentRecord is not initialised then may need to create the filter condition
  3775. typedef std::atomic<RtlRecord *> AtomicRtlRecord;
  3776. AtomicRtlRecord & atomicParentRecord = *reinterpret_cast<AtomicRtlRecord *>(&parentRecord);
  3777. RtlRecord * parent = atomicParentRecord.load(std::memory_order_relaxed);
  3778. if (!parent)
  3779. {
  3780. CriticalBlock block(ifcs);
  3781. parent = atomicParentRecord.load(std::memory_order_relaxed);
  3782. if (!parent)
  3783. {
  3784. if (!filter)
  3785. filter = createCondition();
  3786. parent = new RtlRecord(*rowType, true);
  3787. atomicParentRecord.store(parent, std::memory_order_relaxed);
  3788. numPrevFields = parentRecord->queryIfBlockLimit(this);
  3789. }
  3790. }
  3791. return filter;
  3792. }
  3793. IFieldFilter * RtlDynamicIfBlockTypeInfo::createCondition() const
  3794. {
  3795. //The filter should be initialised on deserialization
  3796. UNIMPLEMENTED;
  3797. }
  3798. //-------------------------------------------------------------------------------------------------------------------
  3799. __int64 RtlBitfieldTypeInfo::signedValue(const void * self) const
  3800. {
  3801. __int64 value = rtlReadInt(self, getBitfieldIntSize());
  3802. unsigned shift = getBitfieldShift();
  3803. unsigned numBits = getBitfieldNumBits();
  3804. unsigned bitsInValue = sizeof(value) * 8;
  3805. value <<= (bitsInValue - shift - numBits);
  3806. return value >> (bitsInValue - numBits);
  3807. }
  3808. unsigned __int64 RtlBitfieldTypeInfo::unsignedValue(const void * self) const
  3809. {
  3810. unsigned __int64 value = rtlReadUInt(self, getBitfieldIntSize());
  3811. unsigned shift = getBitfieldShift();
  3812. unsigned numBits = getBitfieldNumBits();
  3813. unsigned bitsInValue = sizeof(value) * 8;
  3814. value <<= (bitsInValue - shift - numBits);
  3815. return value >> (bitsInValue - numBits);
  3816. }
  3817. size32_t RtlBitfieldTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  3818. {
  3819. builder.ensureCapacity(length+offset, queryName(field));
  3820. byte * cur = builder.getSelf() + offset;
  3821. unsigned __int64 value = rtlReadUInt(builder.getSelf(), getBitfieldIntSize());
  3822. unsigned shift = getBitfieldShift();
  3823. unsigned numBits = getBitfieldNumBits();
  3824. unsigned __int64 mask = (U64C(1) << numBits) - 1;
  3825. value &= ~(mask << shift);
  3826. value |= ((val << shift) & mask);
  3827. rtlWriteInt(cur, val, getBitfieldIntSize());
  3828. return offset + getSize();
  3829. }
  3830. size32_t RtlBitfieldTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  3831. {
  3832. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  3833. }
  3834. size32_t RtlBitfieldTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  3835. {
  3836. size32_t size = rtlUtf8Length(len, value);
  3837. return buildInt(builder, offset, field, rtlStrToInt8(size, value));
  3838. }
  3839. size32_t RtlBitfieldTypeInfo::getMinSize() const
  3840. {
  3841. if (fieldType & RFTMislastbitfield)
  3842. return getBitfieldIntSize();
  3843. return 0;
  3844. }
  3845. size32_t RtlBitfieldTypeInfo::size(const byte * self, const byte * selfrow) const
  3846. {
  3847. if (fieldType & RFTMislastbitfield)
  3848. return getBitfieldIntSize();
  3849. return 0;
  3850. }
  3851. size32_t RtlBitfieldTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3852. {
  3853. if (isUnsigned())
  3854. target.processUInt(unsignedValue(self), field);
  3855. else
  3856. target.processInt(signedValue(self), field);
  3857. return getSize();
  3858. }
  3859. size32_t RtlBitfieldTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3860. {
  3861. size32_t fieldsize = getBitfieldIntSize();
  3862. if (isUnsigned())
  3863. target.outputUInt(unsignedValue(self), fieldsize, queryScalarXPath(field));
  3864. else
  3865. target.outputInt(signedValue(self), fieldsize, queryScalarXPath(field));
  3866. if (fieldType & RFTMislastbitfield)
  3867. return fieldsize;
  3868. return 0;
  3869. }
  3870. void RtlBitfieldTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  3871. {
  3872. if (isUnsigned())
  3873. rtlUInt8ToStrX(resultLen, result, unsignedValue(ptr));
  3874. else
  3875. rtlInt8ToStrX(resultLen, result, signedValue(ptr));
  3876. }
  3877. void RtlBitfieldTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  3878. {
  3879. getString(resultLen, result, ptr);
  3880. }
  3881. __int64 RtlBitfieldTypeInfo::getInt(const void * ptr) const
  3882. {
  3883. if (isUnsigned())
  3884. return (__int64)unsignedValue(ptr);
  3885. else
  3886. return signedValue(ptr);
  3887. }
  3888. int RtlBitfieldTypeInfo::compare(const byte * left, const byte * right) const
  3889. {
  3890. if (isUnsigned())
  3891. {
  3892. unsigned __int64 leftValue = unsignedValue(left);
  3893. unsigned __int64 rightValue = unsignedValue(right);
  3894. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  3895. }
  3896. else
  3897. {
  3898. __int64 leftValue = signedValue(left);
  3899. __int64 rightValue = signedValue(right);
  3900. return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
  3901. }
  3902. }
  3903. unsigned RtlBitfieldTypeInfo::hash(const byte * self, unsigned inhash) const
  3904. {
  3905. __int64 val = getInt(self);
  3906. return rtlHash32Data8(&val, inhash);
  3907. }
  3908. size32_t RtlBitfieldTypeInfo::getSize() const
  3909. {
  3910. if (fieldType & RFTMislastbitfield)
  3911. return getBitfieldIntSize();
  3912. return 0;
  3913. }
  3914. //-------------------------------------------------------------------------------------------------------------------
  3915. size32_t RtlUnimplementedTypeInfo::getMinSize() const
  3916. {
  3917. rtlFailUnexpected();
  3918. }
  3919. size32_t RtlUnimplementedTypeInfo::size(const byte * self, const byte * selfrow) const
  3920. {
  3921. rtlFailUnexpected();
  3922. }
  3923. size32_t RtlUnimplementedTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  3924. {
  3925. rtlFailUnexpected();
  3926. }
  3927. size32_t RtlUnimplementedTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  3928. {
  3929. rtlFailUnexpected();
  3930. }
  3931. size32_t RtlUnimplementedTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3932. {
  3933. rtlFailUnexpected();
  3934. }
  3935. size32_t RtlUnimplementedTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  3936. {
  3937. rtlFailUnexpected();
  3938. }
  3939. size32_t RtlUnimplementedTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  3940. {
  3941. rtlFailUnexpected();
  3942. return offset;
  3943. }
  3944. void RtlUnimplementedTypeInfo::readAhead(IRowPrefetcherSource & in) const
  3945. {
  3946. rtlFailUnexpected();
  3947. }
  3948. void RtlUnimplementedTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  3949. {
  3950. resultLen = 0;
  3951. result = nullptr;
  3952. rtlFailUnexpected();
  3953. }
  3954. void RtlUnimplementedTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  3955. {
  3956. resultLen = 0;
  3957. result = nullptr;
  3958. rtlFailUnexpected();
  3959. }
  3960. __int64 RtlUnimplementedTypeInfo::getInt(const void * ptr) const
  3961. {
  3962. rtlFailUnexpected();
  3963. return 0;
  3964. }
  3965. int RtlUnimplementedTypeInfo::compare(const byte * left, const byte * right) const
  3966. {
  3967. rtlFailUnexpected();
  3968. }
  3969. unsigned RtlUnimplementedTypeInfo::hash(const byte * self, unsigned inhash) const
  3970. {
  3971. rtlFailUnexpected();
  3972. }
  3973. //-------------------------------------------------------------------------------------------------------------------
  3974. size32_t RtlAlienTypeInfo::getMinSize() const
  3975. {
  3976. rtlFailUnexpected();
  3977. }
  3978. size32_t RtlAlienTypeInfo::size(const byte * self, const byte * selfrow) const
  3979. {
  3980. if (isFixedSize())
  3981. return length;
  3982. rtlFailUnexpected();
  3983. }
  3984. size32_t RtlAlienTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
  3985. {
  3986. rtlFailUnexpected();
  3987. }
  3988. size32_t RtlAlienTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
  3989. {
  3990. rtlFailUnexpected();
  3991. }
  3992. size32_t RtlAlienTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
  3993. {
  3994. rtlFailUnexpected();
  3995. }
  3996. size32_t RtlAlienTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  3997. {
  3998. rtlFailUnexpected();
  3999. }
  4000. size32_t RtlAlienTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  4001. {
  4002. rtlFailUnexpected();
  4003. }
  4004. size32_t RtlAlienTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
  4005. {
  4006. if (isFixedSize())
  4007. return RtlCompoundTypeInfo::deserialize(builder, in, offset);
  4008. rtlFailUnexpected();
  4009. }
  4010. void RtlAlienTypeInfo::readAhead(IRowPrefetcherSource & in) const
  4011. {
  4012. if (isFixedSize())
  4013. in.skip(length);
  4014. else
  4015. rtlFailUnexpected();
  4016. }
  4017. void RtlAlienTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
  4018. {
  4019. resultLen = 0;
  4020. result = nullptr;
  4021. rtlFailUnexpected();
  4022. }
  4023. void RtlAlienTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  4024. {
  4025. resultLen = 0;
  4026. result = nullptr;
  4027. rtlFailUnexpected();
  4028. }
  4029. __int64 RtlAlienTypeInfo::getInt(const void * ptr) const
  4030. {
  4031. rtlFailUnexpected();
  4032. return 0;
  4033. }
  4034. int RtlAlienTypeInfo::compare(const byte * left, const byte * right) const
  4035. {
  4036. rtlFailUnexpected();
  4037. }
  4038. unsigned RtlAlienTypeInfo::hash(const byte * self, unsigned inhash) const
  4039. {
  4040. rtlFailUnexpected();
  4041. }
  4042. //-------------------------------------------------------------------------------------------------------------------
  4043. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, unsigned _flags, const char *_initializer)
  4044. : RtlFieldInfo(_name, _xpath, _type, _flags, _initializer)
  4045. {
  4046. }
  4047. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, unsigned _flags)
  4048. : RtlFieldInfo(_name, _xpath, _type, _flags, NULL)
  4049. {
  4050. }
  4051. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type)
  4052. : RtlFieldInfo(_name, _xpath, _type, 0, NULL)
  4053. {
  4054. }
  4055. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, const char *_initializer)
  4056. : RtlFieldInfo(_name, _xpath, _type, 0, _initializer)
  4057. {
  4058. }
  4059. unsigned ECLRTL_API countFields(const RtlFieldInfo * const * fields)
  4060. {
  4061. unsigned cnt = 0;
  4062. for (;*fields;fields++)
  4063. cnt++;
  4064. return cnt;
  4065. }
  4066. //-------------------------------------------------------------------------------------------------------------------
  4067. static const unsigned sameTypeMask = RFTMkind|RFTMebcdic;
  4068. size32_t translateScalar(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, const RtlTypeInfo &destType, const RtlTypeInfo &sourceType, const byte *source)
  4069. {
  4070. switch(destType.getType())
  4071. {
  4072. case type_boolean:
  4073. case type_int:
  4074. case type_swapint:
  4075. case type_packedint:
  4076. case type_filepos:
  4077. case type_keyedint:
  4078. offset = destType.buildInt(builder, offset, field, sourceType.getInt(source));
  4079. break;
  4080. case type_real:
  4081. offset = destType.buildReal(builder, offset, field, sourceType.getReal(source));
  4082. break;
  4083. case type_data:
  4084. case type_string:
  4085. //Special case if source and destination types are identical to avoid cloning strings
  4086. if ((destType.fieldType & sameTypeMask) == (sourceType.fieldType & sameTypeMask))
  4087. {
  4088. size32_t length = sourceType.length;
  4089. if (!sourceType.isFixedSize())
  4090. {
  4091. length = rtlReadSize32t(source);
  4092. source += sizeof(size32_t);
  4093. }
  4094. offset = destType.buildString(builder, offset, field, length, (const char *)source);
  4095. break;
  4096. }
  4097. //fallthrough
  4098. case type_decimal: // Go via string - not common enough to special-case
  4099. case type_varstring:
  4100. case type_qstring:
  4101. {
  4102. size32_t size;
  4103. rtlDataAttr text;
  4104. sourceType.getString(size, text.refstr(), source);
  4105. offset = destType.buildString(builder, offset, field, size, text.getstr());
  4106. break;
  4107. }
  4108. case type_utf8:
  4109. //MORE: Could special case casting from utf8 to utf8 similar to strings above
  4110. case type_unicode:
  4111. case type_varunicode:
  4112. {
  4113. size32_t utf8chars;
  4114. rtlDataAttr utf8Text;
  4115. sourceType.getUtf8(utf8chars, utf8Text.refstr(), source);
  4116. offset = destType.buildUtf8(builder, offset, field, utf8chars, utf8Text.getstr());
  4117. break;
  4118. }
  4119. case type_set:
  4120. {
  4121. bool isAll = *(bool *) source;
  4122. source+= sizeof(bool);
  4123. byte *dest = builder.ensureCapacity(offset+sizeof(bool)+sizeof(size32_t), field->name)+offset;
  4124. *(size32_t *) (dest + sizeof(bool)) = 0; // Patch later when size known
  4125. offset += sizeof(bool) + sizeof(size32_t);
  4126. if (isAll)
  4127. {
  4128. *(bool*) dest = true;
  4129. }
  4130. else
  4131. {
  4132. *(bool*) dest = false;
  4133. size32_t sizeOffset = offset - sizeof(size32_t); // Where we need to patch
  4134. size32_t childSize = *(size32_t *)source;
  4135. source += sizeof(size32_t);
  4136. const byte *initialSource = source;
  4137. size32_t initialOffset = offset;
  4138. const RtlTypeInfo *destChildType = destType.queryChildType();
  4139. const RtlTypeInfo *sourceChildType = sourceType.queryChildType();
  4140. while ((size_t)(source - initialSource) < childSize)
  4141. {
  4142. offset = translateScalar(builder, offset, field, *destChildType, *sourceChildType, source);
  4143. source += sourceChildType->size(source, nullptr); // MORE - shame to repeat a calculation that the translate above almost certainly just did
  4144. }
  4145. dest = builder.getSelf() + sizeOffset; // Note - man have been moved by reallocs since last calculated
  4146. *(size32_t *)dest = offset - initialOffset;
  4147. }
  4148. break;
  4149. }
  4150. default:
  4151. throwUnexpected();
  4152. }
  4153. return offset;
  4154. }
  4155. //-------------------------------------------------------------------------------------------------------------------
  4156. /*
  4157. Stack:
  4158. * Change hqlhtcpp so that the correct derived classes are generated.
  4159. * Test so that toXML calls the default implementaions and check that the same values are generated. (Don't if contains ifblocks/alien)
  4160. * Release
  4161. * Think about bitfields - how do I know it is the last bitfield, how am I going to keep track of the offsets.
  4162. * What code would need to be generated for alien datatypes.
  4163. * Could have alien int and alien string varieties????
  4164. * What would an ecl interpreter look like (a special workunit?) helpers are interpreted? What about the graph?
  4165. * Could I add associations to register user attributes - so a callback could know when they were assigned to?
  4166. * Could I add ctx->noteLocation() into the generated code - so could put breakpoints on variables.
  4167. * Add annotation when a member of the target dataset is updated.
  4168. ctx->noteFieldAssigned(self, <field>); - does this include temporary datasets?
  4169. ctx->noteAttributeX(<name>, Int|String|Unicode|
  4170. ctx->noteLocation(location); - reduce locations, so only one returned per line for a non-dataset? Should it just be the first item on the line that is tagged??
  4171. * Need static information about the breakpoints so debugger knows where to put valid brakpoints....
  4172. * Debugger will want to know about the type of the breakpoints.
  4173. * Should try and compress the location format - possibly have a table of <module.attributes>-># with breakpoint as 12:23
  4174. Also need some information about which datasets, and stored variables etc. are used so they can be displayed.
  4175. - Most datasets can be deduced from the parameters passed into the transform
  4176. - Some are trickier e.g., the extract, could possibly define some mappings
  4177. - options to disable projects/other more complex operations inline (so easier to walk through)
  4178. Bitfields:
  4179. - Two separate questions:
  4180. i) How is the meta information generated.
  4181. ii) How is it stored internally in an IHqlExpression * ?
  4182. * Could store the offset in the type - either in the base type of as a qualifier.
  4183. + much easier code generation.
  4184. - Doesn't provie an easy indication of the last field in a bitfield (because can't really modify after the fact)
  4185. - Problematic when fields are removed to merge them.
  4186. * Could add a bitfield container to the record.
  4187. + Makes it easier to handle the last bitfield
  4188. + Matches the structure used for the cursor.
  4189. - Everything needs to walk the bitfield containers similar to ifblocks.
  4190. - Makes it just as tricky to merge
  4191. - Harder to create the record, unless the code is implicitly handled by appendOperand().
  4192. * The type of no_select could contain a modifier to indicate the offset/islast
  4193. + the type of a no_select would have a 1:1 mapping with type info.
  4194. - A bit complicated to calculate, especially when it isn't used much of the time
  4195. => On Reflection is is probably easiest to keep the structure as it is (some comments should go in hqlexpr to avoid revisiting).
  4196. * interperet bitfield offsets and "is last bitfield" dynamically
  4197. + Greatly simplifies generating the meta - you can always use the field.
  4198. - Requires another parameter and significant extra complexity for the uncommon case. (especially incrementing self)
  4199. * Could generate from the expanded record instead of walking the record structure directly
  4200. + That already knows how the bitfields are allocated, and could easily know which is the last field.
  4201. - A field is no longer sufficient as key fr searching for the information.
  4202. - Best would be a createFieldTypeKey(select-expr) which returns field when approriate, or modified if a bitfield. Then the pain is localised.
  4203. * Output a bitfield container item into the type information
  4204. + Solves the size problem
  4205. - Individual bitfields still need to know their offsets, so doesn't solve the full problem.
  4206. =>
  4207. Change so that either use meta to generate the information, or use no_select when appropriate to fidn out the nesc. information.
  4208. Probably the latter for the moment.
  4209. a) Create a key function and make sure it is always used.
  4210. b) Need to work out how to generate no_ifblock.
  4211. - ifblock is context dependent, so need to generate as part of the parent record, and in the parent record context.
  4212. */