rtlfield.cpp 137 KB

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