rtlfield.cpp 79 KB

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