rtlfield.cpp 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983
  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. //-------------------------------------------------------------------------------------------------------------------
  56. class DummyFieldProcessor : public CInterfaceOf<IFieldProcessor>
  57. {
  58. public:
  59. virtual void processString(unsigned len, const char *value, const RtlFieldInfo * field) {}
  60. virtual void processBool(bool value, const RtlFieldInfo * field) {}
  61. virtual void processData(unsigned len, const void *value, const RtlFieldInfo * field) {}
  62. virtual void processInt(__int64 value, const RtlFieldInfo * field) {}
  63. virtual void processUInt(unsigned __int64 value, const RtlFieldInfo * field) {}
  64. virtual void processReal(double value, const RtlFieldInfo * field) {}
  65. virtual void processDecimal(const void *value, unsigned digits, unsigned precision, const RtlFieldInfo * field) {}
  66. virtual void processUDecimal(const void *value, unsigned digits, unsigned precision, const RtlFieldInfo * field) {}
  67. virtual void processUnicode(unsigned len, const UChar *value, const RtlFieldInfo * field) {}
  68. virtual void processQString(unsigned len, const char *value, const RtlFieldInfo * field) {}
  69. virtual void processUtf8(unsigned len, const char *value, const RtlFieldInfo * field) {}
  70. virtual bool processBeginSet(const RtlFieldInfo * field, unsigned numElements, bool isAll, const byte *data) { return false; }
  71. virtual bool processBeginDataset(const RtlFieldInfo * field, unsigned numRows) { return true; }
  72. virtual bool processBeginRow(const RtlFieldInfo * field) { return true; }
  73. virtual void processEndSet(const RtlFieldInfo * field) {}
  74. virtual void processEndDataset(const RtlFieldInfo * field) {}
  75. virtual void processEndRow(const RtlFieldInfo * field) {}
  76. };
  77. //-------------------------------------------------------------------------------------------------------------------
  78. size32_t ECLRTL_API getMinSize(const RtlFieldInfo * const * fields)
  79. {
  80. size32_t minSize = 0;
  81. for(;;)
  82. {
  83. const RtlFieldInfo * cur = *fields;
  84. if (!cur)
  85. return minSize;
  86. minSize += cur->type->getMinSize();
  87. fields++;
  88. }
  89. }
  90. //-------------------------------------------------------------------------------------------------------------------
  91. size32_t RtlTypeInfoBase::getMinSize() const
  92. {
  93. return length;
  94. }
  95. size32_t RtlTypeInfoBase::size(const byte * self, const byte * selfrow) const
  96. {
  97. return length;
  98. }
  99. size32_t RtlTypeInfoBase::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  100. {
  101. rtlFailUnexpected();
  102. return 0;
  103. }
  104. size32_t RtlTypeInfoBase::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & out) const
  105. {
  106. rtlFailUnexpected();
  107. return 0;
  108. }
  109. size32_t RtlTypeInfoBase::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  110. {
  111. rtlFailUnexpected();
  112. return 0;
  113. }
  114. const char * RtlTypeInfoBase::queryLocale() const
  115. {
  116. return NULL;
  117. }
  118. const RtlFieldInfo * const * RtlTypeInfoBase::queryFields() const
  119. {
  120. return NULL;
  121. }
  122. const RtlTypeInfo * RtlTypeInfoBase::queryChildType() const
  123. {
  124. return NULL;
  125. }
  126. //-------------------------------------------------------------------------------------------------------------------
  127. size32_t RtlBoolTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  128. {
  129. builder.ensureCapacity(sizeof(bool)+offset, field->name);
  130. bool val = source.getBooleanResult(field);
  131. * (bool *) (builder.getSelf() + offset) = val;
  132. offset += sizeof(bool);
  133. return offset;
  134. }
  135. size32_t RtlBoolTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  136. {
  137. target.processBool(*(const bool *)self, field);
  138. return sizeof(bool);
  139. }
  140. size32_t RtlBoolTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  141. {
  142. target.outputBool(*(const bool *)self, queryScalarXPath(field));
  143. return sizeof(bool);
  144. }
  145. void RtlBoolTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  146. {
  147. const bool * cast = static_cast<const bool *>(ptr);
  148. rtlBoolToStrX(resultLen, result, *cast);
  149. }
  150. __int64 RtlBoolTypeInfo::getInt(const void * ptr) const
  151. {
  152. const bool * cast = static_cast<const bool *>(ptr);
  153. return (__int64)*cast;
  154. }
  155. //-------------------------------------------------------------------------------------------------------------------
  156. double RtlRealTypeInfo::value(const void * self) const
  157. {
  158. if (length == 4)
  159. return *(const float *)self;
  160. return *(const double *)self;
  161. }
  162. size32_t RtlRealTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  163. {
  164. builder.ensureCapacity(length+offset, field->name);
  165. double val = source.getRealResult(field);
  166. byte *dest = builder.getSelf() + offset;
  167. if (length == 4)
  168. *(float *) dest = (float) val;
  169. else
  170. *(double *) dest = val;
  171. offset += length;
  172. return offset;
  173. }
  174. size32_t RtlRealTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  175. {
  176. target.processReal(value(self), field);
  177. return length;
  178. }
  179. size32_t RtlRealTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  180. {
  181. target.outputReal(value(self), queryScalarXPath(field));
  182. return length;
  183. }
  184. void RtlRealTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  185. {
  186. double num = value(ptr);
  187. rtlRealToStrX(resultLen, result, num);
  188. }
  189. __int64 RtlRealTypeInfo::getInt(const void * ptr) const
  190. {
  191. double num = value(ptr);
  192. return (__int64)num;
  193. }
  194. //-------------------------------------------------------------------------------------------------------------------
  195. size32_t RtlIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  196. {
  197. builder.ensureCapacity(length+offset, field->name);
  198. __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  199. rtlWriteInt(builder.getSelf() + offset, val, length);
  200. offset += length;
  201. return offset;
  202. }
  203. size32_t RtlIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  204. {
  205. if (isUnsigned())
  206. target.processUInt(rtlReadUInt(self, length), field);
  207. else
  208. target.processInt(rtlReadInt(self, length), field);
  209. return length;
  210. }
  211. size32_t RtlIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  212. {
  213. if (isUnsigned())
  214. target.outputUInt(rtlReadUInt(self, length), length, queryScalarXPath(field));
  215. else
  216. target.outputInt(rtlReadInt(self, length), length, queryScalarXPath(field));
  217. return length;
  218. }
  219. void RtlIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  220. {
  221. if (isUnsigned())
  222. rtlUInt8ToStrX(resultLen, result, rtlReadUInt(ptr, length));
  223. else
  224. rtlInt8ToStrX(resultLen, result, rtlReadInt(ptr, length));
  225. }
  226. __int64 RtlIntTypeInfo::getInt(const void * ptr) const
  227. {
  228. if (isUnsigned())
  229. return rtlReadUInt(ptr, length);
  230. else
  231. return rtlReadInt(ptr, length);
  232. }
  233. //-------------------------------------------------------------------------------------------------------------------
  234. size32_t RtlSwapIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  235. {
  236. builder.ensureCapacity(length+offset, field->name);
  237. __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  238. // 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
  239. rtlWriteSwapInt(builder.getSelf() + offset, val, length);
  240. offset += length;
  241. return offset;
  242. }
  243. size32_t RtlSwapIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  244. {
  245. if (isUnsigned())
  246. target.processUInt(rtlReadSwapUInt(self, length), field);
  247. else
  248. target.processInt(rtlReadSwapInt(self, length), field);
  249. return length;
  250. }
  251. size32_t RtlSwapIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  252. {
  253. if (isUnsigned())
  254. target.outputUInt(rtlReadSwapUInt(self, length), length, queryScalarXPath(field));
  255. else
  256. target.outputInt(rtlReadSwapInt(self, length), length, queryScalarXPath(field));
  257. return length;
  258. }
  259. void RtlSwapIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  260. {
  261. if (isUnsigned())
  262. rtlUInt8ToStrX(resultLen, result, rtlReadSwapUInt(ptr, length));
  263. else
  264. rtlInt8ToStrX(resultLen, result, rtlReadSwapInt(ptr, length));
  265. }
  266. __int64 RtlSwapIntTypeInfo::getInt(const void * ptr) const
  267. {
  268. if (isUnsigned())
  269. return rtlReadUInt(ptr, length);
  270. else
  271. return rtlReadInt(ptr, length);
  272. }
  273. //-------------------------------------------------------------------------------------------------------------------
  274. size32_t RtlPackedIntTypeInfo::getMinSize() const
  275. {
  276. return 1;
  277. }
  278. size32_t RtlPackedIntTypeInfo::size(const byte * self, const byte * selfrow) const
  279. {
  280. return rtlGetPackedSize(self);
  281. }
  282. size32_t RtlPackedIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  283. {
  284. unsigned __int64 value = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
  285. size32_t sizeInBytes = rtlGetPackedSize(&value);
  286. builder.ensureCapacity(sizeInBytes+offset, field->name);
  287. rtlSetPackedUnsigned(builder.getSelf() + offset, value);
  288. offset += sizeInBytes;
  289. return offset;
  290. }
  291. size32_t RtlPackedIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  292. {
  293. if (isUnsigned())
  294. target.processUInt(rtlGetPackedUnsigned(self), field);
  295. else
  296. target.processInt(rtlGetPackedSigned(self), field);
  297. return rtlGetPackedSize(self);
  298. }
  299. size32_t RtlPackedIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  300. {
  301. size32_t fieldsize = rtlGetPackedSize(self);
  302. if (isUnsigned())
  303. target.outputUInt(rtlGetPackedUnsigned(self), fieldsize, queryScalarXPath(field));
  304. else
  305. target.outputInt(rtlGetPackedSigned(self), fieldsize, queryScalarXPath(field));
  306. return fieldsize;
  307. }
  308. void RtlPackedIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  309. {
  310. if (isUnsigned())
  311. rtlUInt8ToStrX(resultLen, result, rtlGetPackedUnsigned(ptr));
  312. else
  313. rtlInt8ToStrX(resultLen, result, rtlGetPackedSigned(ptr));
  314. }
  315. __int64 RtlPackedIntTypeInfo::getInt(const void * ptr) const
  316. {
  317. if (isUnsigned())
  318. return rtlGetPackedUnsigned(ptr);
  319. else
  320. return rtlGetPackedSigned(ptr);
  321. }
  322. //-------------------------------------------------------------------------------------------------------------------
  323. size32_t RtlStringTypeInfo::getMinSize() const
  324. {
  325. if (isFixedSize())
  326. return length;
  327. return sizeof(size32_t);
  328. }
  329. size32_t RtlStringTypeInfo::size(const byte * self, const byte * selfrow) const
  330. {
  331. if (isFixedSize())
  332. return length;
  333. return sizeof(size32_t) + rtlReadUInt4(self);
  334. }
  335. size32_t RtlStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  336. {
  337. size32_t size;
  338. char *value;
  339. source.getStringResult(field, size, value);
  340. if (!isFixedSize())
  341. {
  342. builder.ensureCapacity(offset+size+sizeof(size32_t), field->name);
  343. byte *dest = builder.getSelf()+offset;
  344. rtlWriteInt4(dest, size);
  345. // 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
  346. // In order to be symmetrical with the passing of ecl data to a IFieldProcessor the former interpretation is preferred.
  347. // Expecting source.getStringResult to somehow "know" that EBCDIC was expected seems odd.
  348. if (isEbcdic())
  349. rtlStrToEStr(size, (char *) dest+sizeof(size32_t), size, (char *)value);
  350. else
  351. memcpy(dest+sizeof(size32_t), value, size);
  352. offset += size+sizeof(size32_t);
  353. }
  354. else
  355. {
  356. builder.ensureCapacity(offset+length, field->name);
  357. byte *dest = builder.getSelf()+offset;
  358. if (isEbcdic())
  359. rtlStrToEStr(length, (char *) dest, size, (char *) value);
  360. else
  361. rtlStrToStr(length, dest, size, value);
  362. offset += length;
  363. }
  364. rtlFree(value);
  365. return offset;
  366. }
  367. size32_t RtlStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  368. {
  369. const char * str = reinterpret_cast<const char *>(self);
  370. unsigned thisLength;
  371. unsigned thisSize;
  372. if (isFixedSize())
  373. {
  374. thisLength = length;
  375. thisSize = thisLength;
  376. }
  377. else
  378. {
  379. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  380. thisLength = rtlReadUInt4(self);
  381. thisSize = sizeof(size32_t) + thisLength;
  382. }
  383. if (isEbcdic())
  384. {
  385. unsigned lenAscii;
  386. rtlDataAttr ascii;
  387. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  388. target.processString(lenAscii, ascii.getstr(), field);
  389. }
  390. else
  391. {
  392. target.processString(thisLength, str, field);
  393. }
  394. return thisSize;
  395. }
  396. size32_t RtlStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  397. {
  398. const char * str = reinterpret_cast<const char *>(self);
  399. unsigned thisLength;
  400. unsigned thisSize;
  401. if (isFixedSize())
  402. {
  403. thisLength = length;
  404. thisSize = thisLength;
  405. }
  406. else
  407. {
  408. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  409. thisLength = rtlReadUInt4(self);
  410. thisSize = sizeof(size32_t) + thisLength;
  411. }
  412. if (isEbcdic())
  413. {
  414. unsigned lenAscii;
  415. rtlDataAttr ascii;
  416. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  417. target.outputString(lenAscii, ascii.getstr(), queryScalarXPath(field));
  418. }
  419. else
  420. {
  421. target.outputString(thisLength, str, queryScalarXPath(field));
  422. }
  423. return thisSize;
  424. }
  425. void RtlStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  426. {
  427. if (isFixedSize())
  428. {
  429. return rtlStrToUtf8X(resultLen, result, length, (const char *)ptr);
  430. }
  431. else
  432. {
  433. size32_t len = rtlReadUInt4(ptr);
  434. return rtlStrToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  435. }
  436. }
  437. __int64 RtlStringTypeInfo::getInt(const void * ptr) const
  438. {
  439. //Utf8 output is the same as string output, so avoid the intermediate translation
  440. if (isFixedSize())
  441. return rtlStrToInt8(length, (const char *)ptr);
  442. size32_t len = rtlReadUInt4(ptr);
  443. return rtlStrToInt8(len, (const char *)ptr + sizeof(size32_t));
  444. }
  445. //-------------------------------------------------------------------------------------------------------------------
  446. size32_t RtlDataTypeInfo::getMinSize() const
  447. {
  448. if (isFixedSize())
  449. return length;
  450. return sizeof(size32_t);
  451. }
  452. size32_t RtlDataTypeInfo::size(const byte * self, const byte * selfrow) const
  453. {
  454. if (isFixedSize())
  455. return length;
  456. return sizeof(size32_t) + rtlReadUInt4(self);
  457. }
  458. size32_t RtlDataTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  459. {
  460. size32_t size;
  461. void *value;
  462. source.getDataResult(field, size, value);
  463. if (!isFixedSize())
  464. {
  465. builder.ensureCapacity(offset+size+sizeof(size32_t), field->name);
  466. byte *dest = builder.getSelf()+offset;
  467. rtlWriteInt4(dest, size);
  468. memcpy(dest+sizeof(size32_t), value, size);
  469. offset += size+sizeof(size32_t);
  470. }
  471. else
  472. {
  473. builder.ensureCapacity(offset+length, field->name);
  474. byte *dest = builder.getSelf()+offset;
  475. rtlDataToData(length, dest, size, value);
  476. offset += length;
  477. }
  478. rtlFree(value);
  479. return offset;
  480. }
  481. size32_t RtlDataTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  482. {
  483. const char * str = reinterpret_cast<const char *>(self);
  484. unsigned thisLength;
  485. unsigned thisSize;
  486. if (isFixedSize())
  487. {
  488. thisLength = length;
  489. thisSize = thisLength;
  490. }
  491. else
  492. {
  493. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  494. thisLength = rtlReadUInt4(self);
  495. thisSize = sizeof(size32_t) + thisLength;
  496. }
  497. target.processData(thisLength, str, field);
  498. return thisSize;
  499. }
  500. size32_t RtlDataTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  501. {
  502. const char * str = reinterpret_cast<const char *>(self);
  503. unsigned thisLength;
  504. unsigned thisSize;
  505. if (isFixedSize())
  506. {
  507. thisLength = length;
  508. thisSize = thisLength;
  509. }
  510. else
  511. {
  512. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  513. thisLength = rtlReadUInt4(self);
  514. thisSize = sizeof(size32_t) + thisLength;
  515. }
  516. target.outputData(thisLength, str, queryScalarXPath(field));
  517. return thisSize;
  518. }
  519. void RtlDataTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  520. {
  521. if (isFixedSize())
  522. {
  523. return rtlStrToUtf8X(resultLen, result, length, (const char *)ptr);
  524. }
  525. else
  526. {
  527. size32_t len = rtlReadUInt4(ptr);
  528. return rtlStrToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  529. }
  530. }
  531. __int64 RtlDataTypeInfo::getInt(const void * ptr) const
  532. {
  533. //Utf8 output is the same as string output, so avoid the intermediate translation
  534. if (isFixedSize())
  535. return rtlStrToInt8(length, (const char *)ptr);
  536. size32_t len = rtlReadUInt4(ptr);
  537. return rtlStrToInt8(len, (const char *)ptr + sizeof(size32_t));
  538. }
  539. //-------------------------------------------------------------------------------------------------------------------
  540. size32_t RtlVarStringTypeInfo::getMinSize() const
  541. {
  542. if (isFixedSize())
  543. return length;
  544. return 1;
  545. }
  546. size32_t RtlVarStringTypeInfo::size(const byte * self, const byte * selfrow) const
  547. {
  548. if (isFixedSize())
  549. return length + 1;
  550. const char * str = reinterpret_cast<const char *>(self);
  551. return (size32_t)strlen(str)+1;
  552. }
  553. size32_t RtlVarStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  554. {
  555. size32_t size;
  556. char *value;
  557. source.getStringResult(field, size, value);
  558. if (!isFixedSize())
  559. {
  560. builder.ensureCapacity(offset+size+1, field->name);
  561. // See notes re EBCDIC conversion in RtlStringTypeInfo code
  562. byte *dest = builder.getSelf()+offset;
  563. memcpy(dest, value, size);
  564. dest[size] = '\0';
  565. offset += size+1;
  566. }
  567. else
  568. {
  569. builder.ensureCapacity(offset+length, field->name);
  570. byte *dest = builder.getSelf()+offset;
  571. rtlStrToVStr(length, dest, size, value);
  572. offset += length;
  573. }
  574. rtlFree(value);
  575. return offset;
  576. }
  577. size32_t RtlVarStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  578. {
  579. const char * str = reinterpret_cast<const char *>(self);
  580. unsigned thisLength = (size32_t)strlen(str);
  581. unsigned thisSize;
  582. if (isFixedSize())
  583. thisSize = length+1;
  584. else
  585. thisSize = thisLength+1;
  586. if (isEbcdic())
  587. {
  588. unsigned lenAscii;
  589. rtlDataAttr ascii;
  590. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  591. target.processString(lenAscii, ascii.getstr(), field);
  592. }
  593. else
  594. target.processString(thisLength, str, field);
  595. return thisSize;
  596. }
  597. size32_t RtlVarStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  598. {
  599. const char * str = reinterpret_cast<const char *>(self);
  600. unsigned thisLength = (size32_t)strlen(str);
  601. unsigned thisSize;
  602. if (isFixedSize())
  603. thisSize = length+1;
  604. else
  605. thisSize = thisLength+1;
  606. if (isEbcdic())
  607. {
  608. unsigned lenAscii;
  609. rtlDataAttr ascii;
  610. rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
  611. target.outputString(lenAscii, ascii.getstr(), queryScalarXPath(field));
  612. }
  613. else
  614. target.outputString(thisLength, str, queryScalarXPath(field));
  615. return thisSize;
  616. }
  617. void RtlVarStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  618. {
  619. const char * str = (const char *)ptr;
  620. return rtlStrToUtf8X(resultLen, result, strlen(str), str);
  621. }
  622. __int64 RtlVarStringTypeInfo::getInt(const void * ptr) const
  623. {
  624. const char * str = (const char *)ptr;
  625. return rtlVStrToInt8(str);
  626. }
  627. //-------------------------------------------------------------------------------------------------------------------
  628. size32_t RtlQStringTypeInfo::getMinSize() const
  629. {
  630. if (isFixedSize())
  631. return rtlQStrSize(length);
  632. return sizeof(size32_t);
  633. }
  634. size32_t RtlQStringTypeInfo::size(const byte * self, const byte * selfrow) const
  635. {
  636. if (isFixedSize())
  637. return rtlQStrSize(length);
  638. return sizeof(size32_t) + rtlQStrSize(rtlReadUInt4(self));
  639. }
  640. size32_t RtlQStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  641. {
  642. size32_t size;
  643. char *value;
  644. source.getStringResult(field, size, value);
  645. if (!isFixedSize())
  646. {
  647. size32_t sizeInBytes = rtlQStrSize(size) + sizeof(size32_t);
  648. builder.ensureCapacity(offset+sizeInBytes, field->name);
  649. byte *dest = builder.getSelf()+offset;
  650. rtlWriteInt4(dest, size);
  651. rtlStrToQStr(size, (char *) dest+sizeof(size32_t), size, value);
  652. offset += sizeInBytes;
  653. }
  654. else
  655. {
  656. size32_t sizeInBytes = rtlQStrSize(length);
  657. builder.ensureCapacity(offset+sizeInBytes, field->name);
  658. byte *dest = builder.getSelf()+offset;
  659. rtlStrToQStr(length, (char *) dest, size, value);
  660. offset += sizeInBytes;
  661. }
  662. rtlFree(value);
  663. return offset;
  664. }
  665. size32_t RtlQStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  666. {
  667. const char * str = reinterpret_cast<const char *>(self);
  668. unsigned thisLength;
  669. unsigned thisSize;
  670. if (isFixedSize())
  671. {
  672. thisLength = length;
  673. thisSize = rtlQStrSize(thisLength);
  674. }
  675. else
  676. {
  677. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  678. thisLength = rtlReadUInt4(self);
  679. thisSize = sizeof(size32_t) + rtlQStrSize(thisLength);
  680. }
  681. target.processQString(thisLength, str, field);
  682. return thisSize;
  683. }
  684. size32_t RtlQStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  685. {
  686. const char * str = reinterpret_cast<const char *>(self);
  687. unsigned thisLength;
  688. unsigned thisSize;
  689. if (isFixedSize())
  690. {
  691. thisLength = length;
  692. thisSize = rtlQStrSize(thisLength);
  693. }
  694. else
  695. {
  696. str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  697. thisLength = rtlReadUInt4(self);
  698. thisSize = sizeof(size32_t) + rtlQStrSize(thisLength);
  699. }
  700. target.outputQString(thisLength, str, queryScalarXPath(field));
  701. return thisSize;
  702. }
  703. void RtlQStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  704. {
  705. //NOTE: QStrings cannot contain non-string characters, so converting to str is the same as utf8
  706. if (isFixedSize())
  707. {
  708. return rtlQStrToStrX(resultLen, result, length, (const char *)ptr);
  709. }
  710. else
  711. {
  712. size32_t len = rtlReadUInt4(ptr);
  713. return rtlQStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  714. }
  715. }
  716. __int64 RtlQStringTypeInfo::getInt(const void * ptr) const
  717. {
  718. size32_t lenTemp;
  719. rtlDataAttr temp;
  720. getUtf8(lenTemp, temp.refstr(), ptr);
  721. return rtlStrToInt8(lenTemp, temp.getstr());
  722. }
  723. //-------------------------------------------------------------------------------------------------------------------
  724. size32_t RtlDecimalTypeInfo::calcSize() const
  725. {
  726. if (isUnsigned())
  727. return (getDecimalDigits()+1)/2;
  728. return (getDecimalDigits()+2)/2;
  729. }
  730. size32_t RtlDecimalTypeInfo::getMinSize() const
  731. {
  732. return calcSize();
  733. }
  734. size32_t RtlDecimalTypeInfo::size(const byte * self, const byte * selfrow) const
  735. {
  736. return calcSize();
  737. }
  738. size32_t RtlDecimalTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  739. {
  740. Decimal value;
  741. source.getDecimalResult(field, value);
  742. size32_t sizeInBytes = calcSize();
  743. builder.ensureCapacity(sizeInBytes+offset, field->name);
  744. if (isUnsigned())
  745. value.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  746. else
  747. value.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
  748. offset += sizeInBytes;
  749. return offset;
  750. }
  751. size32_t RtlDecimalTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  752. {
  753. size32_t thisSize = calcSize();
  754. if (isUnsigned())
  755. target.processUDecimal(self, thisSize, getDecimalPrecision(), field);
  756. else
  757. target.processDecimal(self, thisSize, getDecimalPrecision(), field);
  758. return thisSize;
  759. }
  760. size32_t RtlDecimalTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  761. {
  762. size32_t thisSize = calcSize();
  763. if (isUnsigned())
  764. target.outputUDecimal(self, thisSize, getDecimalPrecision(), queryScalarXPath(field));
  765. else
  766. target.outputDecimal(self, thisSize, getDecimalPrecision(), queryScalarXPath(field));
  767. return thisSize;
  768. }
  769. void RtlDecimalTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  770. {
  771. Decimal temp;
  772. if (isUnsigned())
  773. temp.setDecimal(length, getDecimalPrecision(), ptr);
  774. else
  775. temp.setUDecimal(length, getDecimalPrecision(), ptr);
  776. temp.getStringX(resultLen, result);
  777. }
  778. __int64 RtlDecimalTypeInfo::getInt(const void * ptr) const
  779. {
  780. Decimal temp;
  781. if (isUnsigned())
  782. temp.setDecimal(length, getDecimalPrecision(), ptr);
  783. else
  784. temp.setUDecimal(length, getDecimalPrecision(), ptr);
  785. return temp.getInt64();
  786. }
  787. //-------------------------------------------------------------------------------------------------------------------
  788. size32_t RtlCharTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  789. {
  790. throwUnexpected(); // Can't have a field of type char
  791. }
  792. size32_t RtlCharTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  793. {
  794. const char * str = reinterpret_cast<const char *>(self);
  795. char c;
  796. if (isEbcdic())
  797. rtlEStrToStr(1, &c, 1, str);
  798. else
  799. c = *str;
  800. target.processString(1, &c, field);
  801. return 1;
  802. }
  803. size32_t RtlCharTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  804. {
  805. const char * str = reinterpret_cast<const char *>(self);
  806. char c;
  807. if (isEbcdic())
  808. rtlEStrToStr(1, &c, 1, str);
  809. else
  810. c = *str;
  811. target.outputString(1, &c, queryScalarXPath(field));
  812. return 1;
  813. }
  814. void RtlCharTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  815. {
  816. const char * str = (const char *)ptr;
  817. return rtlStrToUtf8X(resultLen, result, 1, str);
  818. }
  819. __int64 RtlCharTypeInfo::getInt(const void * ptr) const
  820. {
  821. const char * str = (const char *)ptr;
  822. return rtlStrToInt8(1, str);
  823. }
  824. //-------------------------------------------------------------------------------------------------------------------
  825. size32_t RtlUnicodeTypeInfo::getMinSize() const
  826. {
  827. if (isFixedSize())
  828. return length * sizeof(UChar);
  829. return sizeof(size32_t);
  830. }
  831. size32_t RtlUnicodeTypeInfo::size(const byte * self, const byte * selfrow) const
  832. {
  833. if (isFixedSize())
  834. return length * sizeof(UChar);
  835. return sizeof(size32_t) + rtlReadUInt4(self) * sizeof(UChar);
  836. }
  837. size32_t RtlUnicodeTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  838. {
  839. size32_t sizeInChars;
  840. UChar *value;
  841. source.getUnicodeResult(field, sizeInChars, value);
  842. if (!isFixedSize())
  843. {
  844. size32_t sizeInBytes = sizeInChars * sizeof(UChar);
  845. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), field->name);
  846. byte *dest = builder.getSelf()+offset;
  847. rtlWriteInt4(dest, sizeInChars); // NOTE - in chars!
  848. memcpy(dest+sizeof(size32_t), value, sizeInBytes);
  849. offset += sizeInBytes+sizeof(size32_t);
  850. }
  851. else
  852. {
  853. size32_t sizeInBytes = length * sizeof(UChar);
  854. builder.ensureCapacity(offset+sizeInBytes, field->name);
  855. byte *dest = builder.getSelf()+offset;
  856. rtlUnicodeToUnicode(length, (UChar *) dest, sizeInChars, value);
  857. offset += sizeInBytes;
  858. }
  859. rtlFree(value);
  860. return offset;
  861. }
  862. size32_t RtlUnicodeTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  863. {
  864. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  865. unsigned thisLength;
  866. unsigned thisSize;
  867. if (isFixedSize())
  868. {
  869. thisLength = length;
  870. thisSize = thisLength * sizeof(UChar);
  871. }
  872. else
  873. {
  874. ustr = reinterpret_cast<const UChar *>(self + sizeof(size32_t));
  875. thisLength = rtlReadUInt4(self);
  876. thisSize = sizeof(size32_t) + thisLength * sizeof(UChar);
  877. }
  878. target.processUnicode(thisLength, ustr, field);
  879. return thisSize;
  880. }
  881. size32_t RtlUnicodeTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  882. {
  883. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  884. unsigned thisLength;
  885. unsigned thisSize;
  886. if (isFixedSize())
  887. {
  888. thisLength = length;
  889. thisSize = thisLength * sizeof(UChar);
  890. }
  891. else
  892. {
  893. ustr = reinterpret_cast<const UChar *>(self + sizeof(size32_t));
  894. thisLength = rtlReadUInt4(self);
  895. thisSize = sizeof(size32_t) + thisLength * sizeof(UChar);
  896. }
  897. target.outputUnicode(thisLength, ustr, queryScalarXPath(field));
  898. return thisSize;
  899. }
  900. void RtlUnicodeTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  901. {
  902. if (isFixedSize())
  903. {
  904. return rtlUnicodeToUtf8X(resultLen, result, length, (const UChar *)ptr);
  905. }
  906. else
  907. {
  908. size32_t len = rtlReadUInt4(ptr);
  909. const char * str = (const char *)ptr + sizeof(size32_t);
  910. return rtlUnicodeToUtf8X(resultLen, result, len, (const UChar *)str);
  911. }
  912. }
  913. __int64 RtlUnicodeTypeInfo::getInt(const void * ptr) const
  914. {
  915. //Utf8 output is the same as string output, so avoid the intermediate translation
  916. if (isFixedSize())
  917. return rtlUnicodeToInt8(length, (const UChar *)ptr);
  918. size32_t len = rtlReadUInt4(ptr);
  919. const char * str = (const char *)ptr + sizeof(size32_t);
  920. return rtlUnicodeToInt8(len, (const UChar *)str);
  921. }
  922. //-------------------------------------------------------------------------------------------------------------------
  923. size32_t RtlVarUnicodeTypeInfo::getMinSize() const
  924. {
  925. if (isFixedSize())
  926. return length * sizeof(UChar);
  927. return sizeof(UChar);
  928. }
  929. size32_t RtlVarUnicodeTypeInfo::size(const byte * self, const byte * selfrow) const
  930. {
  931. if (isFixedSize())
  932. return (length+1) * sizeof(UChar);
  933. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  934. return (rtlUnicodeStrlen(ustr)+1) * sizeof(UChar);
  935. }
  936. size32_t RtlVarUnicodeTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  937. {
  938. size32_t sizeInChars;
  939. UChar *value;
  940. source.getUnicodeResult(field, sizeInChars, value);
  941. if (!isFixedSize())
  942. {
  943. size32_t sizeInBytes = (sizeInChars+1) * sizeof(UChar);
  944. builder.ensureCapacity(offset+sizeInBytes, field->name);
  945. UChar *dest = (UChar *) builder.getSelf()+offset;
  946. memcpy(dest, value, sizeInBytes - sizeof(UChar));
  947. dest[sizeInChars] = 0;
  948. offset += sizeInBytes;
  949. }
  950. else
  951. {
  952. size32_t sizeInBytes = length * sizeof(UChar);
  953. builder.ensureCapacity(offset+sizeInBytes, field->name);
  954. byte *dest = builder.getSelf()+offset;
  955. rtlUnicodeToVUnicode(length, (UChar *) dest, sizeInChars, value);
  956. offset += sizeInBytes;
  957. }
  958. rtlFree(value);
  959. return offset;
  960. }
  961. size32_t RtlVarUnicodeTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  962. {
  963. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  964. unsigned thisLength = rtlUnicodeStrlen(ustr);
  965. unsigned thisSize;
  966. if (isFixedSize())
  967. thisSize = (length + 1) * sizeof(UChar);
  968. else
  969. thisSize = (thisLength + 1) * sizeof(UChar);
  970. target.processUnicode(thisLength, ustr, field);
  971. return thisSize;
  972. }
  973. size32_t RtlVarUnicodeTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  974. {
  975. const UChar * ustr = reinterpret_cast<const UChar *>(self);
  976. unsigned thisLength = rtlUnicodeStrlen(ustr);
  977. unsigned thisSize;
  978. if (isFixedSize())
  979. thisSize = (length + 1) * sizeof(UChar);
  980. else
  981. thisSize = (thisLength + 1) * sizeof(UChar);
  982. target.outputUnicode(thisLength, ustr, queryScalarXPath(field));
  983. return thisSize;
  984. }
  985. void RtlVarUnicodeTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  986. {
  987. const UChar * str = (const UChar *)ptr;
  988. rtlUnicodeToUtf8X(resultLen, result, rtlUnicodeStrlen(str), str);
  989. }
  990. __int64 RtlVarUnicodeTypeInfo::getInt(const void * ptr) const
  991. {
  992. const UChar * str = (const UChar *)ptr;
  993. return rtlUnicodeToInt8(rtlUnicodeStrlen(str), str);
  994. }
  995. //-------------------------------------------------------------------------------------------------------------------
  996. size32_t RtlUtf8TypeInfo::getMinSize() const
  997. {
  998. return sizeof(size32_t);
  999. }
  1000. size32_t RtlUtf8TypeInfo::size(const byte * self, const byte * selfrow) const
  1001. {
  1002. assertex(!isFixedSize());
  1003. return sizeof(size32_t) + rtlUtf8Size(rtlReadUInt4(self), self+sizeof(unsigned));
  1004. }
  1005. size32_t RtlUtf8TypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1006. {
  1007. size32_t sizeInChars;
  1008. char *value;
  1009. source.getUTF8Result(field, sizeInChars, value);
  1010. size32_t sizeInBytes = rtlUtf8Size(sizeInChars, value);
  1011. assertex(!isFixedSize());
  1012. builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), field->name);
  1013. byte *dest = builder.getSelf()+offset;
  1014. rtlWriteInt4(dest, sizeInChars); // NOTE - in chars!
  1015. memcpy(dest+sizeof(size32_t), value, sizeInBytes);
  1016. offset += sizeInBytes+sizeof(size32_t);
  1017. rtlFree(value);
  1018. return offset;
  1019. }
  1020. size32_t RtlUtf8TypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1021. {
  1022. assertex(!isFixedSize());
  1023. const char * str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1024. unsigned thisLength = rtlReadUInt4(self);
  1025. unsigned thisSize = sizeof(size32_t) + rtlUtf8Size(thisLength, str);
  1026. target.processUtf8(thisLength, str, field);
  1027. return thisSize;
  1028. }
  1029. size32_t RtlUtf8TypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1030. {
  1031. assertex(!isFixedSize());
  1032. const char * str = reinterpret_cast<const char *>(self + sizeof(size32_t));
  1033. unsigned thisLength = rtlReadUInt4(self);
  1034. unsigned thisSize = sizeof(size32_t) + rtlUtf8Size(thisLength, str);
  1035. target.outputUtf8(thisLength, str, queryScalarXPath(field));
  1036. return thisSize;
  1037. }
  1038. void RtlUtf8TypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1039. {
  1040. if (isFixedSize())
  1041. {
  1042. rtlUtf8ToUtf8X(resultLen, result, length, (const char *)ptr);
  1043. }
  1044. else
  1045. {
  1046. size32_t len = rtlReadUInt4(ptr);
  1047. rtlUtf8ToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
  1048. }
  1049. }
  1050. __int64 RtlUtf8TypeInfo::getInt(const void * ptr) const
  1051. {
  1052. //Utf8 output is the same as string output, so avoid the intermediate translation
  1053. if (isFixedSize())
  1054. return rtlUtf8ToInt(length, (const char *)ptr);
  1055. size32_t len = rtlReadUInt4(ptr);
  1056. return rtlUtf8ToInt(len, (const char *)ptr + sizeof(size32_t));
  1057. }
  1058. //-------------------------------------------------------------------------------------------------------------------
  1059. inline size32_t sizeFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow)
  1060. {
  1061. unsigned offset = 0;
  1062. for (;;)
  1063. {
  1064. const RtlFieldInfo * child = *cur;
  1065. if (!child)
  1066. break;
  1067. offset += child->size(self+offset, selfrow);
  1068. cur++;
  1069. }
  1070. return offset;
  1071. }
  1072. inline size32_t processFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow, IFieldProcessor & target)
  1073. {
  1074. unsigned offset = 0;
  1075. for (;;)
  1076. {
  1077. const RtlFieldInfo * child = *cur;
  1078. if (!child)
  1079. break;
  1080. child->process(self+offset, selfrow, target);
  1081. offset += child->size(self+offset, selfrow);
  1082. cur++;
  1083. }
  1084. return offset;
  1085. }
  1086. inline size32_t buildFields(const RtlFieldInfo * const * cur, ARowBuilder &builder, size32_t offset, IFieldSource &source)
  1087. {
  1088. for (;;)
  1089. {
  1090. const RtlFieldInfo * child = *cur;
  1091. if (!child)
  1092. break;
  1093. offset = child->build(builder, offset, source);
  1094. cur++;
  1095. }
  1096. return offset;
  1097. }
  1098. inline size32_t toXMLFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow, IXmlWriter & target)
  1099. {
  1100. size32_t offset = 0;
  1101. for (;;)
  1102. {
  1103. const RtlFieldInfo * child = *cur;
  1104. if (!child)
  1105. break;
  1106. size32_t size = child->toXML(self+offset, selfrow, target);
  1107. offset += size;
  1108. cur++;
  1109. }
  1110. return offset;
  1111. }
  1112. //-------------------------------------------------------------------------------------------------------------------
  1113. size32_t RtlRecordTypeInfo::getMinSize() const
  1114. {
  1115. return ::getMinSize(fields);
  1116. }
  1117. size32_t RtlRecordTypeInfo::size(const byte * self, const byte * selfrow) const
  1118. {
  1119. return sizeFields(fields, self, self);
  1120. }
  1121. size32_t RtlRecordTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1122. {
  1123. if (target.processBeginRow(field))
  1124. {
  1125. unsigned offset = processFields(fields, self, self, target);
  1126. target.processEndRow(field);
  1127. return offset;
  1128. }
  1129. return size(self, selfrow);
  1130. }
  1131. size32_t RtlRecordTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1132. {
  1133. const char * xpath = queryXPath(field);
  1134. if (*xpath)
  1135. target.outputBeginNested(xpath, false);
  1136. unsigned thisSize = toXMLFields(fields, self, self, target);
  1137. if (*xpath)
  1138. target.outputEndNested(xpath);
  1139. return thisSize;
  1140. }
  1141. size32_t RtlRecordTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1142. {
  1143. source.processBeginRow(field);
  1144. offset = buildFields(fields, builder, offset, source);
  1145. source.processEndRow(field);
  1146. return offset;
  1147. }
  1148. void RtlRecordTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1149. {
  1150. resultLen = 0;
  1151. result = nullptr;
  1152. }
  1153. __int64 RtlRecordTypeInfo::getInt(const void * ptr) const
  1154. {
  1155. return 0;
  1156. }
  1157. //-------------------------------------------------------------------------------------------------------------------
  1158. void RtlCompoundTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1159. {
  1160. //MORE: Should this fail instead?
  1161. resultLen = 0;
  1162. result = nullptr;
  1163. }
  1164. __int64 RtlCompoundTypeInfo::getInt(const void * ptr) const
  1165. {
  1166. //MORE: Should this fail instead?
  1167. return 0;
  1168. }
  1169. //-------------------------------------------------------------------------------------------------------------------
  1170. size32_t RtlSetTypeInfo::getMinSize() const
  1171. {
  1172. return sizeof(bool) + sizeof(size32_t);
  1173. }
  1174. size32_t RtlSetTypeInfo::size(const byte * self, const byte * selfrow) const
  1175. {
  1176. return sizeof(bool) + sizeof(size32_t) + rtlReadUInt4(self + sizeof(bool));
  1177. }
  1178. size32_t RtlSetTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1179. {
  1180. bool isAll;
  1181. source.processBeginSet(field, isAll);
  1182. size32_t sizeInBytes = sizeof(bool) + sizeof(size32_t);
  1183. builder.ensureCapacity(offset+sizeInBytes, field->name);
  1184. byte *dest = builder.getSelf()+offset;
  1185. if (isAll)
  1186. {
  1187. * (bool *) dest = true;
  1188. rtlWriteInt4(dest+1, 0);
  1189. offset += sizeInBytes;
  1190. }
  1191. else
  1192. {
  1193. * (bool *) dest = false;
  1194. size32_t newOffset = offset + sizeInBytes;
  1195. RtlFieldStrInfo dummyField("<set element>", NULL, child);
  1196. while (source.processNextSet(field))
  1197. {
  1198. newOffset = child->build(builder, newOffset, &dummyField, source);
  1199. }
  1200. // Go back in and patch the size, remembering it may have moved
  1201. rtlWriteInt4(builder.getSelf()+offset+1, newOffset - (offset+sizeInBytes));
  1202. offset = newOffset;
  1203. }
  1204. source.processEndSet(field);
  1205. return offset;
  1206. }
  1207. size32_t RtlSetTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1208. {
  1209. unsigned offset = sizeof(bool) + sizeof(size32_t);
  1210. unsigned max = offset + rtlReadUInt4(self + sizeof(bool));
  1211. unsigned elements = 0;
  1212. if (!*(bool *)self)
  1213. {
  1214. unsigned tempOffset = sizeof(bool) + sizeof(size32_t);
  1215. if (child->isFixedSize())
  1216. {
  1217. unsigned elemSize = child->size(NULL, NULL);
  1218. elements = (max-offset) / elemSize;
  1219. assert(elements*elemSize == max-offset);
  1220. }
  1221. else
  1222. {
  1223. DummyFieldProcessor dummy;
  1224. while (tempOffset < max)
  1225. {
  1226. tempOffset += child->process(self+tempOffset, selfrow, field, dummy); // NOTE - good thing we can't have a set of sets, or this would recurse
  1227. elements++;
  1228. }
  1229. }
  1230. }
  1231. if (target.processBeginSet(field, elements, *(bool *)self, self+offset))
  1232. {
  1233. while (offset < max)
  1234. {
  1235. offset += child->process(self+offset, selfrow, field, target);
  1236. }
  1237. }
  1238. target.processEndSet(field);
  1239. return max;
  1240. }
  1241. size32_t RtlSetTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1242. {
  1243. unsigned offset = sizeof(bool) + sizeof(size32_t);
  1244. unsigned max = offset + rtlReadUInt4(self + sizeof(bool));
  1245. StringAttr outerTag;
  1246. if (hasOuterXPath(field))
  1247. {
  1248. queryNestedOuterXPath(outerTag, field);
  1249. target.outputBeginNested(outerTag, false);
  1250. }
  1251. if (*(bool *)self)
  1252. target.outputSetAll();
  1253. else
  1254. {
  1255. const char *innerPath = queryXPath(field);
  1256. target.outputBeginArray(innerPath);
  1257. while (offset < max)
  1258. {
  1259. child->toXML(self+offset, selfrow, field, target);
  1260. offset += child->size(self+offset, selfrow);
  1261. }
  1262. target.outputEndArray(innerPath);
  1263. }
  1264. if (outerTag)
  1265. target.outputEndNested(outerTag);
  1266. return max;
  1267. }
  1268. //-------------------------------------------------------------------------------------------------------------------
  1269. size32_t RtlRowTypeInfo::getMinSize() const
  1270. {
  1271. if (isLinkCounted())
  1272. return sizeof(void *);
  1273. return child->getMinSize();
  1274. }
  1275. size32_t RtlRowTypeInfo::size(const byte * self, const byte * selfrow) const
  1276. {
  1277. if (isLinkCounted())
  1278. return sizeof(void *);
  1279. return child->size(self, selfrow);
  1280. }
  1281. size32_t RtlRowTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1282. {
  1283. if (isLinkCounted())
  1284. {
  1285. const byte * row = *(const byte * *)self;
  1286. if (row)
  1287. child->process(row, row, field, target);
  1288. return sizeof(row);
  1289. }
  1290. return child->process(self, self, field, target);
  1291. }
  1292. size32_t RtlRowTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1293. {
  1294. if (isLinkCounted())
  1295. {
  1296. const byte * row = *(const byte * *)self;
  1297. child->toXML(row, row, field, target);
  1298. return sizeof(row);
  1299. }
  1300. return child->toXML(self, self, field, target);
  1301. }
  1302. //-------------------------------------------------------------------------------------------------------------------
  1303. size32_t RtlDatasetTypeInfo::getMinSize() const
  1304. {
  1305. if (isLinkCounted())
  1306. return sizeof(size32_t) + sizeof(void * *);
  1307. return sizeof(size32_t);
  1308. }
  1309. size32_t RtlDatasetTypeInfo::size(const byte * self, const byte * selfrow) const
  1310. {
  1311. if (isLinkCounted())
  1312. return sizeof(size32_t) + sizeof(void * *);
  1313. return sizeof(size32_t) + rtlReadUInt4(self);
  1314. }
  1315. size32_t RtlDatasetTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1316. {
  1317. source.processBeginDataset(field);
  1318. if (isLinkCounted())
  1319. {
  1320. // a 32-bit record count, and a pointer to an array of record pointers
  1321. size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
  1322. builder.ensureCapacity(offset+sizeInBytes, field->name);
  1323. size32_t numRows = 0;
  1324. Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
  1325. byte **childRows = NULL;
  1326. RtlFieldStrInfo dummyField("<nested row>", NULL, child);
  1327. while (source.processNextRow(field))
  1328. {
  1329. RtlDynamicRowBuilder childBuilder(*childAllocator);
  1330. size32_t childLen = child->build(childBuilder, 0, &dummyField, source);
  1331. childRows = childAllocator->appendRowOwn(childRows, ++numRows, (void *) childBuilder.finalizeRowClear(childLen));
  1332. }
  1333. // Go back in and patch the count, remembering it may have moved
  1334. rtlWriteInt4(builder.getSelf()+offset, numRows);
  1335. * ( const void * * ) (builder.getSelf()+offset+sizeof(size32_t)) = childRows;
  1336. offset += sizeInBytes;
  1337. }
  1338. else
  1339. {
  1340. // a 32-bit size, then rows inline
  1341. size32_t sizeInBytes = sizeof(size32_t);
  1342. builder.ensureCapacity(offset+sizeInBytes, field->name);
  1343. size32_t newOffset = offset + sizeInBytes;
  1344. RtlFieldStrInfo dummyField("<nested row>", NULL, child);
  1345. while (source.processNextRow(field))
  1346. newOffset = child->build(builder, newOffset, &dummyField, source);
  1347. // Go back in and patch the size, remembering it may have moved
  1348. rtlWriteInt4(builder.getSelf()+offset, newOffset - (offset+sizeInBytes));
  1349. offset = newOffset;
  1350. }
  1351. source.processEndDataset(field);
  1352. return offset;
  1353. }
  1354. size32_t RtlDatasetTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1355. {
  1356. if (isLinkCounted())
  1357. {
  1358. size32_t thisCount = rtlReadUInt4(self);
  1359. if (target.processBeginDataset(field, thisCount))
  1360. {
  1361. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  1362. for (unsigned i= 0; i < thisCount; i++)
  1363. {
  1364. const byte * row = rows[i];
  1365. child->process(row, row, field, target);
  1366. }
  1367. target.processEndDataset(field);
  1368. }
  1369. return sizeof(size32_t) + sizeof(void * *);
  1370. }
  1371. else
  1372. {
  1373. unsigned offset = sizeof(size32_t);
  1374. unsigned max = offset + rtlReadUInt4(self);
  1375. unsigned thisCount = 0;
  1376. DummyFieldProcessor dummy;
  1377. while (offset < max)
  1378. {
  1379. offset += child->process(self+offset, self+offset, field, dummy);
  1380. thisCount++;
  1381. }
  1382. offset = sizeof(size32_t);
  1383. if (target.processBeginDataset(field, thisCount))
  1384. {
  1385. while (offset < max)
  1386. {
  1387. offset += child->process(self+offset, self+offset, field, target);
  1388. }
  1389. target.processEndDataset(field);
  1390. }
  1391. return max;
  1392. }
  1393. }
  1394. size32_t RtlDatasetTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1395. {
  1396. StringAttr outerTag;
  1397. if (hasOuterXPath(field))
  1398. {
  1399. queryNestedOuterXPath(outerTag, field);
  1400. target.outputBeginNested(outerTag, false);
  1401. }
  1402. const char *innerPath = queryXPath(field);
  1403. target.outputBeginArray(innerPath);
  1404. unsigned thisSize;
  1405. if (isLinkCounted())
  1406. {
  1407. size32_t thisCount = rtlReadUInt4(self);
  1408. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  1409. for (unsigned i= 0; i < thisCount; i++)
  1410. {
  1411. const byte * row = rows[i];
  1412. if (row)
  1413. child->toXML(row, row, field, target);
  1414. }
  1415. thisSize = sizeof(size32_t) + sizeof(void * *);
  1416. }
  1417. else
  1418. {
  1419. unsigned offset = sizeof(size32_t);
  1420. unsigned max = offset + rtlReadUInt4(self);
  1421. while (offset < max)
  1422. {
  1423. child->toXML(self+offset, self+offset, field, target);
  1424. offset += child->size(self+offset, self+offset);
  1425. }
  1426. thisSize = max;
  1427. }
  1428. target.outputEndArray(innerPath);
  1429. if (outerTag)
  1430. target.outputEndNested(outerTag);
  1431. return thisSize;
  1432. }
  1433. //-------------------------------------------------------------------------------------------------------------------
  1434. size32_t RtlDictionaryTypeInfo::getMinSize() const
  1435. {
  1436. if (isLinkCounted())
  1437. return sizeof(size32_t) + sizeof(void * *);
  1438. return sizeof(size32_t);
  1439. }
  1440. size32_t RtlDictionaryTypeInfo::size(const byte * self, const byte * selfrow) const
  1441. {
  1442. if (isLinkCounted())
  1443. return sizeof(size32_t) + sizeof(void * *);
  1444. return sizeof(size32_t) + rtlReadUInt4(self);
  1445. }
  1446. size32_t RtlDictionaryTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
  1447. {
  1448. source.processBeginDataset(field);
  1449. if (isLinkCounted())
  1450. {
  1451. // a 32-bit record count, and a pointer to an hash table with record pointers
  1452. size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
  1453. builder.ensureCapacity(offset+sizeInBytes, field->name);
  1454. Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
  1455. RtlLinkedDictionaryBuilder dictBuilder(childAllocator, hashInfo);
  1456. RtlFieldStrInfo dummyField("<nested row>", NULL, child);
  1457. while (source.processNextRow(field))
  1458. {
  1459. RtlDynamicRowBuilder childBuilder(childAllocator);
  1460. size32_t childLen = child->build(childBuilder, 0, &dummyField, source);
  1461. dictBuilder.appendOwn((void *) childBuilder.finalizeRowClear(childLen));
  1462. }
  1463. // Go back in and patch the count
  1464. rtlWriteInt4(builder.getSelf()+offset, dictBuilder.getcount());
  1465. * ( const void * * ) (builder.getSelf()+offset+sizeof(size32_t)) = dictBuilder.linkrows();
  1466. offset += sizeInBytes;
  1467. }
  1468. else
  1469. UNIMPLEMENTED; // And may never be...
  1470. source.processEndDataset(field);
  1471. return offset;
  1472. }
  1473. size32_t RtlDictionaryTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1474. {
  1475. if (isLinkCounted())
  1476. {
  1477. size32_t thisCount = rtlReadUInt4(self);
  1478. if (target.processBeginDataset(field, thisCount))
  1479. {
  1480. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  1481. for (unsigned i= 0; i < thisCount; i++)
  1482. {
  1483. const byte * row = rows[i];
  1484. if (row)
  1485. child->process(row, row, field, target);
  1486. }
  1487. target.processEndDataset(field);
  1488. }
  1489. return sizeof(size32_t) + sizeof(void * *);
  1490. }
  1491. else
  1492. {
  1493. //MORE: We could interpret serialized dictionaries if there was ever a need
  1494. UNIMPLEMENTED;
  1495. }
  1496. }
  1497. size32_t RtlDictionaryTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1498. {
  1499. StringAttr outerTag;
  1500. if (hasOuterXPath(field))
  1501. {
  1502. queryNestedOuterXPath(outerTag, field);
  1503. target.outputBeginNested(outerTag, false);
  1504. }
  1505. const char *innerPath = queryXPath(field);
  1506. target.outputBeginArray(innerPath);
  1507. unsigned thisSize;
  1508. if (isLinkCounted())
  1509. {
  1510. size32_t thisCount = rtlReadUInt4(self);
  1511. const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
  1512. for (unsigned i= 0; i < thisCount; i++)
  1513. {
  1514. const byte * row = rows[i];
  1515. if (row)
  1516. child->toXML(row, row, field, target);
  1517. }
  1518. thisSize = sizeof(size32_t) + sizeof(void * *);
  1519. }
  1520. else
  1521. {
  1522. //MORE: We could interpret serialized dictionaries if there was ever a need
  1523. UNIMPLEMENTED;
  1524. }
  1525. target.outputEndArray(innerPath);
  1526. if (outerTag)
  1527. target.outputEndNested(outerTag);
  1528. return thisSize;
  1529. }
  1530. //-------------------------------------------------------------------------------------------------------------------
  1531. size32_t RtlIfBlockTypeInfo::getMinSize() const
  1532. {
  1533. return 0;
  1534. }
  1535. size32_t RtlIfBlockTypeInfo::size(const byte * self, const byte * selfrow) const
  1536. {
  1537. if (getCondition(selfrow))
  1538. return sizeFields(fields, self, selfrow);
  1539. return 0;
  1540. }
  1541. size32_t RtlIfBlockTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1542. {
  1543. if (getCondition(selfrow))
  1544. return processFields(fields, self, selfrow, target);
  1545. return 0;
  1546. }
  1547. size32_t RtlIfBlockTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1548. {
  1549. if (getCondition(selfrow))
  1550. return toXMLFields(fields, self, selfrow, target);
  1551. return 0;
  1552. }
  1553. void RtlIfBlockTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1554. {
  1555. //MORE: Should this fail instead?
  1556. resultLen = 0;
  1557. result = nullptr;
  1558. }
  1559. __int64 RtlIfBlockTypeInfo::getInt(const void * ptr) const
  1560. {
  1561. //MORE: Should this fail instead?
  1562. return 0;
  1563. }
  1564. //-------------------------------------------------------------------------------------------------------------------
  1565. __int64 RtlBitfieldTypeInfo::signedValue(const void * self) const
  1566. {
  1567. __int64 value = rtlReadInt(self, getBitfieldIntSize());
  1568. unsigned shift = getBitfieldShift();
  1569. unsigned numBits = getBitfieldNumBits();
  1570. unsigned bitsInValue = sizeof(value) * 8;
  1571. value <<= (bitsInValue - shift - numBits);
  1572. return value >> (bitsInValue - numBits);
  1573. }
  1574. unsigned __int64 RtlBitfieldTypeInfo::unsignedValue(const void * self) const
  1575. {
  1576. unsigned __int64 value = rtlReadUInt(self, getBitfieldIntSize());
  1577. unsigned shift = getBitfieldShift();
  1578. unsigned numBits = getBitfieldNumBits();
  1579. unsigned bitsInValue = sizeof(value) * 8;
  1580. value <<= (bitsInValue - shift - numBits);
  1581. return value >> (bitsInValue - numBits);
  1582. }
  1583. size32_t RtlBitfieldTypeInfo::getMinSize() const
  1584. {
  1585. if (fieldType & RFTMislastbitfield)
  1586. return getBitfieldIntSize();
  1587. return 0;
  1588. }
  1589. size32_t RtlBitfieldTypeInfo::size(const byte * self, const byte * selfrow) const
  1590. {
  1591. if (fieldType & RFTMislastbitfield)
  1592. return getBitfieldIntSize();
  1593. return 0;
  1594. }
  1595. size32_t RtlBitfieldTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1596. {
  1597. if (isUnsigned())
  1598. target.processUInt(unsignedValue(self), field);
  1599. else
  1600. target.processInt(signedValue(self), field);
  1601. return size(self, selfrow);
  1602. }
  1603. size32_t RtlBitfieldTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1604. {
  1605. size32_t fieldsize = getBitfieldIntSize();
  1606. if (isUnsigned())
  1607. target.outputUInt(unsignedValue(self), fieldsize, queryScalarXPath(field));
  1608. else
  1609. target.outputInt(signedValue(self), fieldsize, queryScalarXPath(field));
  1610. if (fieldType & RFTMislastbitfield)
  1611. return fieldsize;
  1612. return 0;
  1613. }
  1614. void RtlBitfieldTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1615. {
  1616. if (isUnsigned())
  1617. rtlUInt8ToStrX(resultLen, result, unsignedValue(ptr));
  1618. else
  1619. rtlInt8ToStrX(resultLen, result, signedValue(ptr));
  1620. }
  1621. __int64 RtlBitfieldTypeInfo::getInt(const void * ptr) const
  1622. {
  1623. if (isUnsigned())
  1624. return (__int64)unsignedValue(ptr);
  1625. else
  1626. return signedValue(ptr);
  1627. }
  1628. //-------------------------------------------------------------------------------------------------------------------
  1629. size32_t RtlUnimplementedTypeInfo::getMinSize() const
  1630. {
  1631. rtlFailUnexpected();
  1632. return 0;
  1633. }
  1634. size32_t RtlUnimplementedTypeInfo::size(const byte * self, const byte * selfrow) const
  1635. {
  1636. rtlFailUnexpected();
  1637. return 0;
  1638. }
  1639. size32_t RtlUnimplementedTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
  1640. {
  1641. rtlFailUnexpected();
  1642. return 0;
  1643. }
  1644. size32_t RtlUnimplementedTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
  1645. {
  1646. rtlFailUnexpected();
  1647. return 0;
  1648. }
  1649. void RtlUnimplementedTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
  1650. {
  1651. resultLen = 0;
  1652. result = nullptr;
  1653. rtlFailUnexpected();
  1654. }
  1655. __int64 RtlUnimplementedTypeInfo::getInt(const void * ptr) const
  1656. {
  1657. rtlFailUnexpected();
  1658. return 0;
  1659. }
  1660. //-------------------------------------------------------------------------------------------------------------------
  1661. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, unsigned _flags, const char *_initializer)
  1662. : RtlFieldInfo(_name, _xpath, _type, _flags, _initializer)
  1663. {
  1664. }
  1665. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, unsigned _flags)
  1666. : RtlFieldInfo(_name, _xpath, _type, _flags, NULL)
  1667. {
  1668. }
  1669. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type)
  1670. : RtlFieldInfo(_name, _xpath, _type, 0, NULL)
  1671. {
  1672. }
  1673. RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, const char *_initializer)
  1674. : RtlFieldInfo(_name, _xpath, _type, 0, _initializer)
  1675. {
  1676. }
  1677. /*
  1678. Stack:
  1679. * Change hqlhtcpp so that the correct derived classes are generated.
  1680. * Test so that toXML calls the default implementaions and check that the same values are generated. (Don't if contains ifblocks/alien)
  1681. * Release
  1682. * Think about bitfields - how do I know it is the last bitfield, how am I going to keep track of the offsets.
  1683. * What code would need to be generated for alien datatypes.
  1684. * Could have alien int and alien string varieties????
  1685. * What would an ecl interpreter look like (a special workunit?) helpers are interpreted? What about the graph?
  1686. * Could I add associations to register user attributes - so a callback could know when they were assigned to?
  1687. * Could I add ctx->noteLocation() into the generated code - so could put breakpoints on variables.
  1688. * Add annotation when a member of the target dataset is updated.
  1689. ctx->noteFieldAssigned(self, <field>); - does this include temporary datasets?
  1690. ctx->noteAttributeX(<name>, Int|String|Unicode|
  1691. 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??
  1692. * Need static information about the breakpoints so debugger knows where to put valid brakpoints....
  1693. * Debugger will want to know about the type of the breakpoints.
  1694. * Should try and compress the location format - possibly have a table of <module.attributes>-># with breakpoint as 12:23
  1695. Also need some information about which datasets, and stored variables etc. are used so they can be displayed.
  1696. - Most datasets can be deduced from the parameters passed into the transform
  1697. - Some are trickier e.g., the extract, could possibly define some mappings
  1698. - options to disable projects/other more complex operations inline (so easier to walk through)
  1699. Bitfields:
  1700. - Two separate questions:
  1701. i) How is the meta information generated.
  1702. ii) How is it stored internally in an IHqlExpression * ?
  1703. * Could store the offset in the type - either in the base type of as a qualifier.
  1704. + much easier code generation.
  1705. - Doesn't provie an easy indication of the last field in a bitfield (because can't really modify after the fact)
  1706. - Problematic when fields are removed to merge them.
  1707. * Could add a bitfield container to the record.
  1708. + Makes it easier to handle the last bitfield
  1709. + Matches the structure used for the cursor.
  1710. - Everything needs to walk the bitfield containers similar to ifblocks.
  1711. - Makes it just as tricky to merge
  1712. - Harder to create the record, unless the code is implicitly handled by appendOperand().
  1713. * The type of no_select could contain a modifier to indicate the offset/islast
  1714. + the type of a no_select would have a 1:1 mapping with type info.
  1715. - A bit complicated to calculate, especially when it isn't used much of the time
  1716. => On Reflection is is probably easiest to keep the structure as it is (some comments should go in hqlexpr to avoid revisiting).
  1717. * interperet bitfield offsets and "is last bitfield" dynamically
  1718. + Greatly simplifies generating the meta - you can always use the field.
  1719. - Requires another parameter and significant extra complexity for the uncommon case. (especially incrementing self)
  1720. * Could generate from the expanded record instead of walking the record structure directly
  1721. + That already knows how the bitfields are allocated, and could easily know which is the last field.
  1722. - A field is no longer sufficient as key fr searching for the information.
  1723. - Best would be a createFieldTypeKey(select-expr) which returns field when approriate, or modified if a bitfield. Then the pain is localised.
  1724. * Output a bitfield container item into the type information
  1725. + Solves the size problem
  1726. - Individual bitfields still need to know their offsets, so doesn't solve the full problem.
  1727. =>
  1728. Change so that either use meta to generate the information, or use no_select when appropriate to fidn out the nesc. information.
  1729. Probably the latter for the moment.
  1730. a) Create a key function and make sure it is always used.
  1731. b) Need to work out how to generate no_ifblock.
  1732. - ifblock is context dependent, so need to generate as part of the parent record, and in the parent record context.
  1733. */