rtlfield.cpp 121 KB

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