rtlfield.cpp 134 KB

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