rtlfield.cpp 129 KB

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