12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include "platform.h"
- #include <math.h>
- #include <stdio.h>
- #include "jmisc.hpp"
- #include "jlib.hpp"
- #include "eclhelper.hpp"
- #include "eclrtl_imp.hpp"
- #include "rtlfield.hpp"
- #include "rtlds_imp.hpp"
- #include "nbcd.hpp"
- static const char * queryXPath(const RtlFieldInfo * field)
- {
- const char * xpath = field->xpath;
- if (xpath)
- {
- const char * sep = strchr(xpath, xpathCompoundSeparatorChar);
- if (!sep)
- return xpath;
- return sep+1;
- }
- return field->name;
- }
- static const char * queryScalarXPath(const RtlFieldInfo * field)
- {
- if (field->hasNonScalarXpath())
- return field->name;
- return queryXPath(field);
- }
- static bool hasOuterXPath(const RtlFieldInfo * field)
- {
- const char * xpath = field->xpath;
- assertex(xpath);
- return (*xpath != xpathCompoundSeparatorChar);
- }
- static void queryNestedOuterXPath(StringAttr & ret, const RtlFieldInfo * field)
- {
- const char * xpath = field->xpath;
- assertex(xpath);
- const char * sep = strchr(xpath, xpathCompoundSeparatorChar);
- assertex(sep);
- ret.set(xpath, (size32_t)(sep-xpath));
- }
- inline const char * queryName(const RtlFieldInfo * field) { return field ? field->name : nullptr; }
- //-------------------------------------------------------------------------------------------------------------------
- class DummyFieldProcessor : public CInterfaceOf<IFieldProcessor>
- {
- public:
- virtual void processString(unsigned len, const char *value, const RtlFieldInfo * field) {}
- virtual void processBool(bool value, const RtlFieldInfo * field) {}
- virtual void processData(unsigned len, const void *value, const RtlFieldInfo * field) {}
- virtual void processInt(__int64 value, const RtlFieldInfo * field) {}
- virtual void processUInt(unsigned __int64 value, const RtlFieldInfo * field) {}
- virtual void processReal(double value, const RtlFieldInfo * field) {}
- virtual void processDecimal(const void *value, unsigned digits, unsigned precision, const RtlFieldInfo * field) {}
- virtual void processUDecimal(const void *value, unsigned digits, unsigned precision, const RtlFieldInfo * field) {}
- virtual void processUnicode(unsigned len, const UChar *value, const RtlFieldInfo * field) {}
- virtual void processQString(unsigned len, const char *value, const RtlFieldInfo * field) {}
- virtual void processUtf8(unsigned len, const char *value, const RtlFieldInfo * field) {}
- virtual bool processBeginSet(const RtlFieldInfo * field, unsigned numElements, bool isAll, const byte *data) { return false; }
- virtual bool processBeginDataset(const RtlFieldInfo * field, unsigned numRows) { return true; }
- virtual bool processBeginRow(const RtlFieldInfo * field) { return true; }
- virtual void processEndSet(const RtlFieldInfo * field) {}
- virtual void processEndDataset(const RtlFieldInfo * field) {}
- virtual void processEndRow(const RtlFieldInfo * field) {}
- };
- //-------------------------------------------------------------------------------------------------------------------
- size32_t ECLRTL_API getMinSize(const RtlFieldInfo * const * fields)
- {
- size32_t minSize = 0;
- for(;;)
- {
- const RtlFieldInfo * cur = *fields;
- if (!cur)
- return minSize;
- minSize += cur->type->getMinSize();
- fields++;
- }
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlTypeInfoBase::getMinSize() const
- {
- return length;
- }
- size32_t RtlTypeInfoBase::size(const byte * self, const byte * selfrow) const
- {
- return length;
- }
- size32_t RtlTypeInfoBase::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- rtlFailUnexpected();
- return 0;
- }
- size32_t RtlTypeInfoBase::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & out) const
- {
- rtlFailUnexpected();
- return 0;
- }
- size32_t RtlTypeInfoBase::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- rtlFailUnexpected();
- return 0;
- }
- size32_t RtlTypeInfoBase::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
- {
- if (field->initializer)
- {
- size32_t initSize = size(field->initializer, nullptr);
- builder.ensureCapacity(offset+initSize, queryName(field));
- memcpy(builder.getSelf()+offset, field->initializer, initSize);
- return offset+initSize;
- }
- else
- {
- // This code covers a lot (though not all) of the derived cases
- size32_t initSize = getMinSize();
- builder.ensureCapacity(offset+initSize, queryName(field));
- memset(builder.getSelf() + offset, 0, initSize);
- return offset + initSize;
- }
- }
- size32_t RtlTypeInfoBase::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- size32_t newLen;
- rtlDataAttr temp;
- rtlInt8ToStrX(newLen, temp.refstr(), val);
- return buildString(builder, offset, field, newLen, temp.getstr());
- }
- size32_t RtlTypeInfoBase::buildReal(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, double val) const
- {
- size32_t newLen;
- rtlDataAttr temp;
- rtlRealToStrX(newLen, temp.refstr(), val);
- return buildString(builder, offset, field, newLen, temp.getstr());
- }
- double RtlTypeInfoBase::getReal(const void * ptr) const
- {
- size32_t len;
- rtlDataAttr value;
- getString(len, value.refstr(), ptr);
- return rtlStrToReal(len, value.getstr());
- }
- const char * RtlTypeInfoBase::queryLocale() const
- {
- return NULL;
- }
- bool RtlTypeInfoBase::isScalar() const
- {
- return true;
- }
- const RtlFieldInfo * const * RtlTypeInfoBase::queryFields() const
- {
- return NULL;
- }
- const RtlTypeInfo * RtlTypeInfoBase::queryChildType() const
- {
- return NULL;
- }
- size32_t RtlTypeInfoBase::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- size32_t thisSize = size(nullptr, nullptr);
- byte * dest = builder.ensureCapacity(offset + thisSize, nullptr) + offset;
- in.read(thisSize, dest);
- return offset + thisSize;
- }
- void RtlTypeInfoBase::readAhead(IRowDeserializerSource & in) const
- {
- size32_t thisSize = size(nullptr, nullptr);
- in.skip(thisSize);
- }
- size32_t RtlTypeInfoBase::buildUtf8ViaString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t newLen;
- rtlDataAttr temp;
- rtlUtf8ToStrX(newLen, temp.refstr(), len, value);
- return buildString(builder, offset, field, newLen, temp.getstr());
- }
- void RtlTypeInfoBase::getUtf8ViaString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- size32_t newLen;
- rtlDataAttr temp;
- getString(newLen, temp.refstr(), ptr);
- rtlStrToUtf8X(resultLen, result, newLen, temp.getstr());
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlBoolTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- builder.ensureCapacity(sizeof(bool)+offset, queryName(field));
- bool val = source.getBooleanResult(field);
- * (bool *) (builder.getSelf() + offset) = val;
- offset += sizeof(bool);
- return offset;
- }
- size32_t RtlBoolTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- builder.ensureCapacity(sizeof(bool)+offset, queryName(field));
- * (bool *) (builder.getSelf() + offset) = val != 0;
- offset += sizeof(bool);
- return offset;
- }
- size32_t RtlBoolTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- return buildInt(builder, offset, field, rtlStrToBool(len, value));
- }
- size32_t RtlBoolTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildInt(builder, offset, field, rtlStrToBool(size, value));
- }
- size32_t RtlBoolTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- target.processBool(*(const bool *)self, field);
- return sizeof(bool);
- }
- size32_t RtlBoolTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- target.outputBool(*(const bool *)self, queryScalarXPath(field));
- return sizeof(bool);
- }
- void RtlBoolTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const bool * cast = static_cast<const bool *>(ptr);
- rtlBoolToStrX(resultLen, result, *cast);
- }
- void RtlBoolTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlBoolTypeInfo::getInt(const void * ptr) const
- {
- const bool * cast = static_cast<const bool *>(ptr);
- return (__int64)*cast;
- }
- bool RtlBoolTypeInfo::getBool(const void * ptr) const
- {
- const bool * cast = static_cast<const bool *>(ptr);
- return *cast;
- }
- int RtlBoolTypeInfo::compare(const byte * left, const byte * right) const
- {
- bool leftValue = getBool(left);
- bool rightValue = getBool (right);
- return (!leftValue && rightValue) ? -1 : (leftValue && !rightValue) ? +1 : 0;
- }
- unsigned RtlBoolTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- __int64 val = getInt(self);
- return rtlHash32Data8(&val, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- double RtlRealTypeInfo::value(const void * self) const
- {
- if (length == 4)
- return *(const float *)self;
- return *(const double *)self;
- }
- size32_t RtlRealTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- double val = source.getRealResult(field);
- return buildReal(builder, offset, field, val);
- }
- size32_t RtlRealTypeInfo::buildReal(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, double val) const
- {
- byte *dest = builder.getSelf() + offset;
- if (length == 4)
- *(float *) dest = (float) val;
- else
- *(double *) dest = val;
- offset += length;
- return offset;
- }
- size32_t RtlRealTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- return buildReal(builder, offset, field, rtlStrToReal(len, value));
- }
- size32_t RtlRealTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildReal(builder, offset, field, rtlStrToReal(size, value));
- }
- size32_t RtlRealTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- target.processReal(value(self), field);
- return length;
- }
- size32_t RtlRealTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- target.outputReal(value(self), queryScalarXPath(field));
- return length;
- }
- void RtlRealTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- double num = value(ptr);
- rtlRealToStrX(resultLen, result, num);
- }
- void RtlRealTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlRealTypeInfo::getInt(const void * ptr) const
- {
- double num = value(ptr);
- return (__int64)num;
- }
- double RtlRealTypeInfo::getReal(const void * ptr) const
- {
- return value(ptr);
- }
- int RtlRealTypeInfo::compare(const byte * left, const byte * right) const
- {
- double leftValue = getReal(left);
- double rightValue = getReal(right);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- unsigned RtlRealTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- double val = getReal(self);
- return rtlHash32Data8(&val, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
- rtlWriteInt(builder.getSelf() + offset, val, length);
- offset += length;
- return offset;
- }
- size32_t RtlIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- rtlWriteInt(builder.getSelf() + offset, val, length);
- offset += length;
- return offset;
- }
- size32_t RtlIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isUnsigned())
- target.processUInt(rtlReadUInt(self, length), field);
- else
- target.processInt(rtlReadInt(self, length), field);
- return length;
- }
- size32_t RtlIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- if (isUnsigned())
- target.outputUInt(rtlReadUInt(self, length), length, queryScalarXPath(field));
- else
- target.outputInt(rtlReadInt(self, length), length, queryScalarXPath(field));
- return length;
- }
- void RtlIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isUnsigned())
- rtlUInt8ToStrX(resultLen, result, rtlReadUInt(ptr, length));
- else
- rtlInt8ToStrX(resultLen, result, rtlReadInt(ptr, length));
- }
- void RtlIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlIntTypeInfo::getInt(const void * ptr) const
- {
- if (isUnsigned())
- return rtlReadUInt(ptr, length);
- else
- return rtlReadInt(ptr, length);
- }
- double RtlIntTypeInfo::getReal(const void * ptr) const
- {
- if (isUnsigned())
- return (double) rtlReadUInt(ptr, length);
- else
- return (double) rtlReadInt(ptr, length);
- }
- int RtlIntTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isUnsigned())
- {
- unsigned __int64 leftValue = rtlReadUInt(left, length);
- unsigned __int64 rightValue = rtlReadUInt(right, length);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- else
- {
- __int64 leftValue = rtlReadInt(left, length);
- __int64 rightValue = rtlReadInt(right, length);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- }
- bool RtlIntTypeInfo::canMemCmp() const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- return false;
- #else
- return isUnsigned();
- #endif
- }
- unsigned RtlIntTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- __int64 val = getInt(self);
- return rtlHash32Data8(&val, inhash);
- }
- bool RtlIntTypeInfo::canTruncate() const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- return true;
- #else
- return false;
- #endif
- }
- bool RtlIntTypeInfo::canExtend(char &fillChar) const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- fillChar = 0;
- return true;
- #else
- return false;
- #endif
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlBlobTypeInfo::getMinSize() const
- {
- return sizeof(offset_t);
- }
- size32_t RtlBlobTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- throwUnexpected(); // This is only expected to be used for reading at present
- }
- size32_t RtlBlobTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- throwUnexpected(); // This is only expected to be used for reading at present
- }
- size32_t RtlBlobTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- throwUnexpected(); // This is only expected to be used for reading at present
- }
- size32_t RtlBlobTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- throwUnexpected(); // This is only expected to be used for reading at present
- }
- size32_t RtlBlobTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- assertex(callback);
- UNIMPLEMENTED;
- }
- size32_t RtlBlobTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- assertex(callback);
- UNIMPLEMENTED;
- }
- void RtlBlobTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- assertex(callback);
- UNIMPLEMENTED;
- }
- void RtlBlobTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- UNIMPLEMENTED;
- }
- __int64 RtlBlobTypeInfo::getInt(const void * ptr) const
- {
- UNIMPLEMENTED;
- }
- double RtlBlobTypeInfo::getReal(const void * ptr) const
- {
- UNIMPLEMENTED;
- }
- bool RtlBlobTypeInfo::canTruncate() const
- {
- return false;
- }
- bool RtlBlobTypeInfo::canExtend(char &fillChar) const
- {
- return false;
- }
- void RtlBlobTypeInfo::setCallback(IThorIndexCallback *_callback)
- {
- callback = _callback;
- }
- int RtlBlobTypeInfo::compare(const byte * left, const byte * right) const
- {
- UNIMPLEMENTED;
- }
- unsigned RtlBlobTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- UNIMPLEMENTED;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlSwapIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
- // 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
- rtlWriteSwapInt(builder.getSelf() + offset, val, length);
- offset += length;
- return offset;
- }
- size32_t RtlSwapIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- rtlWriteSwapInt(builder.getSelf() + offset, val, length);
- offset += length;
- return offset;
- }
- size32_t RtlSwapIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlSwapIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlSwapIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isUnsigned())
- target.processUInt(rtlReadSwapUInt(self, length), field);
- else
- target.processInt(rtlReadSwapInt(self, length), field);
- return length;
- }
- size32_t RtlSwapIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- if (isUnsigned())
- target.outputUInt(rtlReadSwapUInt(self, length), length, queryScalarXPath(field));
- else
- target.outputInt(rtlReadSwapInt(self, length), length, queryScalarXPath(field));
- return length;
- }
- void RtlSwapIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isUnsigned())
- rtlUInt8ToStrX(resultLen, result, rtlReadSwapUInt(ptr, length));
- else
- rtlInt8ToStrX(resultLen, result, rtlReadSwapInt(ptr, length));
- }
- void RtlSwapIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlSwapIntTypeInfo::getInt(const void * ptr) const
- {
- if (isUnsigned())
- return rtlReadSwapUInt(ptr, length);
- else
- return rtlReadSwapInt(ptr, length);
- }
- double RtlSwapIntTypeInfo::getReal(const void * ptr) const
- {
- if (isUnsigned())
- return (double) rtlReadSwapUInt(ptr, length);
- else
- return (double) (rtlReadSwapInt(ptr, length));
- }
- int RtlSwapIntTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isUnsigned())
- {
- unsigned __int64 leftValue = rtlReadSwapUInt(left, length);
- unsigned __int64 rightValue = rtlReadSwapUInt(right, length);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- else
- {
- __int64 leftValue = rtlReadSwapInt(left, length);
- __int64 rightValue = rtlReadSwapInt(right, length);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- }
- bool RtlSwapIntTypeInfo::canMemCmp() const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- return isUnsigned();
- #else
- return false;
- #endif
- }
- unsigned RtlSwapIntTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- __int64 val = getInt(self);
- return rtlHash32Data8(&val, inhash);
- }
- bool RtlSwapIntTypeInfo::canTruncate() const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- return false;
- #else
- return true;
- #endif
- }
- bool RtlSwapIntTypeInfo::canExtend(char &fillChar) const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- return false;
- #else
- fillChar = 0;
- return true;
- #endif
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlKeyedIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- __int64 val = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
- return buildInt(builder, offset, field, val);
- }
- size32_t RtlKeyedIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- if (isUnsigned())
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- rtlWriteSwapInt(builder.getSelf() + offset, val, length);
- #else
- rtlWriteInt(builder.getSelf() + offset, val, length);
- #endif
- else
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- rtlWriteSwapInt(builder.getSelf() + offset, addBias(val, length), length);
- #else
- rtlWriteInt(builder.getSelf() + offset, addBias(val, length), length);
- #endif
- offset += length;
- return offset;
- }
- size32_t RtlKeyedIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlKeyedIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlKeyedIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isUnsigned())
- target.processUInt(getUInt(self), field);
- else
- target.processInt(getInt(self), field);
- return length;
- }
- size32_t RtlKeyedIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- if (isUnsigned())
- target.outputUInt(getUInt(self), length, queryScalarXPath(field));
- else
- target.outputInt(getInt(self), length, queryScalarXPath(field));
- return length;
- }
- void RtlKeyedIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isUnsigned())
- rtlUInt8ToStrX(resultLen, result, getUInt(ptr));
- else
- rtlInt8ToStrX(resultLen, result, getInt(ptr));
- }
- void RtlKeyedIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlKeyedIntTypeInfo::getInt(const void * ptr) const
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- if (isUnsigned())
- return rtlReadSwapUInt(ptr, length);
- else
- return removeBias(rtlReadSwapUInt(ptr, length), length);
- #else
- if (isUnsigned())
- return rtlReadUInt(ptr, length);
- else
- return removeBias(rtlReadInt(ptr, length), length);
- #endif
- }
- double RtlKeyedIntTypeInfo::getReal(const void * ptr) const
- {
- if (isUnsigned())
- return (double) getUInt(ptr);
- else
- return (double) getInt(ptr);
- }
- int RtlKeyedIntTypeInfo::compare(const byte * left, const byte * right) const
- {
- // The whole point of biased ints is that we can do this:
- return memcmp(left, right, length);
- }
- unsigned RtlKeyedIntTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- __int64 val = getInt(self);
- return rtlHash32Data8(&val, inhash);
- }
- unsigned __int64 RtlKeyedIntTypeInfo::addBias(__int64 value, unsigned length)
- {
- return value + ((unsigned __int64)1 << (length*8-1));
- }
- __int64 RtlKeyedIntTypeInfo::removeBias(unsigned __int64 value, unsigned length)
- {
- return value - ((unsigned __int64)1 << (length*8-1));
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlPackedIntTypeInfo::getMinSize() const
- {
- return 1;
- }
- size32_t RtlPackedIntTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- return rtlGetPackedSize(self);
- }
- size32_t RtlPackedIntTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- __int64 value = isUnsigned() ? (__int64) source.getUnsignedResult(field) : source.getSignedResult(field);
- return buildInt(builder, offset, field, value);
- }
- size32_t RtlPackedIntTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- size32_t sizeInBytes = rtlGetPackedSize(&val);
- builder.ensureCapacity(sizeInBytes+offset, queryName(field));
- rtlSetPackedUnsigned(builder.getSelf() + offset, val);
- offset += sizeInBytes;
- return offset;
- }
- size32_t RtlPackedIntTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlPackedIntTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlPackedIntTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isUnsigned())
- target.processUInt(rtlGetPackedUnsigned(self), field);
- else
- target.processInt(rtlGetPackedSigned(self), field);
- return rtlGetPackedSize(self);
- }
- size32_t RtlPackedIntTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- size32_t fieldsize = rtlGetPackedSize(self);
- if (isUnsigned())
- target.outputUInt(rtlGetPackedUnsigned(self), fieldsize, queryScalarXPath(field));
- else
- target.outputInt(rtlGetPackedSigned(self), fieldsize, queryScalarXPath(field));
- return fieldsize;
- }
- size32_t RtlPackedIntTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- char temp[9];
- size32_t size = in.readPackedInt(temp);
- byte * dest = builder.ensureCapacity(offset + size, nullptr) + offset;
- memcpy(dest, temp, size);
- return offset + size;
- }
- void RtlPackedIntTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- in.skipPackedInt();
- }
- void RtlPackedIntTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isUnsigned())
- rtlUInt8ToStrX(resultLen, result, rtlGetPackedUnsigned(ptr));
- else
- rtlInt8ToStrX(resultLen, result, rtlGetPackedSigned(ptr));
- }
- void RtlPackedIntTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlPackedIntTypeInfo::getInt(const void * ptr) const
- {
- if (isUnsigned())
- return rtlGetPackedUnsigned(ptr);
- else
- return rtlGetPackedSigned(ptr);
- }
- double RtlPackedIntTypeInfo::getReal(const void * ptr) const
- {
- if (isUnsigned())
- return (double) rtlGetPackedUnsigned(ptr);
- else
- return (double) rtlGetPackedSigned(ptr);
- }
- int RtlPackedIntTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isUnsigned())
- {
- unsigned __int64 leftValue = rtlGetPackedUnsigned(left);
- unsigned __int64 rightValue = rtlGetPackedUnsigned(right);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- else
- {
- __int64 leftValue = rtlGetPackedSigned(left);
- __int64 rightValue = rtlGetPackedSigned(right);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- }
- unsigned RtlPackedIntTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- __int64 val = getInt(self);
- return rtlHash32Data8(&val, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlStringTypeInfo::getMinSize() const
- {
- if (isFixedSize())
- return length;
- return sizeof(size32_t);
- }
- size32_t RtlStringTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isFixedSize())
- return length;
- return sizeof(size32_t) + rtlReadSize32t(self);
- }
- size32_t RtlStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t size;
- rtlDataAttr value;
- source.getStringResult(field, size, value.refstr());
- return buildString(builder, offset, field, size, value.getstr());
- }
- size32_t RtlStringTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- if (!isFixedSize())
- {
- builder.ensureCapacity(offset+size+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteInt4(dest, size);
- // 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
- // In order to be symmetrical with the passing of ecl data to a IFieldProcessor the former interpretation is preferred.
- // Expecting source.getStringResult to somehow "know" that EBCDIC was expected seems odd.
- if (isEbcdic())
- rtlStrToEStr(size, (char *) dest+sizeof(size32_t), size, (char *)value);
- else
- memcpy(dest+sizeof(size32_t), value, size);
- offset += size+sizeof(size32_t);
- }
- else
- {
- builder.ensureCapacity(offset+length, queryName(field));
- byte *dest = builder.getSelf()+offset;
- if (isEbcdic())
- rtlStrToEStr(length, (char *) dest, size, (char *) value);
- else
- rtlStrToStr(length, dest, size, value);
- offset += length;
- }
- return offset;
- }
- size32_t RtlStringTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
- {
- if (isEbcdic())
- return buildUtf8ViaString(builder, offset, field, codepoints, value);
- if (!isFixedSize())
- {
- builder.ensureCapacity(offset+codepoints+sizeof(size32_t), queryName(field));
- char *dest = (char *) builder.getSelf()+offset;
- rtlWriteInt4(dest, codepoints);
- rtlUtf8ToStr(codepoints, dest+sizeof(size32_t), codepoints, value);
- offset += codepoints+sizeof(size32_t);
- }
- else
- {
- builder.ensureCapacity(offset+length, queryName(field));
- char *dest = (char *) builder.getSelf()+offset;
- rtlUtf8ToStr(length, dest, codepoints, value);
- offset += length;
- }
- return offset;
- }
- size32_t RtlStringTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
- {
- if (field->initializer || !isFixedSize())
- return RtlTypeInfoBase::buildNull(builder, offset, field);
- else
- {
- builder.ensureCapacity(offset+length, queryName(field));
- memset(builder.getSelf()+offset, isEbcdic() ? 0x40 : ' ', length);
- return offset + length;
- }
- }
- size32_t RtlStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = thisLength;
- }
- else
- {
- str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + thisLength;
- }
- if (isEbcdic())
- {
- unsigned lenAscii;
- rtlDataAttr ascii;
- rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
- target.processString(lenAscii, ascii.getstr(), field);
- }
- else
- {
- target.processString(thisLength, str, field);
- }
- return thisSize;
- }
- size32_t RtlStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = thisLength;
- }
- else
- {
- str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + thisLength;
- }
- if (isEbcdic())
- {
- unsigned lenAscii;
- rtlDataAttr ascii;
- rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
- target.outputString(lenAscii, ascii.getstr(), queryScalarXPath(field));
- }
- else
- {
- target.outputString(thisLength, str, queryScalarXPath(field));
- }
- return thisSize;
- }
- size32_t RtlStringTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isFixedSize())
- {
- size32_t size = length;
- byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
- in.read(size, dest);
- offset += size;
- }
- else
- {
- size32_t size = in.readSize();
- byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
- rtlWriteSize32t(dest, size);
- in.read(size, dest + sizeof(size32_t));
- offset += sizeof(size32_t)+size;
- }
- return offset;
- }
- void RtlStringTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- if (isFixedSize())
- {
- in.skip(length);
- }
- else
- {
- size32_t thisLength = in.readSize();
- in.skip(thisLength);
- }
- }
- void RtlStringTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- if (isEbcdic())
- return rtlEStrToStrX(resultLen, result, length, (const char *)ptr);
- else
- return rtlStrToStrX(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- if (isEbcdic())
- return rtlEStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- else
- return rtlStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- void RtlStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isEbcdic())
- {
- getUtf8ViaString(resultLen, result, ptr);
- return;
- }
- if (isFixedSize())
- {
- return rtlStrToUtf8X(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- return rtlStrToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- __int64 RtlStringTypeInfo::getInt(const void * ptr) const
- {
- //Utf8 output is the same as string output, so avoid the intermediate translation
- if (isFixedSize())
- return rtlStrToInt8(length, (const char *)ptr);
- size32_t len = rtlReadSize32t(ptr);
- return rtlStrToInt8(len, (const char *)ptr + sizeof(size32_t));
- }
- int RtlStringTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isFixedSize())
- return memcmp(left, right, length);
- else if (isEbcdic())
- {
- // Logically this should be
- // if (isFixedSize())
- // return rtlCompareEStrEStr(length, (const char *)left, length, (const char *)right);
- // but that's the same as a memcmp if lengths match
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- return rtlCompareEStrEStr(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
- }
- else
- {
- // Logically this should be
- // if (isFixedSize())
- // return rtlCompareStrStr(length, (const char *)left, length, (const char *)right); // Actually this is a memcmp
- // but that's the same as a memcmp if lengths match
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- return rtlCompareStrStr(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
- }
- }
- bool RtlStringTypeInfo::canMemCmp() const
- {
- return isFixedSize();
- }
- unsigned RtlStringTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- size32_t len;
- if (isFixedSize())
- len = length;
- else
- {
- len = rtlReadSize32t(self);
- self += sizeof(size32_t);
- }
- return rtlHash32Data(rtlTrimStrLen(len, (const char *) self), self, inhash);
- }
- bool RtlStringTypeInfo::canExtend(char &fillChar) const
- {
- if (isFixedSize())
- {
- fillChar = isEbcdic() ? 0x40 : ' ';
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlDataTypeInfo::getMinSize() const
- {
- if (isFixedSize())
- return length;
- return sizeof(size32_t);
- }
- size32_t RtlDataTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isFixedSize())
- return length;
- return sizeof(size32_t) + rtlReadSize32t(self);
- }
- size32_t RtlDataTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t size;
- rtlDataAttr value;
- source.getDataResult(field, size, value.refdata());
- return buildString(builder, offset, field, size, value.getstr());
- }
- size32_t RtlDataTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- if (!isFixedSize())
- {
- builder.ensureCapacity(offset+size+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteInt4(dest, size);
- memcpy(dest+sizeof(size32_t), value, size);
- offset += size+sizeof(size32_t);
- }
- else
- {
- builder.ensureCapacity(offset+length, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlDataToData(length, dest, size, value);
- offset += length;
- }
- return offset;
- }
- size32_t RtlDataTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
- {
- return buildUtf8ViaString(builder, offset, field, codepoints, value);
- }
- size32_t RtlDataTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = thisLength;
- }
- else
- {
- str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + thisLength;
- }
- target.processData(thisLength, str, field);
- return thisSize;
- }
- size32_t RtlDataTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = thisLength;
- }
- else
- {
- str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + thisLength;
- }
- target.outputData(thisLength, str, queryScalarXPath(field));
- return thisSize;
- }
- size32_t RtlDataTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isFixedSize())
- {
- size32_t size = length;
- byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
- in.read(size, dest);
- offset += size;
- }
- else
- {
- size32_t size = in.readSize();
- byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
- rtlWriteSize32t(dest, size);
- in.read(size, dest + sizeof(size32_t));
- offset += sizeof(size32_t)+size;
- }
- return offset;
- }
- void RtlDataTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- if (isFixedSize())
- {
- in.skip(length);
- }
- else
- {
- size32_t thisLength = in.readSize();
- in.skip(thisLength);
- }
- }
- void RtlDataTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- return rtlStrToStrX(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- return rtlStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- void RtlDataTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- return rtlStrToUtf8X(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- return rtlStrToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- __int64 RtlDataTypeInfo::getInt(const void * ptr) const
- {
- //Utf8 output is the same as string output, so avoid the intermediate translation
- if (isFixedSize())
- return rtlStrToInt8(length, (const char *)ptr);
- size32_t len = rtlReadSize32t(ptr);
- return rtlStrToInt8(len, (const char *)ptr + sizeof(size32_t));
- }
- int RtlDataTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isFixedSize())
- // Logically this should be return rtlCompareDataData(length, (const char *)left, length, (const char *)right);
- // but that acts as a memcmp if lengths match
- return memcmp(left, right, length);
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- return rtlCompareDataData(lenLeft, (const char *)left + sizeof(size32_t), lenRight, (const char *)right + sizeof(size32_t));
- }
- bool RtlDataTypeInfo::canMemCmp() const
- {
- return isFixedSize();
- }
- unsigned RtlDataTypeInfo::hash(const byte *self, unsigned inhash) const
- {
- size32_t len;
- if (isFixedSize())
- len = length;
- else
- {
- len = rtlReadSize32t(self);
- self += sizeof(size32_t);
- }
- return rtlHash32Data(len, self, inhash);
- }
- bool RtlDataTypeInfo::canExtend(char &fillChar) const
- {
- if (isFixedSize())
- {
- fillChar = 0;
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlVarStringTypeInfo::getMinSize() const
- {
- if (isFixedSize())
- return length+1;
- return 1;
- }
- size32_t RtlVarStringTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isFixedSize())
- return length + 1;
- const char * str = reinterpret_cast<const char *>(self);
- return (size32_t)strlen(str)+1;
- }
- size32_t RtlVarStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t size;
- rtlDataAttr value;
- source.getStringResult(field, size, value.refstr());
- return buildString(builder, offset, field, size, value.getstr());
- }
- size32_t RtlVarStringTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- if (!isFixedSize())
- {
- builder.ensureCapacity(offset+size+1, queryName(field));
- // See notes re EBCDIC conversion in RtlStringTypeInfo code
- byte *dest = builder.getSelf()+offset;
- if (isEbcdic())
- rtlStrToEStr(size, (char *) dest, size, (char *)value);
- else
- memcpy(dest, value, size);
- dest[size] = '\0';
- offset += size+1;
- }
- else
- {
- builder.ensureCapacity(offset+length+1, queryName(field));
- byte *dest = builder.getSelf()+offset;
- if (isEbcdic())
- rtlEStrToVStr(length+1, dest, size, value);
- else
- rtlStrToVStr(length+1, dest, size, value);
- offset += length+1;
- }
- return offset;
- }
- size32_t RtlVarStringTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
- {
- return buildUtf8ViaString(builder, offset, field, codepoints, value);
- }
- size32_t RtlVarStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength = (size32_t)strlen(str);
- unsigned thisSize;
- if (isFixedSize())
- thisSize = length+1;
- else
- thisSize = thisLength+1;
- if (isEbcdic())
- {
- unsigned lenAscii;
- rtlDataAttr ascii;
- rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
- target.processString(lenAscii, ascii.getstr(), field);
- }
- else
- target.processString(thisLength, str, field);
- return thisSize;
- }
- size32_t RtlVarStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength = (size32_t)strlen(str);
- unsigned thisSize;
- if (isFixedSize())
- thisSize = length+1;
- else
- thisSize = thisLength+1;
- if (isEbcdic())
- {
- unsigned lenAscii;
- rtlDataAttr ascii;
- rtlEStrToStrX(lenAscii, ascii.refstr(), thisLength, str);
- target.outputString(lenAscii, ascii.getstr(), queryScalarXPath(field));
- }
- else
- target.outputString(thisLength, str, queryScalarXPath(field));
- return thisSize;
- }
- size32_t RtlVarStringTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isFixedSize())
- {
- size32_t size = length+1;
- byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
- in.read(size, dest);
- return offset + size;
- }
- else
- return offset + in.readVStr(builder, offset, 0);
- }
- void RtlVarStringTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- if (isFixedSize())
- {
- in.skip(length+1);
- }
- else
- {
- in.skipVStr();
- }
- }
- void RtlVarStringTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const char * str = (const char *)ptr;
- return rtlStrToStrX(resultLen, result, strlen(str), str);
- }
- void RtlVarStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const char * str = (const char *)ptr;
- return rtlStrToUtf8X(resultLen, result, strlen(str), str);
- }
- __int64 RtlVarStringTypeInfo::getInt(const void * ptr) const
- {
- const char * str = (const char *)ptr;
- return rtlVStrToInt8(str);
- }
- int RtlVarStringTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isEbcdic())
- {
- const char * leftValue = (const char *)left;
- const char * rightValue = (const char *)right;
- return rtlCompareEStrEStr(strlen(leftValue), leftValue, strlen(rightValue), rightValue);
- }
- return rtlCompareVStrVStr((const char *)left, (const char *)right);
- }
- unsigned RtlVarStringTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- return rtlHash32VStr((const char *) self, inhash);
- }
- bool RtlVarStringTypeInfo::canExtend(char &fillChar) const
- {
- if (isFixedSize())
- {
- fillChar = 0;
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlQStringTypeInfo::getMinSize() const
- {
- if (isFixedSize())
- return rtlQStrSize(length);
- return sizeof(size32_t);
- }
- size32_t RtlQStringTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isFixedSize())
- return rtlQStrSize(length);
- return sizeof(size32_t) + rtlQStrSize(rtlReadSize32t(self));
- }
- size32_t RtlQStringTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t size;
- rtlDataAttr value;
- source.getStringResult(field, size, value.refstr());
- return buildString(builder, offset, field, size, value.getstr());
- }
- size32_t RtlQStringTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- if (!isFixedSize())
- {
- size32_t sizeInBytes = rtlQStrSize(size) + sizeof(size32_t);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteInt4(dest, size);
- rtlStrToQStr(size, (char *) dest+sizeof(size32_t), size, value);
- offset += sizeInBytes;
- }
- else
- {
- size32_t sizeInBytes = rtlQStrSize(length);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlStrToQStr(length, (char *) dest, size, value);
- offset += sizeInBytes;
- }
- return offset;
- }
- size32_t RtlQStringTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t codepoints, const char *value) const
- {
- return buildUtf8ViaString(builder, offset, field, codepoints, value);
- }
- size32_t RtlQStringTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = rtlQStrSize(thisLength);
- }
- else
- {
- str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + rtlQStrSize(thisLength);
- }
- target.processQString(thisLength, str, field);
- return thisSize;
- }
- size32_t RtlQStringTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = rtlQStrSize(thisLength);
- }
- else
- {
- str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + rtlQStrSize(thisLength);
- }
- target.outputQString(thisLength, str, queryScalarXPath(field));
- return thisSize;
- }
- size32_t RtlQStringTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isFixedSize())
- {
- size32_t size = rtlQStrSize(length);
- byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
- in.read(size, dest);
- offset += size;
- }
- else
- {
- size32_t thisLength = in.readSize();
- size32_t size = rtlQStrSize(thisLength);
- byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
- rtlWriteSize32t(dest, thisLength);
- in.read(size, dest + sizeof(size32_t));
- offset += sizeof(size32_t)+size;
- }
- return offset;
- }
- void RtlQStringTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- if (isFixedSize())
- {
- size32_t size = rtlQStrSize(length);
- in.skip(size);
- }
- else
- {
- size32_t thisLength = in.readSize();
- size32_t size = rtlQStrSize(thisLength);
- in.skip(size);
- }
- }
- void RtlQStringTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- return rtlQStrToStrX(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- return rtlQStrToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- void RtlQStringTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- //NOTE: QStrings cannot contain non-string characters, so converting to str is the same as utf8
- getString(resultLen, result, ptr);
- }
- __int64 RtlQStringTypeInfo::getInt(const void * ptr) const
- {
- size32_t lenTemp;
- rtlDataAttr temp;
- getUtf8(lenTemp, temp.refstr(), ptr);
- return rtlStrToInt8(lenTemp, temp.getstr());
- }
- int RtlQStringTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isFixedSize())
- // Logically this should be return rtlCompareQStrQStr(length, left, length, right);
- // but that acts as a memcmp if lengths match
- return memcmp(left, right, length);
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- return rtlCompareQStrQStr(lenLeft, left + sizeof(size32_t), lenRight, right + sizeof(size32_t));
- }
- bool RtlQStringTypeInfo::canMemCmp() const
- {
- return isFixedSize();
- }
- unsigned RtlQStringTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- rtlDataAttr val;
- unsigned len;
- getString(len, val.refstr(), self);
- return rtlHash32Data(rtlTrimStrLen(len, val.getstr()), val.getstr(), inhash);
- }
- bool RtlQStringTypeInfo::canExtend(char &fillChar) const
- {
- if (isFixedSize())
- {
- fillChar = 0;
- return true;
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlDecimalTypeInfo::calcSize() const
- {
- if (isUnsigned())
- return (getDecimalDigits()+1)/2;
- return (getDecimalDigits()+2)/2;
- }
- size32_t RtlDecimalTypeInfo::getMinSize() const
- {
- return calcSize();
- }
- size32_t RtlDecimalTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- return calcSize();
- }
- size32_t RtlDecimalTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- Decimal value;
- source.getDecimalResult(field, value);
- size32_t sizeInBytes = calcSize();
- builder.ensureCapacity(sizeInBytes+offset, queryName(field));
- if (isUnsigned())
- value.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
- else
- value.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
- offset += sizeInBytes;
- return offset;
- }
- size32_t RtlDecimalTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
- {
- if (field->initializer)
- return RtlTypeInfoBase::buildNull(builder, offset, field);
- Decimal value;
- size32_t sizeInBytes = calcSize();
- builder.ensureCapacity(sizeInBytes+offset, queryName(field));
- if (isUnsigned())
- value.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
- else
- value.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
- offset += sizeInBytes;
- return offset;
- }
- size32_t RtlDecimalTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- Decimal dvalue;
- dvalue.setString(len, value);
- size32_t sizeInBytes = calcSize();
- builder.ensureCapacity(sizeInBytes+offset, queryName(field));
- if (isUnsigned())
- dvalue.getUDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
- else
- dvalue.getDecimal(sizeInBytes, getDecimalPrecision(), builder.getSelf()+offset);
- offset += sizeInBytes;
- return offset;
- }
- size32_t RtlDecimalTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildString(builder, offset, field, size, value);
- }
- size32_t RtlDecimalTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- size32_t thisSize = calcSize();
- if (isUnsigned())
- target.processUDecimal(self, thisSize, getDecimalPrecision(), field);
- else
- target.processDecimal(self, thisSize, getDecimalPrecision(), field);
- return thisSize;
- }
- size32_t RtlDecimalTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- size32_t thisSize = calcSize();
- if (isUnsigned())
- target.outputUDecimal(self, thisSize, getDecimalPrecision(), queryScalarXPath(field));
- else
- target.outputDecimal(self, thisSize, getDecimalPrecision(), queryScalarXPath(field));
- return thisSize;
- }
- void RtlDecimalTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- Decimal temp;
- size32_t sizeInBytes = calcSize();
- if (isUnsigned())
- temp.setUDecimal(sizeInBytes, getDecimalPrecision(), ptr);
- else
- temp.setDecimal(sizeInBytes, getDecimalPrecision(), ptr);
- temp.getStringX(resultLen, result);
- }
- void RtlDecimalTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlDecimalTypeInfo::getInt(const void * ptr) const
- {
- Decimal temp;
- size32_t sizeInBytes = calcSize();
- if (isUnsigned())
- temp.setUDecimal(sizeInBytes, getDecimalPrecision(), ptr);
- else
- temp.setDecimal(sizeInBytes, getDecimalPrecision(), ptr);
- return temp.getInt64();
- }
- double RtlDecimalTypeInfo::getReal(const void * ptr) const
- {
- Decimal temp;
- size32_t sizeInBytes = calcSize();
- if (isUnsigned())
- temp.setUDecimal(sizeInBytes, getDecimalPrecision(), ptr);
- else
- temp.setDecimal(sizeInBytes, getDecimalPrecision(), ptr);
- return temp.getReal();
- }
- int RtlDecimalTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isUnsigned())
- return decCompareUDecimal(calcSize(), left, right);
- else
- return decCompareDecimal(calcSize(), left, right);
- }
- unsigned RtlDecimalTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- return rtlHash32Data(calcSize(), self, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlCharTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- throwUnexpected(); // Can't have a field of type char
- }
- size32_t RtlCharTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- rtlFailUnexpected();
- }
- size32_t RtlCharTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- return buildUtf8ViaString(builder, offset, field, len, value);
- }
- size32_t RtlCharTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- char c;
- if (isEbcdic())
- rtlEStrToStr(1, &c, 1, str);
- else
- c = *str;
- target.processString(1, &c, field);
- return 1;
- }
- size32_t RtlCharTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const char * str = reinterpret_cast<const char *>(self);
- char c;
- if (isEbcdic())
- rtlEStrToStr(1, &c, 1, str);
- else
- c = *str;
- target.outputString(1, &c, queryScalarXPath(field));
- return 1;
- }
- void RtlCharTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const char * str = (const char *)ptr;
- return rtlStrToStrX(resultLen, result, 1, str);
- }
- void RtlCharTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const char * str = (const char *)ptr;
- return rtlStrToUtf8X(resultLen, result, 1, str);
- }
- __int64 RtlCharTypeInfo::getInt(const void * ptr) const
- {
- const char * str = (const char *)ptr;
- return rtlStrToInt8(1, str);
- }
- int RtlCharTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isEbcdic())
- return rtlCompareEStrEStr(1, (const char *)left, 1, (const char *)right);
- else
- return rtlCompareStrStr(1, (const char *)left, 1, (const char *)right);
- }
- unsigned RtlCharTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- return rtlHash32Data(1, self, inhash); // MORE - should we trim?
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlUnicodeTypeInfo::getMinSize() const
- {
- if (isFixedSize())
- return length * sizeof(UChar);
- return sizeof(size32_t);
- }
- size32_t RtlUnicodeTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isFixedSize())
- return length * sizeof(UChar);
- return sizeof(size32_t) + rtlReadSize32t(self) * sizeof(UChar);
- }
- size32_t RtlUnicodeTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t sizeInChars;
- UChar *value;
- source.getUnicodeResult(field, sizeInChars, value);
- if (!isFixedSize())
- {
- size32_t sizeInBytes = sizeInChars * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteInt4(dest, sizeInChars); // NOTE - in chars!
- memcpy(dest+sizeof(size32_t), value, sizeInBytes);
- offset += sizeInBytes+sizeof(size32_t);
- }
- else
- {
- size32_t sizeInBytes = length * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlUnicodeToUnicode(length, (UChar *) dest, sizeInChars, value);
- offset += sizeInBytes;
- }
- rtlFree(value);
- return offset;
- }
- size32_t RtlUnicodeTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
- {
- if (field->initializer || !isFixedSize())
- return RtlTypeInfoBase::buildNull(builder, offset, field);
- else
- {
- size32_t sizeInBytes = length * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlUnicodeToUnicode(length, (UChar *) dest, 0, nullptr);
- return offset + sizeInBytes;
- }
- }
- size32_t RtlUnicodeTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
- {
- if (!isFixedSize())
- {
- size32_t sizeInBytes = sizeInChars * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteInt4(dest, sizeInChars); // NOTE - in chars!
- rtlUtf8ToUnicode(sizeInChars, (UChar *) (dest+sizeof(size32_t)), sizeInChars, value);
- offset += sizeInBytes+sizeof(size32_t);
- }
- else
- {
- size32_t sizeInBytes = length * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlUtf8ToUnicode(length, (UChar *) dest, sizeInChars, value);
- offset += sizeInBytes;
- }
- return offset;
- }
- size32_t RtlUnicodeTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
- {
- if (!isFixedSize())
- {
- size32_t sizeInBytes = sizeInChars * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteSize32t(dest, sizeInChars); // NOTE - in chars!
- rtlStrToUnicode(sizeInChars, (UChar *) (dest+sizeof(size32_t)), sizeInChars, value);
- offset += sizeInBytes+sizeof(size32_t);
- }
- else
- {
- size32_t sizeInBytes = length * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlStrToUnicode(length, (UChar *) dest, sizeInChars, value);
- offset += sizeInBytes;
- }
- return offset;
- }
- size32_t RtlUnicodeTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const UChar * ustr = reinterpret_cast<const UChar *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = thisLength * sizeof(UChar);
- }
- else
- {
- ustr = reinterpret_cast<const UChar *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + thisLength * sizeof(UChar);
- }
- target.processUnicode(thisLength, ustr, field);
- return thisSize;
- }
- size32_t RtlUnicodeTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const UChar * ustr = reinterpret_cast<const UChar *>(self);
- unsigned thisLength;
- unsigned thisSize;
- if (isFixedSize())
- {
- thisLength = length;
- thisSize = thisLength * sizeof(UChar);
- }
- else
- {
- ustr = reinterpret_cast<const UChar *>(self + sizeof(size32_t));
- thisLength = rtlReadSize32t(self);
- thisSize = sizeof(size32_t) + thisLength * sizeof(UChar);
- }
- target.outputUnicode(thisLength, ustr, queryScalarXPath(field));
- return thisSize;
- }
- size32_t RtlUnicodeTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isFixedSize())
- {
- size32_t size = length * sizeof(UChar);
- byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
- in.read(size, dest);
- offset += size;
- }
- else
- {
- size32_t thisLength = in.readSize();
- size32_t size = thisLength * sizeof(UChar);
- byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
- rtlWriteSize32t(dest, thisLength);
- in.read(size, dest + sizeof(size32_t));
- offset += sizeof(size32_t)+size;
- }
- return offset;
- }
- void RtlUnicodeTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- if (isFixedSize())
- {
- size32_t size = length * sizeof(UChar);
- in.skip(size);
- }
- else
- {
- size32_t thisLength = in.readSize();
- size32_t size = thisLength * sizeof(UChar);
- in.skip(size);
- }
- }
- void RtlUnicodeTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- return rtlUnicodeToStrX(resultLen, result, length, (const UChar *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- const char * str = (const char *)ptr + sizeof(size32_t);
- return rtlUnicodeToStrX(resultLen, result, len, (const UChar *)str);
- }
- }
- void RtlUnicodeTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- return rtlUnicodeToUtf8X(resultLen, result, length, (const UChar *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- const char * str = (const char *)ptr + sizeof(size32_t);
- return rtlUnicodeToUtf8X(resultLen, result, len, (const UChar *)str);
- }
- }
- __int64 RtlUnicodeTypeInfo::getInt(const void * ptr) const
- {
- //Utf8 output is the same as string output, so avoid the intermediate translation
- if (isFixedSize())
- return rtlUnicodeToInt8(length, (const UChar *)ptr);
- size32_t len = rtlReadSize32t(ptr);
- const char * str = (const char *)ptr + sizeof(size32_t);
- return rtlUnicodeToInt8(len, (const UChar *)str);
- }
- int RtlUnicodeTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isFixedSize())
- return rtlCompareUnicodeUnicode(length, (const UChar *)left, length, (const UChar *)right, locale);
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- const UChar * valueLeft = reinterpret_cast<const UChar *>(left + sizeof(size32_t));
- const UChar * valueRight = reinterpret_cast<const UChar *>(right + sizeof(size32_t));
- return rtlCompareUnicodeUnicode(lenLeft, valueLeft, lenRight, valueRight, locale);
- }
- unsigned RtlUnicodeTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- size32_t len;
- if (isFixedSize())
- len = length;
- else
- {
- len = rtlReadSize32t(self);
- self += sizeof(size32_t);
- }
- const UChar * uself = reinterpret_cast<const UChar *>(self);
- return rtlHash32Unicode(rtlTrimUnicodeStrLen(len, uself), uself, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlVarUnicodeTypeInfo::getMinSize() const
- {
- if (isFixedSize())
- return (length+1) * sizeof(UChar);
- return sizeof(UChar);
- }
- size32_t RtlVarUnicodeTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isFixedSize())
- return (length+1) * sizeof(UChar);
- const UChar * ustr = reinterpret_cast<const UChar *>(self);
- return (rtlUnicodeStrlen(ustr)+1) * sizeof(UChar);
- }
- size32_t RtlVarUnicodeTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t sizeInChars;
- UChar *value;
- source.getUnicodeResult(field, sizeInChars, value);
- if (!isFixedSize())
- {
- size32_t sizeInBytes = (sizeInChars+1) * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- UChar *dest = (UChar *) (builder.getSelf()+offset);
- memcpy(dest, value, sizeInBytes - sizeof(UChar));
- dest[sizeInChars] = 0;
- offset += sizeInBytes;
- }
- else
- {
- size32_t sizeInBytes = (length+1) * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlUnicodeToVUnicode(length+1, (UChar *) dest, sizeInChars, value);
- offset += sizeInBytes;
- }
- rtlFree(value);
- return offset;
- }
- size32_t RtlVarUnicodeTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
- {
- size32_t usize;
- rtlDataAttr uvalue;
- rtlUtf8ToUnicodeX(usize, uvalue.refustr(), sizeInChars, value);
- if (!isFixedSize())
- {
- size32_t sizeInBytes = (usize+1) * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- UChar *dest = (UChar *) (builder.getSelf()+offset);
- memcpy(dest, uvalue.getustr(), sizeInBytes - sizeof(UChar));
- dest[usize] = 0;
- offset += sizeInBytes;
- }
- else
- {
- size32_t sizeInBytes = (length+1) * sizeof(UChar);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlUnicodeToVUnicode(length+1, (UChar *) dest, usize, uvalue.getustr());
- offset += sizeInBytes;
- }
- return offset;
- }
- size32_t RtlVarUnicodeTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
- {
- size32_t lengthTarget;
- if (!isFixedSize())
- {
- lengthTarget = (sizeInChars + 1);
- }
- else
- {
- lengthTarget = (length + 1);
- }
- size32_t sizeTarget = lengthTarget * sizeof(UChar);
- builder.ensureCapacity(offset+sizeTarget, queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlStrToVUnicode(lengthTarget, (UChar *) dest, sizeInChars, value);
- offset += sizeTarget;
- return offset;
- }
- size32_t RtlVarUnicodeTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- const UChar * ustr = reinterpret_cast<const UChar *>(self);
- unsigned thisLength = rtlUnicodeStrlen(ustr);
- unsigned thisSize;
- if (isFixedSize())
- thisSize = (length + 1) * sizeof(UChar);
- else
- thisSize = (thisLength + 1) * sizeof(UChar);
- target.processUnicode(thisLength, ustr, field);
- return thisSize;
- }
- size32_t RtlVarUnicodeTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const UChar * ustr = reinterpret_cast<const UChar *>(self);
- unsigned thisLength = rtlUnicodeStrlen(ustr);
- unsigned thisSize;
- if (isFixedSize())
- thisSize = (length + 1) * sizeof(UChar);
- else
- thisSize = (thisLength + 1) * sizeof(UChar);
- target.outputUnicode(thisLength, ustr, queryScalarXPath(field));
- return thisSize;
- }
- size32_t RtlVarUnicodeTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isFixedSize())
- {
- size32_t size = (length+1)*sizeof(UChar);
- byte * dest = builder.ensureCapacity(offset+size, nullptr) + offset;
- in.read(size, dest);
- return offset + size;
- }
- else
- return offset + in.readVUni(builder, offset, 0);
- }
- void RtlVarUnicodeTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- if (isFixedSize())
- {
- size32_t size = (length+1)*sizeof(UChar);
- in.skip(size);
- }
- else
- {
- in.skipVUni();
- }
- }
- void RtlVarUnicodeTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const UChar * str = (const UChar *)ptr;
- rtlUnicodeToStrX(resultLen, result, rtlUnicodeStrlen(str), str);
- }
- void RtlVarUnicodeTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- const UChar * str = (const UChar *)ptr;
- rtlUnicodeToUtf8X(resultLen, result, rtlUnicodeStrlen(str), str);
- }
- __int64 RtlVarUnicodeTypeInfo::getInt(const void * ptr) const
- {
- const UChar * str = (const UChar *)ptr;
- return rtlUnicodeToInt8(rtlUnicodeStrlen(str), str);
- }
- int RtlVarUnicodeTypeInfo::compare(const byte * left, const byte * right) const
- {
- const UChar * valueLeft = reinterpret_cast<const UChar *>(left);
- const UChar * valueRight = reinterpret_cast<const UChar *>(right);
- size32_t lenLeft = rtlUnicodeStrlen(valueLeft);
- size32_t lenRight = rtlUnicodeStrlen(valueRight);
- return rtlCompareUnicodeUnicode(lenLeft, valueLeft, lenRight, valueRight, locale);
- }
- unsigned RtlVarUnicodeTypeInfo::hash(const byte * _self, unsigned inhash) const
- {
- const UChar * self = reinterpret_cast<const UChar *>(_self);
- return rtlHash32VUnicode(self, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlUtf8TypeInfo::getMinSize() const
- {
- return sizeof(size32_t);
- }
- size32_t RtlUtf8TypeInfo::size(const byte * self, const byte * selfrow) const
- {
- assertex(!isFixedSize());
- return sizeof(size32_t) + rtlUtf8Size(rtlReadSize32t(self), self+sizeof(unsigned));
- }
- size32_t RtlUtf8TypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- size32_t sizeInChars;
- rtlDataAttr value;
- source.getUTF8Result(field, sizeInChars, value.refstr());
- return buildUtf8(builder, offset, field, sizeInChars, value.getstr());
- }
- size32_t RtlUtf8TypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
- {
- size32_t sizeInBytes = rtlUtf8Size(sizeInChars, value);
- assertex(!isFixedSize());
- builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteSize32t(dest, sizeInChars); // NOTE - in chars!
- memcpy(dest+sizeof(size32_t), value, sizeInBytes);
- return offset + sizeInBytes+sizeof(size32_t);
- }
- size32_t RtlUtf8TypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t sizeInChars, const char *value) const
- {
- assertex(!isFixedSize());
- //MORE: The target size could be precalculated - which would avoid creating a temporary
- size32_t tempLen;
- rtlDataAttr temp;
- rtlStrToUtf8X(tempLen, temp.refstr(), sizeInChars, value);
- size32_t sizeInBytes = rtlUtf8Size(tempLen, temp.getstr());
- builder.ensureCapacity(offset+sizeInBytes+sizeof(size32_t), queryName(field));
- byte *dest = builder.getSelf()+offset;
- rtlWriteSize32t(dest, sizeInChars); // NOTE - in chars!
- memcpy((dest+sizeof(size32_t)), temp.getstr(), sizeInBytes);
- return offset + sizeInBytes+sizeof(size32_t);
- }
- size32_t RtlUtf8TypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- assertex(!isFixedSize());
- const char * str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- unsigned thisLength = rtlReadSize32t(self);
- unsigned thisSize = sizeof(size32_t) + rtlUtf8Size(thisLength, str);
- target.processUtf8(thisLength, str, field);
- return thisSize;
- }
- size32_t RtlUtf8TypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- assertex(!isFixedSize());
- const char * str = reinterpret_cast<const char *>(self + sizeof(size32_t));
- unsigned thisLength = rtlReadSize32t(self);
- unsigned thisSize = sizeof(size32_t) + rtlUtf8Size(thisLength, str);
- target.outputUtf8(thisLength, str, queryScalarXPath(field));
- return thisSize;
- }
- size32_t RtlUtf8TypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- assertex(!isFixedSize());
- size32_t thisLength = in.readSize();
- size32_t size = in.readUtf8(builder, offset + sizeof(size_t), 0, thisLength);
- rtlWriteSize32t(builder.getSelf() + offset, thisLength);
- return offset + sizeof(size32_t) + size;
- }
- void RtlUtf8TypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- assertex(!isFixedSize());
- size32_t thisLength = in.readSize();
- in.skipUtf8(thisLength);
- }
- void RtlUtf8TypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- rtlUtf8ToStrX(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- rtlUtf8ToStrX(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- void RtlUtf8TypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isFixedSize())
- {
- rtlUtf8ToUtf8X(resultLen, result, length, (const char *)ptr);
- }
- else
- {
- size32_t len = rtlReadSize32t(ptr);
- rtlUtf8ToUtf8X(resultLen, result, len, (const char *)ptr + sizeof(size32_t));
- }
- }
- __int64 RtlUtf8TypeInfo::getInt(const void * ptr) const
- {
- //Utf8 output is the same as string output, so avoid the intermediate translation
- if (isFixedSize())
- return rtlUtf8ToInt(length, (const char *)ptr);
- size32_t len = rtlReadSize32t(ptr);
- return rtlUtf8ToInt(len, (const char *)ptr + sizeof(size32_t));
- }
- int RtlUtf8TypeInfo::compare(const byte * left, const byte * right) const
- {
- assertex(!isFixedSize());
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- const char * valueLeft = reinterpret_cast<const char *>(left) + sizeof(size32_t);
- const char * valueRight = reinterpret_cast<const char *>(right) + sizeof(size32_t);
- return rtlCompareUtf8Utf8(lenLeft, valueLeft, lenRight, valueRight, locale);
- }
- unsigned RtlUtf8TypeInfo::hash(const byte * self, unsigned inhash) const
- {
- assertex(!isFixedSize());
- size32_t len = rtlReadSize32t(self);
- const char * uself = reinterpret_cast<const char *>(self + sizeof(size32_t));
- return rtlHash32Utf8(rtlTrimUtf8StrLen(len, uself), uself,inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- inline size32_t sizeFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow)
- {
- unsigned offset = 0;
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- offset += child->size(self+offset, selfrow);
- cur++;
- }
- return offset;
- }
- static size32_t processFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow, IFieldProcessor & target)
- {
- unsigned offset = 0;
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- child->process(self+offset, selfrow, target);
- offset += child->size(self+offset, selfrow);
- cur++;
- }
- return offset;
- }
- static size32_t buildFields(const RtlFieldInfo * const * cur, ARowBuilder &builder, size32_t offset, IFieldSource &source)
- {
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- offset = child->build(builder, offset, source);
- cur++;
- }
- return offset;
- }
- static size32_t toXMLFields(const RtlFieldInfo * const * cur, const byte * self, const byte * selfrow, IXmlWriter & target)
- {
- size32_t offset = 0;
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- size32_t size = child->toXML(self+offset, selfrow, target);
- offset += size;
- cur++;
- }
- return offset;
- }
- static size32_t deserializeFields(const RtlFieldInfo * const * cur, ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset)
- {
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- offset = child->type->deserialize(builder, in, offset);
- cur++;
- }
- return offset;
- }
- static void readAheadFields(const RtlFieldInfo * const * cur, IRowDeserializerSource & in)
- {
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- child->type->readAhead(in);
- cur++;
- }
- }
- int ECLRTL_API compareFields(const RtlFieldInfo * const * cur, const byte * left, const byte * right, bool excludePayload)
- {
- size32_t leftOffset = 0;
- size32_t rightOffset = 0;
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child || (excludePayload && (child->flags & RFTMispayloadfield)))
- return 0;
- auto type = child->type;
- int rc = type->compare(left + leftOffset, right + rightOffset);
- if (rc != 0)
- return rc;
- leftOffset += type->size(left + leftOffset, left);
- rightOffset += type->size(right + rightOffset, right);
- cur++;
- }
- }
- unsigned ECLRTL_API hashFields(const RtlFieldInfo * const * cur, const byte *self, unsigned inhash, bool excludePayload)
- {
- size32_t offset = 0;
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child || (excludePayload && (child->flags & RFTMispayloadfield)))
- break;
- auto type = child->type;
- inhash = type->hash(self + offset, inhash);
- offset += type->size(self + offset, self);
- cur++;
- }
- return inhash;
- }
- extern bool ECLRTL_API hasTrailingFileposition(const RtlFieldInfo * const * fields)
- {
- if (!*fields)
- return false;
- while (*fields)
- fields++;
- return (fields[-1]->type->getType() == type_filepos); // note - filepos is created as an RtlSwapIntTypeInfo with type set to type_filepos
- }
- extern bool ECLRTL_API hasTrailingFileposition(const RtlTypeInfo * type)
- {
- switch (type->getType())
- {
- case type_record:
- {
- const RtlRecordTypeInfo * record = static_cast<const RtlRecordTypeInfo *>(type);
- return hasTrailingFileposition(record->fields);
- }
- }
- return false;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlRecordTypeInfo::getMinSize() const
- {
- return ::getMinSize(fields);
- }
- size32_t RtlRecordTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- return sizeFields(fields, self, self);
- }
- size32_t RtlRecordTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (target.processBeginRow(field))
- {
- unsigned offset = processFields(fields, self, self, target);
- target.processEndRow(field);
- return offset;
- }
- return size(self, selfrow);
- }
- size32_t RtlRecordTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- const char * xpath = queryXPath(field);
- if (*xpath)
- target.outputBeginNested(xpath, false);
- unsigned thisSize = toXMLFields(fields, self, self, target);
- if (*xpath)
- target.outputEndNested(xpath);
- return thisSize;
- }
- size32_t RtlRecordTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- //Will not generally be called because it will have been expanded
- return deserializeFields(fields, builder, in, offset);
- }
- void RtlRecordTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- //Will not generally be called because it will have been expanded
- return readAheadFields(fields, in);
- }
- size32_t RtlRecordTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- source.processBeginRow(field);
- offset = buildFields(fields, builder, offset, source);
- source.processEndRow(field);
- return offset;
- }
- size32_t RtlRecordTypeInfo::buildNull(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field) const
- {
- const RtlFieldInfo * const * cur = fields;
- for (;;)
- {
- const RtlFieldInfo * child = *cur;
- if (!child)
- break;
- offset = child->type->buildNull(builder, offset, child);
- cur++;
- }
- return offset;
- }
- size32_t RtlRecordTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- throwUnexpected();
- }
- size32_t RtlRecordTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- throwUnexpected();
- }
- void RtlRecordTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- resultLen = 0;
- result = nullptr;
- }
- void RtlRecordTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- resultLen = 0;
- result = nullptr;
- }
- __int64 RtlRecordTypeInfo::getInt(const void * ptr) const
- {
- return 0;
- }
- int RtlRecordTypeInfo::compare(const byte * left, const byte * right) const
- {
- return compareFields(fields, left, right);
- }
- unsigned RtlRecordTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- return hashFields(fields, self, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlCompoundTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- UNIMPLEMENTED;
- }
- size32_t RtlCompoundTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- UNIMPLEMENTED;
- }
- void RtlCompoundTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- //MORE: Should this fail instead?
- resultLen = 0;
- result = nullptr;
- }
- void RtlCompoundTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- //MORE: Should this fail instead?
- resultLen = 0;
- result = nullptr;
- }
- __int64 RtlCompoundTypeInfo::getInt(const void * ptr) const
- {
- //MORE: Should this fail instead?
- return 0;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlSetTypeInfo::getMinSize() const
- {
- return sizeof(bool) + sizeof(size32_t);
- }
- size32_t RtlSetTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- return sizeof(bool) + sizeof(size32_t) + rtlReadSize32t(self + sizeof(bool));
- }
- size32_t RtlSetTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- bool isAll;
- source.processBeginSet(field, isAll);
- size32_t sizeInBytes = sizeof(bool) + sizeof(size32_t);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- byte *dest = builder.getSelf()+offset;
- if (isAll)
- {
- * (bool *) dest = true;
- rtlWriteInt4(dest+1, 0);
- offset += sizeInBytes;
- }
- else
- {
- * (bool *) dest = false;
- size32_t newOffset = offset + sizeInBytes;
- RtlFieldStrInfo dummyField("<set element>", NULL, child);
- while (source.processNextSet(field))
- {
- newOffset = child->build(builder, newOffset, &dummyField, source);
- }
- // Go back in and patch the size, remembering it may have moved
- rtlWriteInt4(builder.getSelf()+offset+1, newOffset - (offset+sizeInBytes));
- offset = newOffset;
- }
- source.processEndSet(field);
- return offset;
- }
- size32_t RtlSetTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- unsigned offset = sizeof(bool) + sizeof(size32_t);
- unsigned max = offset + rtlReadSize32t(self + sizeof(bool));
- unsigned elements = 0;
- if (!*(bool *)self)
- {
- unsigned tempOffset = sizeof(bool) + sizeof(size32_t);
- if (child->isFixedSize())
- {
- unsigned elemSize = child->size(NULL, NULL);
- elements = (max-offset) / elemSize;
- assert(elements*elemSize == max-offset);
- }
- else
- {
- DummyFieldProcessor dummy;
- while (tempOffset < max)
- {
- tempOffset += child->process(self+tempOffset, selfrow, field, dummy); // NOTE - good thing we can't have a set of sets, or this would recurse
- elements++;
- }
- }
- }
- if (target.processBeginSet(field, elements, *(bool *)self, self+offset))
- {
- while (offset < max)
- {
- offset += child->process(self+offset, selfrow, field, target);
- }
- }
- target.processEndSet(field);
- return max;
- }
- size32_t RtlSetTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- unsigned offset = sizeof(bool) + sizeof(size32_t);
- unsigned max = offset + rtlReadSize32t(self + sizeof(bool));
- StringAttr outerTag;
- if (hasOuterXPath(field))
- {
- queryNestedOuterXPath(outerTag, field);
- target.outputBeginNested(outerTag, false);
- }
- if (*(bool *)self)
- target.outputSetAll();
- else
- {
- const char *innerPath = queryXPath(field);
- target.outputBeginArray(innerPath);
- while (offset < max)
- {
- child->toXML(self+offset, selfrow, field, target);
- offset += child->size(self+offset, selfrow);
- }
- target.outputEndArray(innerPath);
- }
- if (outerTag)
- target.outputEndNested(outerTag);
- return max;
- }
- size32_t RtlSetTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- bool isAll;
- in.read(1, &isAll);
- size32_t size = in.readSize();
- byte * dest = builder.ensureCapacity(offset+sizeof(bool)+sizeof(size32_t)+size, nullptr) + offset;
- *dest = isAll;
- rtlWriteSize32t(dest + sizeof(bool), size);
- in.read(size, dest + sizeof(bool) + sizeof(size32_t));
- return offset+sizeof(bool)+sizeof(size32_t)+size;
- }
- void RtlSetTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- in.skip(1);
- size32_t thisLength = in.readSize();
- in.skip(thisLength);
- }
- int RtlSetTypeInfo::compare(const byte * left, const byte * right) const
- {
- const bool allLeft = *(const bool *)left;
- const bool allRight = *(const bool *)right;
- if (allLeft || allRight)
- {
- if (allLeft && allRight)
- return 0;
- if (allLeft)
- return +1;
- else
- return -1;
- }
- size32_t sizeLeft = rtlReadSize32t(left + sizeof(bool));
- const byte * ptrLeft = left + sizeof(bool) + sizeof(size32_t);
- size32_t sizeRight = rtlReadSize32t(right + sizeof(bool));
- const byte * ptrRight = right + sizeof(bool) + sizeof(size32_t);
- size32_t offLeft = 0;
- size32_t offRight = 0;
- for (;;)
- {
- if ((offLeft == sizeLeft) || (offRight == sizeRight))
- {
- if ((offLeft == sizeLeft) && (offRight == sizeRight))
- return 0;
- if (offLeft == sizeLeft)
- return -1;
- else
- return +1;
- }
- int rc = child->compare(ptrLeft + offLeft, ptrRight + offRight);
- if (rc != 0)
- return rc;
- offLeft += child->size(ptrLeft + offLeft, ptrLeft + offLeft);
- offRight += child->size(ptrRight + offRight, ptrRight + offRight);
- }
- }
- unsigned RtlSetTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- const bool allLeft = *(const bool *) self;
- self += sizeof(bool);
- if (allLeft)
- {
- // Nothing - this is unfortunate as it means hash(all) and hash([]) are the same...
- // But it matches generated code
- }
- else
- {
- size32_t size = rtlReadSize32t(self);
- self += sizeof(size32_t);
- #if 0
- // This might be the smart way to hash - since it means that the hash depends on the value, not the type,
- // and that things that compare equal will hash equal. But that is not what the code generator does
- for (size32_t offset = 0; offset < size; offset += child->size(self + offset, self + offset))
- {
- inhash = child->hash(self + offset, inhash);
- }
- #else
- inhash = rtlHash32Data(size, self, inhash);
- #endif
- }
- return inhash;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlRowTypeInfo::getMinSize() const
- {
- if (isLinkCounted())
- return sizeof(void *);
- return child->getMinSize();
- }
- size32_t RtlRowTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isLinkCounted())
- return sizeof(void *);
- return child->size(self, selfrow);
- }
- size32_t RtlRowTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isLinkCounted())
- {
- const byte * row = *(const byte * *)self;
- if (row)
- child->process(row, row, field, target);
- return sizeof(row);
- }
- return child->process(self, self, field, target);
- }
- size32_t RtlRowTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- if (isLinkCounted())
- {
- const byte * row = *(const byte * *)self;
- child->toXML(row, row, field, target);
- return sizeof(row);
- }
- return child->toXML(self, self, field, target);
- }
- size32_t RtlRowTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- //Link counted isn't yet implemented in the code generator
- if (isLinkCounted())
- UNIMPLEMENTED;
- return child->deserialize(builder, in, offset);
- }
- void RtlRowTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- return child->readAhead(in);
- }
- int RtlRowTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isLinkCounted())
- {
- const byte * leftRow = *(const byte * *)left;
- const byte * rightRow = *(const byte * *)right;
- if (leftRow && rightRow)
- return child->compare(leftRow, rightRow);
- if (leftRow)
- return +1;
- if (rightRow)
- return -1;
- return 0;
- }
- return child->compare(left, right);
- }
- unsigned RtlRowTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- if (isLinkCounted())
- {
- const byte * selfRow = *(const byte * *)self;
- if (selfRow)
- inhash = child->hash(selfRow, inhash);
- return inhash;
- }
- return child->hash(self, inhash);
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlDatasetTypeInfo::getMinSize() const
- {
- if (isLinkCounted())
- return sizeof(size32_t) + sizeof(void * *);
- return sizeof(size32_t);
- }
- size32_t RtlDatasetTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isLinkCounted())
- return sizeof(size32_t) + sizeof(void * *);
- return sizeof(size32_t) + rtlReadSize32t(self);
- }
- size32_t RtlDatasetTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- source.processBeginDataset(field);
- if (isLinkCounted())
- {
- // a 32-bit record count, and a pointer to an array of record pointers
- size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- size32_t numRows = 0;
- Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
- const byte **childRows = NULL;
- RtlFieldStrInfo dummyField("<nested row>", NULL, child);
- while (source.processNextRow(field))
- {
- RtlDynamicRowBuilder childBuilder(*childAllocator);
- size32_t childLen = child->build(childBuilder, 0, &dummyField, source);
- childRows = childAllocator->appendRowOwn(childRows, ++numRows, (void *) childBuilder.finalizeRowClear(childLen));
- }
- // Go back in and patch the count, remembering it may have moved
- rtlWriteInt4(builder.getSelf()+offset, numRows);
- * ( const void * * ) (builder.getSelf()+offset+sizeof(size32_t)) = childRows;
- offset += sizeInBytes;
- }
- else
- {
- // a 32-bit size, then rows inline
- size32_t sizeInBytes = sizeof(size32_t);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- size32_t newOffset = offset + sizeInBytes;
- RtlFieldStrInfo dummyField("<nested row>", NULL, child);
- while (source.processNextRow(field))
- newOffset = child->build(builder, newOffset, &dummyField, source);
- // Go back in and patch the size, remembering it may have moved
- rtlWriteInt4(builder.getSelf()+offset, newOffset - (offset+sizeInBytes));
- offset = newOffset;
- }
- source.processEndDataset(field);
- return offset;
- }
- size32_t RtlDatasetTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isLinkCounted())
- {
- size32_t thisCount = rtlReadSize32t(self);
- if (target.processBeginDataset(field, thisCount))
- {
- const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
- for (unsigned i= 0; i < thisCount; i++)
- {
- const byte * row = rows[i];
- child->process(row, row, field, target);
- }
- target.processEndDataset(field);
- }
- return sizeof(size32_t) + sizeof(void * *);
- }
- else
- {
- unsigned offset = sizeof(size32_t);
- unsigned max = offset + rtlReadSize32t(self);
- unsigned thisCount = 0;
- DummyFieldProcessor dummy;
- while (offset < max)
- {
- offset += child->process(self+offset, self+offset, field, dummy);
- thisCount++;
- }
- offset = sizeof(size32_t);
- if (target.processBeginDataset(field, thisCount))
- {
- while (offset < max)
- {
- offset += child->process(self+offset, self+offset, field, target);
- }
- target.processEndDataset(field);
- }
- return max;
- }
- }
- size32_t RtlDatasetTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- StringAttr outerTag;
- if (hasOuterXPath(field))
- {
- queryNestedOuterXPath(outerTag, field);
- target.outputBeginNested(outerTag, false);
- }
- const char *innerPath = queryXPath(field);
- target.outputBeginArray(innerPath);
- unsigned thisSize;
- if (isLinkCounted())
- {
- size32_t thisCount = rtlReadSize32t(self);
- const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
- for (unsigned i= 0; i < thisCount; i++)
- {
- const byte * row = rows[i];
- if (row)
- child->toXML(row, row, field, target);
- }
- thisSize = sizeof(size32_t) + sizeof(void * *);
- }
- else
- {
- unsigned offset = sizeof(size32_t);
- unsigned max = offset + rtlReadSize32t(self);
- while (offset < max)
- {
- child->toXML(self+offset, self+offset, field, target);
- offset += child->size(self+offset, self+offset);
- }
- thisSize = max;
- }
- target.outputEndArray(innerPath);
- if (outerTag)
- target.outputEndNested(outerTag);
- return thisSize;
- }
- size32_t RtlDatasetTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- const bool canUseMemcpy = true;
- if (canUseMemcpy && !isLinkCounted())
- {
- size32_t size = in.readSize();
- byte * dest = builder.ensureCapacity(offset+sizeof(size32_t)+size, nullptr) + offset;
- rtlWriteSize32t(dest, size);
- in.read(size, dest + sizeof(size32_t));
- return offset + sizeof(size32_t) + size;
- }
- else
- {
- if (isLinkCounted())
- {
- //Currently inefficient because it is recreating deserializers and resolving child allocators each time it is called.
- ICodeContext * ctx = nullptr; // Slightly dodgy, but not needed if the child deserializers are also calculated
- unsigned activityId = 0;
- // a 32-bit record count, and a pointer to an hash table with record pointers
- size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
- byte * dest = builder.ensureCapacity(offset+sizeInBytes, nullptr) + offset;
- Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
- Owned<IOutputRowDeserializer> deserializer = childAllocator->queryOutputMeta()->createDiskDeserializer(ctx, activityId);
- rtlDeserializeChildRowset(*(size32_t *)dest, *(const byte * * *)(dest + sizeof(size32_t)), childAllocator, deserializer, in);
- return offset + sizeInBytes;
- }
- else
- {
- size32_t startOffset = offset + sizeof(size32_t);
- size32_t nextOffset = startOffset;
- offset_t endOffset = in.beginNested();
- while (in.finishedNested(endOffset))
- nextOffset = child->deserialize(builder, in, nextOffset);
- rtlWriteSize32t(builder.getSelf() + offset, nextOffset - startOffset);
- return nextOffset;
- }
- }
- }
- void RtlDatasetTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- size32_t size = in.readSize();
- in.skip(size);
- }
- int RtlDatasetTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isLinkCounted())
- {
- const size32_t countLeft = rtlReadSize32t(left);
- const size32_t countRight = rtlReadSize32t(right);
- const byte * * rowsLeft = (const byte * *)((const byte *)left + sizeof(size32_t));
- const byte * * rowsRight = (const byte * *)((const byte *)right + sizeof(size32_t));
- size32_t row = 0;
- for (;;)
- {
- if ((row == countLeft) || (row == countRight))
- {
- if (countLeft == countRight)
- return 0;
- if (row == countLeft)
- return -1;
- else
- return +1;
- }
- int rc = child->compare(rowsLeft[row], rowsRight[row]);
- if (rc != 0)
- return rc;
- row++;
- }
- }
- size32_t lenLeft = rtlReadSize32t(left);
- size32_t lenRight = rtlReadSize32t(right);
- const byte * ptrLeft = left + sizeof(size32_t);
- const byte * ptrRight = right + sizeof(size32_t);
- size32_t offLeft = 0;
- size32_t offRight = 0;
- for (;;)
- {
- if ((offLeft == lenLeft) || (offRight == lenRight))
- {
- if ((offLeft == lenLeft) && (offRight == lenRight))
- return 0;
- if (offLeft == lenLeft)
- return -1;
- else
- return +1;
- }
- int rc = child->compare(ptrLeft + offLeft, ptrRight + offRight);
- if (rc != 0)
- return rc;
- offLeft += child->size(ptrLeft + offLeft, ptrLeft + offLeft);
- offRight += child->size(ptrRight + offRight, ptrRight + offRight);
- }
- }
- unsigned RtlDatasetTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- if (isLinkCounted())
- {
- const size32_t count = rtlReadSize32t(self);
- self += sizeof(size32_t);
- const byte * * rows = (const byte * *) self;
- for (size32_t row = 0; row < count; row++)
- {
- inhash = child->hash(rows[row], inhash);
- row++;
- }
- }
- else
- {
- size32_t len = rtlReadSize32t(self);
- self += sizeof(size32_t);
- for (size32_t offset = 0; offset < len; offset += child->size(self + offset, self + offset))
- {
- inhash = child->hash(self + offset, inhash);
- }
- }
- return inhash;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlDictionaryTypeInfo::getMinSize() const
- {
- if (isLinkCounted())
- return sizeof(size32_t) + sizeof(void * *);
- return sizeof(size32_t);
- }
- size32_t RtlDictionaryTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (isLinkCounted())
- return sizeof(size32_t) + sizeof(void * *);
- return sizeof(size32_t) + rtlReadSize32t(self);
- }
- size32_t RtlDictionaryTypeInfo::build(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, IFieldSource &source) const
- {
- source.processBeginDataset(field);
- if (isLinkCounted())
- {
- // a 32-bit record count, and a pointer to an hash table with record pointers
- size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
- builder.ensureCapacity(offset+sizeInBytes, queryName(field));
- Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
- CHThorHashLookupInfo hashInfo(*static_cast<const RtlRecordTypeInfo *>(child));
- RtlLinkedDictionaryBuilder dictBuilder(childAllocator, &hashInfo);
- RtlFieldStrInfo dummyField("<nested row>", NULL, child);
- while (source.processNextRow(field))
- {
- RtlDynamicRowBuilder childBuilder(childAllocator);
- size32_t childLen = child->build(childBuilder, 0, &dummyField, source);
- dictBuilder.appendOwn((void *) childBuilder.finalizeRowClear(childLen));
- }
- // Go back in and patch the count
- rtlWriteInt4(builder.getSelf()+offset, dictBuilder.getcount());
- * ( const void * * ) (builder.getSelf()+offset+sizeof(size32_t)) = dictBuilder.linkrows();
- offset += sizeInBytes;
- }
- else
- throwUnexpected(); // And may never be...
- source.processEndDataset(field);
- return offset;
- }
- size32_t RtlDictionaryTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isLinkCounted())
- {
- size32_t thisCount = rtlReadSize32t(self);
- if (target.processBeginDataset(field, thisCount))
- {
- const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
- for (unsigned i= 0; i < thisCount; i++)
- {
- const byte * row = rows[i];
- if (row)
- child->process(row, row, field, target);
- }
- target.processEndDataset(field);
- }
- return sizeof(size32_t) + sizeof(void * *);
- }
- else
- {
- //MORE: We could interpret serialized dictionaries if there was ever a need
- throwUnexpected();
- }
- }
- size32_t RtlDictionaryTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- StringAttr outerTag;
- if (hasOuterXPath(field))
- {
- queryNestedOuterXPath(outerTag, field);
- target.outputBeginNested(outerTag, false);
- }
- const char *innerPath = queryXPath(field);
- target.outputBeginArray(innerPath);
- unsigned thisSize;
- if (isLinkCounted())
- {
- size32_t thisCount = rtlReadSize32t(self);
- const byte * * rows = *reinterpret_cast<const byte * * const *>(self + sizeof(size32_t));
- for (unsigned i= 0; i < thisCount; i++)
- {
- const byte * row = rows[i];
- if (row)
- child->toXML(row, row, field, target);
- }
- thisSize = sizeof(size32_t) + sizeof(void * *);
- }
- else
- {
- //MORE: We could interpret serialized dictionaries if there was ever a need
- throwUnexpected();
- }
- target.outputEndArray(innerPath);
- if (outerTag)
- target.outputEndNested(outerTag);
- return thisSize;
- }
- size32_t RtlDictionaryTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (isLinkCounted())
- {
- //Currently inefficient because it is recreating deserializers and resolving child allocators each time it is called.
- ICodeContext * ctx = nullptr; // Slightly dodgy, but not needed if the child deserializers are also calculated
- unsigned activityId = 0;
- // a 32-bit record count, and a pointer to an hash table with record pointers
- size32_t sizeInBytes = sizeof(size32_t) + sizeof(void *);
- byte * dest = builder.ensureCapacity(offset + sizeInBytes, nullptr) + offset;
- Owned<IEngineRowAllocator> childAllocator = builder.queryAllocator()->createChildRowAllocator(child);
- Owned<IOutputRowDeserializer> deserializer = childAllocator->queryOutputMeta()->createDiskDeserializer(ctx, activityId);
- rtlDeserializeChildDictionary(*(size32_t *)dest, *(const byte * * *)(dest + sizeof(size32_t)), childAllocator, deserializer, in);
- return offset + sizeInBytes;
- }
- else
- {
- UNIMPLEMENTED;
- }
- }
- void RtlDictionaryTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- size32_t size = in.readSize();
- in.skip(size);
- }
- int RtlDictionaryTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isLinkCounted())
- {
- const size32_t countLeft = rtlReadSize32t(left);
- const size32_t countRight = rtlReadSize32t(right);
- const byte * * rowsLeft = (const byte * *)((const byte *)left + sizeof(size32_t));
- const byte * * rowsRight = (const byte * *)((const byte *)right + sizeof(size32_t));
- size32_t leftRow = 0;
- size32_t rightRow = 0;
- for (;;)
- {
- //Dictionaries are compared as datasets => skip until the first non-null entry
- while ((leftRow != countLeft) && !rowsLeft[leftRow])
- leftRow++;
- while ((rightRow != countRight) && !rowsRight[rightRow])
- rightRow++;
- if ((leftRow == countLeft) || (rightRow == countRight))
- {
- if ((leftRow == countLeft) && (rightRow == countRight))
- return 0;
- if (leftRow == countLeft)
- return -1;
- else
- return +1;
- }
- int rc = child->compare(rowsLeft[leftRow], rowsRight[rightRow]);
- if (rc != 0)
- return rc;
- leftRow++;
- rightRow++;
- }
- }
- else
- {
- //Non LCR dictionaries are not supported.
- throwUnexpected();
- }
- }
- unsigned RtlDictionaryTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- if (isLinkCounted())
- {
- const size32_t count = rtlReadSize32t(self);
- self += sizeof(size32_t);
- const byte * * rows = (const byte * *) self;
- size32_t row = 0;
- for (;;)
- {
- //Dictionaries are compared as datasets => skip until the first non-null entry
- while ((row != count) && !rows[row])
- row++;
- if (row == count)
- break;
- inhash = child->hash(rows[row], inhash);
- row++;
- }
- }
- else
- {
- //Non LCR dictionaries are not supported.
- throwUnexpected();
- }
- return inhash;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlIfBlockTypeInfo::getMinSize() const
- {
- return 0;
- }
- size32_t RtlIfBlockTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (getCondition(selfrow))
- return sizeFields(fields, self, selfrow);
- return 0;
- }
- size32_t RtlIfBlockTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- throwUnexpected();
- }
- size32_t RtlIfBlockTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- throwUnexpected();
- }
- size32_t RtlIfBlockTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (getCondition(selfrow))
- return processFields(fields, self, selfrow, target);
- return 0;
- }
- size32_t RtlIfBlockTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- if (getCondition(selfrow))
- return toXMLFields(fields, self, selfrow, target);
- return 0;
- }
- size32_t RtlIfBlockTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- if (getCondition(builder.getSelf()))
- return deserializeFields(fields, builder, in, offset);
- return offset;
- }
- void RtlIfBlockTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- UNIMPLEMENTED;
- }
- void RtlIfBlockTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- //MORE: Should this fail instead?
- resultLen = 0;
- result = nullptr;
- }
- void RtlIfBlockTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- //MORE: Should this fail instead?
- resultLen = 0;
- result = nullptr;
- }
- __int64 RtlIfBlockTypeInfo::getInt(const void * ptr) const
- {
- //MORE: Should this fail instead?
- return 0;
- }
- int RtlIfBlockTypeInfo::compare(const byte * left, const byte * right) const
- {
- bool includeLeft = getCondition(left);
- bool includeRight = getCondition(right);
- if (includeLeft && includeRight)
- return compareFields(fields, left, right);
- //If the fields are all blank then this isn't actually correct, but that is unlikely to be a problem
- if (includeLeft)
- return +1;
- else if (includeRight)
- return -1;
- else
- return 0;
- }
- unsigned RtlIfBlockTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- bool included = getCondition(self);
- if (included)
- inhash = hashFields(fields, self, inhash);
- return inhash;
- }
- bool RtlDynamicIfBlockTypeInfo::getCondition(const byte * selfrow) const
- {
- #ifdef _DEBUG
- // Temporary code to help my testing, until proper implementation available
- return selfrow[3] != 2;
- #endif
- UNIMPLEMENTED;
- }
- //-------------------------------------------------------------------------------------------------------------------
- __int64 RtlBitfieldTypeInfo::signedValue(const void * self) const
- {
- __int64 value = rtlReadInt(self, getBitfieldIntSize());
- unsigned shift = getBitfieldShift();
- unsigned numBits = getBitfieldNumBits();
- unsigned bitsInValue = sizeof(value) * 8;
- value <<= (bitsInValue - shift - numBits);
- return value >> (bitsInValue - numBits);
- }
- unsigned __int64 RtlBitfieldTypeInfo::unsignedValue(const void * self) const
- {
- unsigned __int64 value = rtlReadUInt(self, getBitfieldIntSize());
- unsigned shift = getBitfieldShift();
- unsigned numBits = getBitfieldNumBits();
- unsigned bitsInValue = sizeof(value) * 8;
- value <<= (bitsInValue - shift - numBits);
- return value >> (bitsInValue - numBits);
- }
- size32_t RtlBitfieldTypeInfo::buildInt(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, __int64 val) const
- {
- builder.ensureCapacity(length+offset, queryName(field));
- byte * cur = builder.getSelf() + offset;
- unsigned __int64 value = rtlReadUInt(builder.getSelf(), getBitfieldIntSize());
- unsigned shift = getBitfieldShift();
- unsigned numBits = getBitfieldNumBits();
- unsigned __int64 mask = (U64C(1) << numBits) - 1;
- value &= ~(mask << shift);
- value |= ((val << shift) & mask);
- rtlWriteInt(cur, val, getBitfieldIntSize());
- return offset + getSize();
- }
- size32_t RtlBitfieldTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlBitfieldTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- size32_t size = rtlUtf8Length(len, value);
- return buildInt(builder, offset, field, rtlStrToInt8(size, value));
- }
- size32_t RtlBitfieldTypeInfo::getMinSize() const
- {
- if (fieldType & RFTMislastbitfield)
- return getBitfieldIntSize();
- return 0;
- }
- size32_t RtlBitfieldTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- if (fieldType & RFTMislastbitfield)
- return getBitfieldIntSize();
- return 0;
- }
- size32_t RtlBitfieldTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- if (isUnsigned())
- target.processUInt(unsignedValue(self), field);
- else
- target.processInt(signedValue(self), field);
- return getSize();
- }
- size32_t RtlBitfieldTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- size32_t fieldsize = getBitfieldIntSize();
- if (isUnsigned())
- target.outputUInt(unsignedValue(self), fieldsize, queryScalarXPath(field));
- else
- target.outputInt(signedValue(self), fieldsize, queryScalarXPath(field));
- if (fieldType & RFTMislastbitfield)
- return fieldsize;
- return 0;
- }
- void RtlBitfieldTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- if (isUnsigned())
- rtlUInt8ToStrX(resultLen, result, unsignedValue(ptr));
- else
- rtlInt8ToStrX(resultLen, result, signedValue(ptr));
- }
- void RtlBitfieldTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- getString(resultLen, result, ptr);
- }
- __int64 RtlBitfieldTypeInfo::getInt(const void * ptr) const
- {
- if (isUnsigned())
- return (__int64)unsignedValue(ptr);
- else
- return signedValue(ptr);
- }
- int RtlBitfieldTypeInfo::compare(const byte * left, const byte * right) const
- {
- if (isUnsigned())
- {
- unsigned __int64 leftValue = unsignedValue(left);
- unsigned __int64 rightValue = unsignedValue(right);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- else
- {
- __int64 leftValue = signedValue(left);
- __int64 rightValue = signedValue(right);
- return (leftValue < rightValue) ? -1 : (leftValue > rightValue) ? +1 : 0;
- }
- }
- unsigned RtlBitfieldTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- __int64 val = getInt(self);
- return rtlHash32Data8(&val, inhash);
- }
- size32_t RtlBitfieldTypeInfo::getSize() const
- {
- if (fieldType & RFTMislastbitfield)
- return getBitfieldIntSize();
- return 0;
- }
- //-------------------------------------------------------------------------------------------------------------------
- size32_t RtlUnimplementedTypeInfo::getMinSize() const
- {
- rtlFailUnexpected();
- }
- size32_t RtlUnimplementedTypeInfo::size(const byte * self, const byte * selfrow) const
- {
- rtlFailUnexpected();
- }
- size32_t RtlUnimplementedTypeInfo::buildString(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t size, const char *value) const
- {
- rtlFailUnexpected();
- }
- size32_t RtlUnimplementedTypeInfo::buildUtf8(ARowBuilder &builder, size32_t offset, const RtlFieldInfo *field, size32_t len, const char *value) const
- {
- rtlFailUnexpected();
- }
- size32_t RtlUnimplementedTypeInfo::process(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IFieldProcessor & target) const
- {
- rtlFailUnexpected();
- }
- size32_t RtlUnimplementedTypeInfo::toXML(const byte * self, const byte * selfrow, const RtlFieldInfo * field, IXmlWriter & target) const
- {
- rtlFailUnexpected();
- }
- size32_t RtlUnimplementedTypeInfo::deserialize(ARowBuilder & builder, IRowDeserializerSource & in, size32_t offset) const
- {
- rtlFailUnexpected();
- return offset;
- }
- void RtlUnimplementedTypeInfo::readAhead(IRowDeserializerSource & in) const
- {
- rtlFailUnexpected();
- }
- void RtlUnimplementedTypeInfo::getString(size32_t & resultLen, char * & result, const void * ptr) const
- {
- resultLen = 0;
- result = nullptr;
- rtlFailUnexpected();
- }
- void RtlUnimplementedTypeInfo::getUtf8(size32_t & resultLen, char * & result, const void * ptr) const
- {
- resultLen = 0;
- result = nullptr;
- rtlFailUnexpected();
- }
- __int64 RtlUnimplementedTypeInfo::getInt(const void * ptr) const
- {
- rtlFailUnexpected();
- return 0;
- }
- int RtlUnimplementedTypeInfo::compare(const byte * left, const byte * right) const
- {
- rtlFailUnexpected();
- }
- unsigned RtlUnimplementedTypeInfo::hash(const byte * self, unsigned inhash) const
- {
- rtlFailUnexpected();
- }
- //-------------------------------------------------------------------------------------------------------------------
- RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, unsigned _flags, const char *_initializer)
- : RtlFieldInfo(_name, _xpath, _type, _flags, _initializer)
- {
- }
- RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, unsigned _flags)
- : RtlFieldInfo(_name, _xpath, _type, _flags, NULL)
- {
- }
- RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type)
- : RtlFieldInfo(_name, _xpath, _type, 0, NULL)
- {
- }
- RtlFieldStrInfo::RtlFieldStrInfo(const char * _name, const char * _xpath, const RtlTypeInfo * _type, const char *_initializer)
- : RtlFieldInfo(_name, _xpath, _type, 0, _initializer)
- {
- }
- unsigned ECLRTL_API countFields(const RtlFieldInfo * const * fields)
- {
- unsigned cnt = 0;
- for (;*fields;fields++)
- cnt++;
- return cnt;
- }
- /*
- Stack:
- * Change hqlhtcpp so that the correct derived classes are generated.
- * Test so that toXML calls the default implementaions and check that the same values are generated. (Don't if contains ifblocks/alien)
- * Release
- * Think about bitfields - how do I know it is the last bitfield, how am I going to keep track of the offsets.
- * What code would need to be generated for alien datatypes.
- * Could have alien int and alien string varieties????
- * What would an ecl interpreter look like (a special workunit?) helpers are interpreted? What about the graph?
- * Could I add associations to register user attributes - so a callback could know when they were assigned to?
- * Could I add ctx->noteLocation() into the generated code - so could put breakpoints on variables.
- * Add annotation when a member of the target dataset is updated.
- ctx->noteFieldAssigned(self, <field>); - does this include temporary datasets?
- ctx->noteAttributeX(<name>, Int|String|Unicode|
- 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??
- * Need static information about the breakpoints so debugger knows where to put valid brakpoints....
- * Debugger will want to know about the type of the breakpoints.
- * Should try and compress the location format - possibly have a table of <module.attributes>-># with breakpoint as 12:23
- Also need some information about which datasets, and stored variables etc. are used so they can be displayed.
- - Most datasets can be deduced from the parameters passed into the transform
- - Some are trickier e.g., the extract, could possibly define some mappings
- - options to disable projects/other more complex operations inline (so easier to walk through)
- Bitfields:
- - Two separate questions:
- i) How is the meta information generated.
- ii) How is it stored internally in an IHqlExpression * ?
- * Could store the offset in the type - either in the base type of as a qualifier.
- + much easier code generation.
- - Doesn't provie an easy indication of the last field in a bitfield (because can't really modify after the fact)
- - Problematic when fields are removed to merge them.
- * Could add a bitfield container to the record.
- + Makes it easier to handle the last bitfield
- + Matches the structure used for the cursor.
- - Everything needs to walk the bitfield containers similar to ifblocks.
- - Makes it just as tricky to merge
- - Harder to create the record, unless the code is implicitly handled by appendOperand().
- * The type of no_select could contain a modifier to indicate the offset/islast
- + the type of a no_select would have a 1:1 mapping with type info.
- - A bit complicated to calculate, especially when it isn't used much of the time
- => On Reflection is is probably easiest to keep the structure as it is (some comments should go in hqlexpr to avoid revisiting).
- * interperet bitfield offsets and "is last bitfield" dynamically
- + Greatly simplifies generating the meta - you can always use the field.
- - Requires another parameter and significant extra complexity for the uncommon case. (especially incrementing self)
- * Could generate from the expanded record instead of walking the record structure directly
- + That already knows how the bitfields are allocated, and could easily know which is the last field.
- - A field is no longer sufficient as key fr searching for the information.
- - Best would be a createFieldTypeKey(select-expr) which returns field when approriate, or modified if a bitfield. Then the pain is localised.
-
- * Output a bitfield container item into the type information
- + Solves the size problem
- - Individual bitfields still need to know their offsets, so doesn't solve the full problem.
- =>
- Change so that either use meta to generate the information, or use no_select when appropriate to fidn out the nesc. information.
- Probably the latter for the moment.
- a) Create a key function and make sure it is always used.
- b) Need to work out how to generate no_ifblock.
- - ifblock is context dependent, so need to generate as part of the parent record, and in the parent record context.
- */
|