deftype.cpp 104 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "platform.h"
  14. #if defined(_DEBUG) && defined(_WIN32) && !defined(USING_MPATROL)
  15. #undef new
  16. #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
  17. #endif
  18. #include "jlib.hpp"
  19. #include "jstream.hpp"
  20. #include "jmisc.hpp"
  21. #include "defvalue.hpp"
  22. #include "jexcept.hpp"
  23. #include "deftype.ipp"
  24. #include <stdio.h>
  25. #include <math.h>
  26. #include <algorithm>
  27. #include "rtlbcd.hpp"
  28. #include "eclrtl.hpp"
  29. #include "eclrtl_imp.hpp"
  30. #if defined(_DEBUG) && defined(_WIN32) && !defined(USING_MPATROL)
  31. #undef new
  32. #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
  33. #endif
  34. //#define DATA_STRING_COMPATIBLE
  35. #define HASHFIELD(p) hashcode = hashc((unsigned char *) &p, sizeof(p), hashcode)
  36. static IAtom * asciiAtom;
  37. static IAtom * dataAtom;
  38. static IAtom * ebcdicAtom;
  39. static IAtom * utf8Atom;
  40. static IAtom * asciiCodepageAtom;
  41. static IAtom * ebcdicCodepageAtom;
  42. static IAtom * ascii2ebcdicAtom;
  43. static IAtom * ebcdic2asciiAtom;
  44. static IAtom * emptyAtom;
  45. static CriticalSection * typeCS;
  46. static TypeCache * globalTypeCache;
  47. static CBoolTypeInfo *btt = NULL;
  48. static CBlobTypeInfo *bltt = NULL;
  49. static CVoidTypeInfo *vtt = NULL;
  50. static CNullTypeInfo *ntt = NULL;
  51. static CRecordTypeInfo *rtt = NULL;
  52. static CAnyTypeInfo *anytt = NULL;
  53. static CPatternTypeInfo *patt = NULL;
  54. static CTokenTypeInfo *tokentt = NULL;
  55. static CFeatureTypeInfo *featurett = NULL;
  56. static CStringTypeToTypeMap * stt;
  57. static CStringTypeToTypeMap * datatt;
  58. static CStringTypeToTypeMap * vstt;
  59. static CStringTypeToTypeMap * qstt;
  60. static CUnicodeTypeToTypeMap * utt;
  61. static CUnicodeTypeToTypeMap * vutt;
  62. static CUnicodeTypeToTypeMap * u8tt;
  63. static CIntTypeInfo *itt[2][8];
  64. static CSwapIntTypeInfo *sitt[2][8];
  65. static TypeToTypeMap * pitt;
  66. static CRealTypeInfo *realtt[10];
  67. static CBitfieldTypeInfo *bftt[64][8];
  68. static CCharTypeInfo * ctt[2];
  69. static TypeToTypeMap * setTT;
  70. static CEventTypeInfo *ett = NULL;
  71. //charssets and collation...
  72. static ICharsetInfo * dataCharset;
  73. static ICharsetInfo * asciiCharset;
  74. static ICharsetInfo * ebcdicCharset;
  75. static ICharsetInfo * utf8Charset;
  76. static ICollationInfo * asciiCollation;
  77. static ICollationInfo * ebcdicCollation;
  78. static ITranslationInfo * ascii2ebcdic;
  79. static ITranslationInfo * ebcdic2ascii;
  80. //---------------------------------------------------------------------------
  81. MODULE_INIT(INIT_PRIORITY_DEFTYPE)
  82. {
  83. typeCS = new CriticalSection;
  84. asciiAtom = createLowerCaseAtom("ascii");
  85. dataAtom = createLowerCaseAtom("data");
  86. ebcdicAtom = createLowerCaseAtom("ebcdic");
  87. utf8Atom = createLowerCaseAtom("utf-8");
  88. asciiCodepageAtom = createLowerCaseAtom(ASCII_LIKE_CODEPAGE);
  89. ebcdicCodepageAtom = createLowerCaseAtom("IBM037");
  90. ascii2ebcdicAtom = createAtom("ascii2ebcdic");
  91. ebcdic2asciiAtom = createAtom("ebcdic2ascii");
  92. emptyAtom = createAtom("");
  93. globalTypeCache = new TypeCache;
  94. stt = new CStringTypeToTypeMap;
  95. datatt = new CStringTypeToTypeMap;
  96. vstt = new CStringTypeToTypeMap;
  97. qstt = new CStringTypeToTypeMap;
  98. utt = new CUnicodeTypeToTypeMap;
  99. vutt = new CUnicodeTypeToTypeMap;
  100. u8tt = new CUnicodeTypeToTypeMap;
  101. pitt = new TypeToTypeMap;
  102. setTT = new TypeToTypeMap;
  103. return 1;
  104. }
  105. MODULE_EXIT()
  106. {
  107. ClearTypeCache();
  108. delete globalTypeCache;
  109. delete stt;
  110. delete datatt;
  111. delete vstt;
  112. delete qstt;
  113. delete utt;
  114. delete vutt;
  115. delete u8tt;
  116. delete pitt;
  117. delete setTT;
  118. delete typeCS;
  119. }
  120. //---------------------------------------------------------------------------
  121. int cards[] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
  122. unsigned promotedIntSize[9] = { 0, 1, 2, 4, 4, 8, 8, 8, 8 };
  123. //===========================================================================
  124. ITypeInfo *makeType(type_t type, int size)
  125. {
  126. switch (type)
  127. {
  128. case type_string:
  129. return makeStringType(size, NULL, NULL); // MORE!!
  130. case type_varstring:
  131. return makeVarStringType(size);
  132. case type_qstring:
  133. return makeQStringType(size);
  134. case type_unicode:
  135. return makeUnicodeType(size, 0);
  136. case type_varunicode:
  137. return makeVarUnicodeType(size, 0);
  138. case type_utf8:
  139. return makeUtf8Type(size, 0);
  140. case type_data:
  141. return makeDataType(size);
  142. case type_int:
  143. return makeIntType(size, false);
  144. case type_swapint:
  145. return makeSwapIntType(size, false);
  146. case type_packedint:
  147. return makePackedIntType(size, false);
  148. case type_real:
  149. return makeRealType(size);
  150. case type_bitfield:
  151. return makeBitfieldType(size);
  152. case type_boolean:
  153. return makeBoolType();
  154. case type_blob:
  155. return makeBlobType();
  156. case type_void:
  157. return makeVoidType();
  158. case type_null:
  159. return makeNullType();
  160. case type_record:
  161. return makeRecordType();
  162. case type_pattern:
  163. return makePatternType();
  164. case type_rule:
  165. return makeRuleType(NULL);
  166. case type_token:
  167. return makeTokenType();
  168. case type_feature:
  169. return makeFeatureType();
  170. case type_event:
  171. return makeEventType();
  172. case type_any:
  173. return makeAnyType();
  174. case type_date:
  175. return makeBoolType(); // JCSMORE: Todo.
  176. }
  177. return NULL;
  178. }
  179. static IValue * castViaString(ITypeInfo * type, size32_t len, const char * text)
  180. {
  181. Owned<IValue> temp = createStringValue(text, len);
  182. return temp->castTo(type);
  183. }
  184. static IValue * castViaString(ITypeInfo * type, bool isSignedValue, __int64 value, int len)
  185. {
  186. Owned<ITypeInfo> stype = makeStringType(len, NULL, NULL);
  187. Owned<IValue> temp = createIntValue(value, 8, isSignedValue);
  188. Owned<IValue> temp2 = temp->castTo(stype);
  189. return temp2->castTo(type);
  190. }
  191. bool isAscii(ITypeInfo * type)
  192. {
  193. return type->queryCharset()->queryName() == asciiAtom;
  194. }
  195. //===========================================================================
  196. CTypeInfo::~CTypeInfo()
  197. {
  198. }
  199. IValue * CTypeInfo::castFrom(double value)
  200. {
  201. //NB: Force VMT use...
  202. if (value < 0)
  203. return ((ITypeInfo *)this)->castFrom(true, (__int64)value);
  204. return ((ITypeInfo *)this)->castFrom(false, (__int64)(unsigned __int64)value);
  205. }
  206. IValue * CTypeInfo::castFrom(size32_t len, const UChar * text)
  207. {
  208. unsigned bufflen;
  209. rtlDataAttr buff;
  210. rtlUnicodeToStrX(bufflen, buff.refstr(), len, text);
  211. return ((ITypeInfo *)this)->castFrom(bufflen, buff.getstr());
  212. }
  213. unsigned CTypeInfo::getCardinality()
  214. {
  215. if (length < 4)
  216. return 1U << (length * 8);
  217. return (unsigned)-1;
  218. }
  219. unsigned CTypeInfo::getCrc()
  220. {
  221. unsigned crc = getTypeCode();
  222. crc = hashc((const byte *)&length, sizeof(length), crc);
  223. return crc;
  224. }
  225. unsigned CTypeInfo::getHash() const
  226. {
  227. unsigned hashcode = getHashKind();
  228. HASHFIELD(length);
  229. return hashcode;
  230. }
  231. bool CTypeInfo::equals(const CTypeInfo & other) const
  232. {
  233. return (getHashKind() == other.getHashKind()) && (length == other.length);
  234. }
  235. void CHashedTypeInfo::addObserver(IObserver & observer)
  236. {
  237. assertex(!observed);
  238. assert(&observer == globalTypeCache);
  239. observed = true;
  240. }
  241. void CHashedTypeInfo::removeObserver(IObserver & observer)
  242. {
  243. assertex(observed);
  244. assert(&observer == globalTypeCache);
  245. observed = false;
  246. }
  247. void CHashedTypeInfo::beforeDispose()
  248. {
  249. CriticalBlock block(*typeCS);
  250. if (observed)
  251. globalTypeCache->removeExact(this);
  252. assertex(!observed);
  253. }
  254. //===========================================================================
  255. inline unsigned getPromotedBitfieldSize(unsigned len)
  256. {
  257. if (len <= 8)
  258. return 1;
  259. else if (len <= 16)
  260. return 2;
  261. else if (len <= 32)
  262. return 4;
  263. else
  264. return 8;
  265. }
  266. inline ITypeInfo * getPromotedBitfieldType(unsigned len)
  267. {
  268. return makeIntType(getPromotedBitfieldSize(len), false);
  269. }
  270. CBitfieldTypeInfo::CBitfieldTypeInfo(int _length, ITypeInfo * _baseType) : CTypeInfo((_length+7)/8), bitLength(_length)
  271. {
  272. storeType = _baseType;
  273. promoted = getPromotedBitfieldType(_length);
  274. }
  275. bool CBitfieldTypeInfo::assignableFrom(ITypeInfo *t2)
  276. {
  277. switch (t2->getTypeCode())
  278. {
  279. case type_real: case type_int: case type_decimal: case type_swapint: case type_bitfield: case type_any: case type_packedint:
  280. return true;
  281. }
  282. return false;
  283. }
  284. IValue * CBitfieldTypeInfo::castFrom(bool isSignedValue, __int64 value)
  285. {
  286. return createBitfieldValue(value, LINK(this));
  287. }
  288. IValue * CBitfieldTypeInfo::castFrom(size32_t len, const char * text)
  289. {
  290. unsigned __int64 value;
  291. if (false)//typeIsSigned)
  292. value = rtlStrToInt8(len, text);
  293. else
  294. value = rtlStrToUInt8(len, text);
  295. return createBitfieldValue(value, LINK(this));
  296. }
  297. unsigned CBitfieldTypeInfo::getCrc()
  298. {
  299. unsigned crc = CTypeInfo::getCrc();
  300. crc = hashc((const byte *)&bitLength, sizeof(bitLength), crc);
  301. unsigned childCrc = storeType->getCrc();
  302. crc = hashc((const byte *)&childCrc, sizeof(childCrc), crc);
  303. return crc;
  304. }
  305. StringBuffer &CBitfieldTypeInfo::getECLType(StringBuffer &out)
  306. {
  307. out.append("bitfield").append(bitLength);
  308. if (storeType->getSize() != getPromotedBitfieldSize(bitLength))
  309. out.append("_").append(storeType->getSize());
  310. return out;
  311. }
  312. //---------------------------------------------------------------------------
  313. bool CIntTypeInfo::assignableFrom(ITypeInfo *t2)
  314. {
  315. switch (t2->getTypeCode())
  316. {
  317. case type_real: case type_int: case type_decimal: case type_swapint: case type_bitfield: case type_any: case type_packedint:
  318. return true;
  319. }
  320. return false;
  321. }
  322. unsigned CIntTypeInfo::getStringLen(void)
  323. {
  324. unsigned sign = isSigned() ? 1 : 0;
  325. return getDigits() + sign;
  326. }
  327. unsigned CIntTypeInfo::getDigits(void)
  328. {
  329. switch (length)
  330. {
  331. case 1: return 3;
  332. case 2: return 5;
  333. case 3: return 8;
  334. case 4: return 10;
  335. case 5: return 13;
  336. case 6: return 15;
  337. case 7: return 17;
  338. case 8: return 20;
  339. }
  340. assertex(false);
  341. return 0;
  342. }
  343. unsigned CIntTypeInfo::getCrc()
  344. {
  345. unsigned crc = CTypeInfo::getCrc();
  346. crc = hashc((const byte *)&typeIsSigned, sizeof(typeIsSigned), crc);
  347. return crc;
  348. }
  349. StringBuffer &CIntTypeInfo::getECLType(StringBuffer &out)
  350. {
  351. if (!typeIsSigned)
  352. out.append("unsigned");
  353. else
  354. out.append("integer");
  355. if(length >0)
  356. out.append(length);
  357. return out;
  358. }
  359. //---------------------------------------------------------------------------
  360. StringBuffer &CSwapIntTypeInfo::getECLType(StringBuffer &out)
  361. {
  362. #if __BYTE_ORDER == __LITTLE_ENDIAN
  363. out.append("big_endian ");
  364. #else
  365. out.append("little_endian ");
  366. #endif
  367. if (!typeIsSigned)
  368. out.append("unsigned ");
  369. out.append("integer");
  370. if(length >0)
  371. out.append(length);
  372. return out;
  373. }
  374. //---------------------------------------------------------------------------
  375. bool CPackedIntTypeInfo::assignableFrom(ITypeInfo *t2)
  376. {
  377. switch (t2->getTypeCode())
  378. {
  379. case type_real: case type_int: case type_decimal: case type_swapint: case type_bitfield: case type_any: case type_packedint:
  380. return true;
  381. }
  382. return false;
  383. }
  384. unsigned CPackedIntTypeInfo::getCrc()
  385. {
  386. return CTypeInfo::getCrc() ^ basetype->getCrc();
  387. }
  388. StringBuffer &CPackedIntTypeInfo::getECLType(StringBuffer &out)
  389. {
  390. out.append("packed ");
  391. if (!isSigned())
  392. out.append("unsigned ");
  393. out.append("integer");
  394. out.append(basetype->getSize());
  395. return out;
  396. }
  397. IValue * CPackedIntTypeInfo::castFrom(bool isSignedValue, __int64 value)
  398. {
  399. return createTruncIntValue(value, LINK(this));
  400. }
  401. IValue * CPackedIntTypeInfo::castFrom(size32_t len, const char * text)
  402. {
  403. unsigned __int64 value;
  404. if (basetype->isSigned())
  405. value = rtlStrToInt8(len, text);
  406. else
  407. value = rtlStrToUInt8(len, text);
  408. return createTruncIntValue(value, LINK(this));
  409. }
  410. //---------------------------------------------------------------------------
  411. unsigned CRealTypeInfo::getStringLen(void)
  412. {
  413. switch (length)
  414. { // sign + digits + dot + E+-<digits>
  415. case 4: return 1 + FLOAT_SIG_DIGITS + 1 + 4;
  416. case 8: return 1 + DOUBLE_SIG_DIGITS + 1 + 5;
  417. }
  418. assertex(false);
  419. return 0;
  420. }
  421. unsigned CRealTypeInfo::getDigits(void)
  422. {
  423. switch (length)
  424. {
  425. case 4: return FLOAT_SIG_DIGITS;
  426. case 8: return DOUBLE_SIG_DIGITS;
  427. }
  428. assertex(false);
  429. return 0;
  430. }
  431. IValue * CRealTypeInfo::castFrom(bool isSignedValue, __int64 value)
  432. {
  433. if (isSignedValue)
  434. return createRealValue((double)value, LINK(this));
  435. return createRealValue((double)(unsigned __int64)value, LINK(this));
  436. }
  437. IValue * CRealTypeInfo::castFrom(double value)
  438. {
  439. return createRealValue(value, LINK(this));
  440. }
  441. IValue * CRealTypeInfo::castFrom(size32_t len, const char * text)
  442. {
  443. return createRealValue(rtlStrToReal(len, text), LINK(this));
  444. }
  445. StringBuffer &CRealTypeInfo::getECLType(StringBuffer &out)
  446. {
  447. out.append("real");
  448. if(length >0)
  449. out.append(length);
  450. return out;
  451. }
  452. bool CRealTypeInfo::assignableFrom(ITypeInfo *t2)
  453. {
  454. switch (t2->getTypeCode())
  455. {
  456. case type_real: case type_int: case type_decimal: case type_swapint: case type_bitfield: case type_any: case type_packedint:
  457. return true;
  458. }
  459. return false;
  460. }
  461. //---------------------------------------------------------------------------
  462. inline unsigned cvtDigitsToLength(bool isSigned, unsigned digits)
  463. {
  464. if (digits == UNKNOWN_LENGTH)
  465. return UNKNOWN_LENGTH;
  466. return isSigned ? digits/2+1 : (digits+1)/2;
  467. }
  468. CDecimalTypeInfo::CDecimalTypeInfo(unsigned _digits, unsigned _prec, bool _isSigned)
  469. : CHashedTypeInfo(cvtDigitsToLength(_isSigned, _digits))
  470. {
  471. digits = (_digits == UNKNOWN_LENGTH) ? UNKNOWN_DIGITS : (byte)_digits;
  472. prec = (_prec == UNKNOWN_LENGTH) ? UNKNOWN_DIGITS : (byte)_prec;
  473. typeIsSigned = _isSigned;
  474. };
  475. IValue * CDecimalTypeInfo::createValueFromStack()
  476. {
  477. Linked<ITypeInfo> retType;
  478. if ((length == UNKNOWN_LENGTH) || (length == MAX_DECIMAL_LEADING + MAX_DECIMAL_PRECISION))
  479. {
  480. unsigned tosDigits, tosPrecision;
  481. DecClipInfo(tosDigits, tosPrecision);
  482. unsigned tosLeading = tosDigits - tosPrecision;
  483. if (tosLeading > MAX_DECIMAL_LEADING)
  484. tosLeading = MAX_DECIMAL_LEADING;
  485. if (tosPrecision > MAX_DECIMAL_PRECISION)
  486. tosPrecision = MAX_DECIMAL_PRECISION;
  487. Owned<ITypeInfo> newType = makeDecimalType(tosLeading+tosPrecision, tosPrecision, typeIsSigned);
  488. return createDecimalValueFromStack(newType);
  489. }
  490. void * val = alloca(length);
  491. DecSetPrecision(getDigits(), prec);
  492. if (typeIsSigned)
  493. DecPopDecimal(val, length, prec);
  494. else
  495. DecPopUDecimal(val, length, prec);
  496. return createDecimalValue(val, LINK(this));
  497. }
  498. IValue * CDecimalTypeInfo::castFrom(bool isSignedValue, __int64 value)
  499. {
  500. BcdCriticalBlock bcdBlock;
  501. if (isSignedValue)
  502. DecPushInt64(value);
  503. else
  504. DecPushUInt64(value);
  505. return createValueFromStack();
  506. }
  507. IValue * CDecimalTypeInfo::castFrom(double value)
  508. {
  509. DecPushReal(value);
  510. return createValueFromStack();
  511. }
  512. IValue * CDecimalTypeInfo::castFrom(size32_t len, const char * text)
  513. {
  514. DecPushString(len, text);
  515. return createValueFromStack();
  516. }
  517. unsigned CDecimalTypeInfo::getHash() const
  518. {
  519. unsigned hashcode = CHashedTypeInfo::getHash();
  520. HASHFIELD(prec);
  521. HASHFIELD(digits);
  522. HASHFIELD(typeIsSigned);
  523. return hashcode;
  524. }
  525. bool CDecimalTypeInfo::equals(const CTypeInfo & _other) const
  526. {
  527. if (!CHashedTypeInfo::equals(_other))
  528. return false;
  529. const CDecimalTypeInfo & other = static_cast<const CDecimalTypeInfo &>(_other);
  530. return (prec == other.prec) && (digits == other.digits) && (typeIsSigned == other.typeIsSigned);
  531. }
  532. unsigned CDecimalTypeInfo::getStringLen(void)
  533. {
  534. if (length == UNKNOWN_LENGTH)
  535. return UNKNOWN_LENGTH;
  536. return (typeIsSigned ? 1 : 0) + getDigits() + (prec ? 1 : 0); // sign + digits + dot
  537. }
  538. StringBuffer &CDecimalTypeInfo::getECLType(StringBuffer &out)
  539. {
  540. if (!typeIsSigned)
  541. out.append('u');
  542. out.append("decimal");
  543. if (digits != UNKNOWN_DIGITS)
  544. {
  545. out.append((int)digits);
  546. if (prec)
  547. out.append("_").append((int)prec);
  548. }
  549. return out;
  550. }
  551. bool CDecimalTypeInfo::assignableFrom(ITypeInfo *t2)
  552. {
  553. switch (t2->getTypeCode())
  554. {
  555. case type_real: case type_int: case type_decimal: case type_swapint: case type_any: case type_packedint:
  556. return true;
  557. }
  558. return false;
  559. }
  560. unsigned CDecimalTypeInfo::getBitSize()
  561. {
  562. if (digits == UNKNOWN_DIGITS)
  563. return UNKNOWN_LENGTH;
  564. if (typeIsSigned)
  565. return (digits+1)*4;
  566. else
  567. return digits*4;
  568. };
  569. unsigned CDecimalTypeInfo::getCrc()
  570. {
  571. unsigned crc = CTypeInfo::getCrc();
  572. crc = hashc((const byte *)&typeIsSigned, sizeof(typeIsSigned), crc);
  573. crc = hashc((const byte *)&prec, sizeof(prec), crc);
  574. crc = hashc((const byte *)&digits, sizeof(digits), crc);
  575. return crc;
  576. }
  577. void CDecimalTypeInfo::serialize(MemoryBuffer &tgt)
  578. {
  579. CTypeInfo::serialize(tgt);
  580. tgt.append(prec);
  581. tgt.append(digits);
  582. tgt.append(typeIsSigned);
  583. }
  584. //---------------------------------------------------------------------------
  585. bool CBoolTypeInfo::assignableFrom(ITypeInfo *t2)
  586. {
  587. // FIX: only bool or int type can be assigned to a bool type
  588. //return (t2->isScalar());
  589. switch(t2->getTypeCode())
  590. {
  591. case type_boolean:
  592. case type_int:
  593. case type_any:
  594. return true;
  595. }
  596. return false;
  597. }
  598. IValue * CBoolTypeInfo::castFrom(bool /*isSignedValue*/, __int64 value)
  599. {
  600. return createBoolValue(value != 0);
  601. }
  602. IValue * CBoolTypeInfo::castFrom(size32_t len, const char * text)
  603. {
  604. return castViaString(this, len, text);
  605. }
  606. StringBuffer &CBoolTypeInfo::getECLType(StringBuffer &out)
  607. {
  608. return out.append("boolean");
  609. }
  610. //---------------------------------------------------------------------------
  611. IValue * CVoidTypeInfo::castFrom(bool isSignedValue, __int64 value)
  612. {
  613. return NULL;
  614. }
  615. IValue * CVoidTypeInfo::castFrom(size32_t len, const char * text)
  616. {
  617. return NULL;
  618. }
  619. StringBuffer &CVoidTypeInfo::getECLType(StringBuffer &out)
  620. {
  621. return out;
  622. }
  623. //---------------------------------------------------------------------------
  624. //Make crc match void for backward compatibility
  625. unsigned CNullTypeInfo::getCrc()
  626. {
  627. unsigned crc = type_void;
  628. crc = hashc((const byte *)&length, sizeof(length), crc);
  629. return crc;
  630. }
  631. //---------------------------------------------------------------------------
  632. IValue * CAnyTypeInfo::castFrom(bool isSignedValue, __int64 value)
  633. {
  634. return createIntValue(value, sizeof(__int64), isSignedValue);
  635. }
  636. IValue * CAnyTypeInfo::castFrom(size32_t len, const char * text)
  637. {
  638. return createStringValue(text, len);
  639. }
  640. IValue * CAnyTypeInfo::castFrom(double value)
  641. {
  642. return createRealValue(value, sizeof(double));
  643. }
  644. StringBuffer &CAnyTypeInfo::getECLType(StringBuffer &out)
  645. {
  646. return out.append("any");
  647. }
  648. //---------------------------------------------------------------------------
  649. CStringTypeInfo::CStringTypeInfo(unsigned _length, ICharsetInfo * _charset, ICollationInfo * _collation) : CTypeInfo(_length), charset(_charset), collation(_collation)
  650. {
  651. if (!charset)
  652. charset.setown(getCharset(NULL));
  653. if (!collation)
  654. collation.set(charset->queryDefaultCollation());
  655. }
  656. unsigned cardGuesses[] = { 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
  657. unsigned CStringTypeInfo::getCardinality()
  658. {
  659. // Wild guess at cardinalities. Probably more accurate than the default integer variety...
  660. unsigned numChars = getStringLen();
  661. if (numChars < 10)
  662. return cardGuesses[numChars];
  663. return (unsigned)-1;
  664. }
  665. bool CStringTypeInfo::assignableFrom(ITypeInfo *t2)
  666. {
  667. switch (t2->getTypeCode())
  668. {
  669. case type_string: case type_varstring:
  670. case type_qstring: case type_any:
  671. #ifdef DATA_STRING_COMPATIBLE
  672. case type_data:
  673. #endif
  674. return true;
  675. }
  676. return false;
  677. }
  678. IValue * CStringTypeInfo::castFrom(bool isSignedValue, __int64 value)
  679. {
  680. return castViaString(this, isSignedValue, value, getStringLen());
  681. }
  682. IValue * CStringTypeInfo::castFrom(double value)
  683. {
  684. char * text = NULL;
  685. unsigned length = getStringLen();
  686. if (length == UNKNOWN_LENGTH)
  687. {
  688. rtlRealToStrX(length, text, value);
  689. }
  690. else
  691. {
  692. text = (char *)malloc(length);
  693. rtlRealToStr(length, text, value);
  694. }
  695. IValue * ret = castFrom(length, text);
  696. free(text);
  697. return ret;
  698. }
  699. IValue * CStringTypeInfo::castFrom(size32_t len, const char * text)
  700. {
  701. Owned<ICharsetInfo> ascii = getCharset(asciiAtom);
  702. return createStringValue(text, LINK(this), len, ascii);
  703. }
  704. unsigned CStringTypeInfo::getCrc()
  705. {
  706. unsigned crc = CTypeInfo::getCrc();
  707. if (charset)
  708. {
  709. const char * name = str(charset->queryName());
  710. //MORE: This and following should really be case insensitive, but we get away with it at the moment because the atoms are created very early
  711. crc = hashc((const byte *)name, (size32_t)strlen(name), crc);
  712. }
  713. if (collation)
  714. {
  715. const char * name = str(collation->queryName());
  716. crc = hashc((const byte *)name, (size32_t)strlen(name), crc);
  717. }
  718. return crc;
  719. }
  720. StringBuffer &CStringTypeInfo::getECLType(StringBuffer &out)
  721. {
  722. if (charset->queryName() == ebcdicAtom)
  723. out.append("EBCDIC ");
  724. out.append("string");
  725. if (length != UNKNOWN_LENGTH)
  726. out.append(length);
  727. return out;
  728. }
  729. StringBuffer &CStringTypeInfo::getDescriptiveType(StringBuffer &out)
  730. {
  731. out.append("string");
  732. if (length != UNKNOWN_LENGTH)
  733. out.append(length);
  734. if(charset || collation)
  735. {
  736. out.append(" (");
  737. if(charset) out.append("charset:").append(str(charset->queryName()));
  738. if(charset && collation) out.append(", ");
  739. if(collation) out.append("collation:").append(str(collation->queryName()));
  740. out.append(")");
  741. }
  742. return out;
  743. }
  744. //---------------------------------------------------------------------------
  745. unsigned CUnicodeTypeInfo::getCardinality()
  746. {
  747. // Wild guess at cardinalities. Probably more accurate than the default integer variety...
  748. if (length < 19)
  749. return cardGuesses[(length+1)/2];
  750. return (unsigned)-1;
  751. }
  752. IValue * CUnicodeTypeInfo::castFrom(bool isSignedValue, __int64 value)
  753. {
  754. Owned<ITypeInfo> asciiType = makeStringType(getStringLen(), 0, 0);
  755. Owned<IValue> asciiValue = asciiType->castFrom(isSignedValue, value);
  756. return asciiValue->castTo(this);
  757. }
  758. IValue * CUnicodeTypeInfo::castFrom(double value)
  759. {
  760. Owned<ITypeInfo> asciiType = makeStringType(getStringLen(), 0, 0);
  761. Owned<IValue> asciiValue = asciiType->castFrom(value);
  762. return asciiValue->castTo(this);
  763. }
  764. IValue * CUnicodeTypeInfo::castFrom(size32_t len, const char * text)
  765. {
  766. Owned<IValue> unicodeValue = createUnicodeValue(text, len, str(locale), false);
  767. return unicodeValue->castTo(this);
  768. }
  769. IValue * CUnicodeTypeInfo::castFrom(size32_t len, const UChar * uchars)
  770. {
  771. return createUnicodeValue(len, uchars, LINK(this));
  772. }
  773. StringBuffer &CUnicodeTypeInfo::getECLType(StringBuffer &out)
  774. {
  775. out.append("unicode");
  776. if(locale && *str(locale))
  777. out.append('_').append(str(locale));
  778. if(length != UNKNOWN_LENGTH)
  779. out.append(length/2);
  780. return out;
  781. }
  782. bool CUnicodeTypeInfo::assignableFrom(ITypeInfo *t2)
  783. {
  784. switch (t2->getTypeCode())
  785. {
  786. case type_any:
  787. return true;
  788. }
  789. //All string types can be converted to unicode with no loss of information, so allow an assign without a cast
  790. if (isStringType(t2))
  791. return true;
  792. return isUnicodeType(t2) && haveCommonLocale(this, t2);
  793. }
  794. //---------------------------------------------------------------------------
  795. CVarUnicodeTypeInfo::CVarUnicodeTypeInfo(unsigned len, IAtom * _locale) : CUnicodeTypeInfo(len, _locale)
  796. {
  797. #if UNKNOWN_LENGTH != 0
  798. assertex(len != 0);
  799. #endif
  800. };
  801. IValue * CVarUnicodeTypeInfo::castFrom(size32_t len, const char * text)
  802. {
  803. Owned<IValue> unicodeValue = createVarUnicodeValue(text, len, str(locale), false);
  804. return unicodeValue->castTo(this);
  805. }
  806. IValue * CVarUnicodeTypeInfo::castFrom(size32_t len, const UChar * uchars)
  807. {
  808. return createVarUnicodeValue(len, uchars, LINK(this));
  809. }
  810. StringBuffer & CVarUnicodeTypeInfo::getECLType(StringBuffer & out)
  811. {
  812. out.append("varunicode");
  813. if(locale && *str(locale))
  814. out.append('_').append(str(locale));
  815. if(length != UNKNOWN_LENGTH)
  816. out.append(length/2-1);
  817. return out;
  818. }
  819. //---------------------------------------------------------------------------
  820. IValue * CUtf8TypeInfo::castFrom(size32_t len, const UChar * uchars)
  821. {
  822. unsigned tlen = getStringLen();
  823. if (tlen == UNKNOWN_LENGTH)
  824. tlen = len;
  825. rtlDataAttr buff(tlen * 4);
  826. rtlUnicodeToUtf8(tlen, buff.getstr(), len, uchars);
  827. return createUtf8Value(tlen, buff.getstr(), LINK(this));
  828. }
  829. StringBuffer &CUtf8TypeInfo::getECLType(StringBuffer &out)
  830. {
  831. out.append("utf8");
  832. if(locale && *str(locale))
  833. out.append('_').append(str(locale));
  834. if(length != UNKNOWN_LENGTH)
  835. out.append('_').append(length/4);
  836. return out;
  837. }
  838. //---------------------------------------------------------------------------
  839. CDataTypeInfo::CDataTypeInfo(int _length) : CStringTypeInfo(_length, getCharset(dataAtom), NULL)
  840. {
  841. }
  842. StringBuffer &CDataTypeInfo::getECLType(StringBuffer &out)
  843. {
  844. if(length != UNKNOWN_LENGTH && length != INFINITE_LENGTH)
  845. return out.append("data").append(length);
  846. else
  847. return out.append("data");
  848. }
  849. bool CDataTypeInfo::assignableFrom(ITypeInfo *t2)
  850. {
  851. switch (t2->getTypeCode())
  852. {
  853. case type_data:
  854. case type_any:
  855. #ifdef DATA_STRING_COMPATIBLE
  856. case type_string: case type_varstring:
  857. #endif
  858. return true;
  859. }
  860. return false;
  861. }
  862. //---------------------------------------------------------------------------
  863. CVarStringTypeInfo::CVarStringTypeInfo(unsigned len, ICharsetInfo * _charset, ICollationInfo * _collation) :
  864. CStringTypeInfo(len, _charset, _collation)
  865. {
  866. #if UNKNOWN_LENGTH != 0
  867. assertex(len != 0);
  868. #endif
  869. };
  870. IValue * CVarStringTypeInfo::castFrom(size32_t len, const char * text)
  871. {
  872. Owned<ICharsetInfo> ascii = getCharset(asciiAtom);
  873. return createVarStringValue(text, LINK(this), len, ascii);
  874. }
  875. StringBuffer &CVarStringTypeInfo::getECLType(StringBuffer &out)
  876. {
  877. out.append("varstring");
  878. if (length != UNKNOWN_LENGTH)
  879. out.append(length-1);
  880. return out;
  881. }
  882. StringBuffer &CVarStringTypeInfo::getDescriptiveType(StringBuffer &out)
  883. {
  884. out.append("varstring");
  885. if (length != UNKNOWN_LENGTH)
  886. out.append(length-1);
  887. if(charset || collation)
  888. {
  889. out.append(" (");
  890. if(charset) out.append("charset:").append(str(charset->queryName()));
  891. if(charset && collation) out.append(", ");
  892. if(collation) out.append("collation:").append(str(collation->queryName()));
  893. out.append(")");
  894. }
  895. return out;
  896. }
  897. //---------------------------------------------------------------------------
  898. CQStringTypeInfo::CQStringTypeInfo(unsigned _strLength) : CStringTypeInfo(_strLength == UNKNOWN_LENGTH ? UNKNOWN_LENGTH : rtlQStrSize(_strLength), NULL, NULL)
  899. {
  900. strLength = _strLength;
  901. }
  902. #if 0
  903. bool CQStringTypeInfo::assignableFrom(ITypeInfo *t2)
  904. {
  905. switch (t2->getTypeCode())
  906. {
  907. case type_qstring:
  908. case type_any:
  909. return true;
  910. }
  911. return false;
  912. }
  913. #endif
  914. IValue * CQStringTypeInfo::castFrom(size32_t len, const char * text)
  915. {
  916. if (length != UNKNOWN_LENGTH)
  917. {
  918. if (len >= strLength)
  919. len = strLength;
  920. }
  921. return createQStringValue(len, text, LINK(this));
  922. }
  923. StringBuffer &CQStringTypeInfo::getECLType(StringBuffer &out)
  924. {
  925. out.append("qstring");
  926. if (length != UNKNOWN_LENGTH)
  927. out.append(strLength);
  928. return out;
  929. }
  930. //---------------------------------------------------------------------------
  931. IValue * CCharTypeInfo::castFrom(bool isSignedValue, __int64 value)
  932. {
  933. return castViaString(this, isSignedValue, value, 1);
  934. }
  935. StringBuffer &CCharTypeInfo::getECLType(StringBuffer &out)
  936. {
  937. assertex(false);
  938. return out;
  939. }
  940. IValue * CCharTypeInfo::castFrom(size32_t len, const char * text)
  941. {
  942. return createCharValue(len ? *text : ' ', caseSensitive);
  943. }
  944. //---------------------------------------------------------------------------
  945. IValue * CIntTypeInfo::castFrom(bool isSignedValue, __int64 value)
  946. {
  947. return createTruncIntValue(value, LINK(this));
  948. }
  949. IValue * CIntTypeInfo::castFrom(size32_t len, const char * text)
  950. {
  951. unsigned __int64 value;
  952. if (typeIsSigned)
  953. value = rtlStrToInt8(len, text);
  954. else
  955. value = rtlStrToUInt8(len, text);
  956. return createTruncIntValue(value, LINK(this));
  957. }
  958. //===========================================================================
  959. class StringValueMapper : public Mapping
  960. {
  961. size32_t index;
  962. public:
  963. StringValueMapper(const void *k, int ksize, size32_t index);
  964. size32_t getIndex() { return index; }
  965. };
  966. StringValueMapper::StringValueMapper(const void *_key, int _ksize, size32_t _index) : Mapping(_key, _ksize)
  967. {
  968. index = _index;
  969. }
  970. static int getIntSize(size32_t range)
  971. {
  972. if (range <= 0xff)
  973. return 1;
  974. else if (range <= 0xffff)
  975. return 2;
  976. else
  977. return 4;
  978. }
  979. //===========================================================================
  980. CEnumeratedTypeInfo::CEnumeratedTypeInfo(ITypeInfo *_base, size32_t _numValues)
  981. : CTypeInfo(getIntSize(_numValues)), valueMap(_base->getSize(), false), base(_base)
  982. {
  983. numValues = _numValues;
  984. // valueMap.setCapacity(_numValues);
  985. }
  986. StringBuffer &CEnumeratedTypeInfo::getECLType(StringBuffer &out)
  987. {
  988. assertex(false);
  989. return out;
  990. }
  991. ITypeInfo *CEnumeratedTypeInfo::getTypeInfo()
  992. {
  993. Link();
  994. return this;
  995. }
  996. int CEnumeratedTypeInfo::addValue(IValue *val, size32_t frequency)
  997. {
  998. assertex(!IsShared());
  999. size32_t baseSize = base->getSize();
  1000. assertex(val->queryType()==base);
  1001. void *buf = malloc(baseSize);
  1002. val->toMem(buf);
  1003. size32_t index = valueList.length();
  1004. valueMap.addOwn(*new StringValueMapper(buf, baseSize, index));
  1005. valueList.append(*val);
  1006. free(buf);
  1007. return index;
  1008. }
  1009. IValue *CEnumeratedTypeInfo::castFrom(bool isSignedValue, __int64 value)
  1010. {
  1011. return createEnumValue((int) value, LINK(this));
  1012. }
  1013. IValue *CEnumeratedTypeInfo::castFrom(size32_t len, const char * text)
  1014. {
  1015. MemoryAttr temp;
  1016. size32_t baselen = base->getSize();
  1017. if (len<baselen)
  1018. {
  1019. char *pad = (char *)temp.allocate(baselen);
  1020. memcpy(pad, text, len);
  1021. memset(pad+len, ' ', baselen-len);
  1022. text = pad;
  1023. }
  1024. StringValueMapper *ret = (StringValueMapper *) valueMap.find(text);
  1025. if (ret)
  1026. return createEnumValue(ret->getIndex(), LINK(this));
  1027. else
  1028. {
  1029. // assertex(false);
  1030. return NULL; // MORE - is this right?
  1031. }
  1032. }
  1033. IValue *CEnumeratedTypeInfo::queryValue(size32_t index)
  1034. {
  1035. if (valueList.isItem(index))
  1036. return (IValue *) &valueList.item(index);
  1037. else
  1038. return NULL;
  1039. }
  1040. ITypeInfo *CEnumeratedTypeInfo::queryBase()
  1041. {
  1042. return base;
  1043. }
  1044. extern DEFTYPE_API IEnumeratedTypeBuilder *makeEnumeratedTypeBuilder(ITypeInfo *base, aindex_t numValues)
  1045. {
  1046. return new CEnumeratedTypeInfo(base, numValues);
  1047. }
  1048. //===========================================================================
  1049. ITypeInfo *CBasedTypeInfo::queryChildType()
  1050. {
  1051. return basetype;
  1052. }
  1053. bool CBasedTypeInfo::assignableFrom(ITypeInfo *t2)
  1054. {
  1055. return getTypeCode()==t2->getTypeCode() && queryChildType()==t2->queryChildType();
  1056. }
  1057. unsigned CBasedTypeInfo::getHash() const
  1058. {
  1059. unsigned hashcode = CHashedTypeInfo::getHash();
  1060. HASHFIELD(basetype);
  1061. return hashcode;
  1062. }
  1063. bool CBasedTypeInfo::equals(const CTypeInfo & _other) const
  1064. {
  1065. if (!CHashedTypeInfo::equals(_other))
  1066. return false;
  1067. const CBasedTypeInfo & other = static_cast<const CBasedTypeInfo &>(_other);
  1068. return basetype == other.basetype;
  1069. }
  1070. void CBasedTypeInfo::serializeSkipChild(MemoryBuffer &tgt)
  1071. {
  1072. CTypeInfo::serialize(tgt);
  1073. ITypeInfo * child = basetype ? basetype->queryChildType() : NULL;
  1074. serializeType(tgt, child);
  1075. }
  1076. //===========================================================================
  1077. bool CTransformTypeInfo::assignableFrom(ITypeInfo *t2)
  1078. {
  1079. if (getTypeCode()==t2->getTypeCode())
  1080. {
  1081. ITypeInfo *c1 = queryChildType();
  1082. ITypeInfo *c2 = t2->queryChildType();
  1083. if (c1==NULL || c2==NULL || c1->assignableFrom(c2))
  1084. return true;
  1085. }
  1086. return false;
  1087. }
  1088. bool CSortListTypeInfo::assignableFrom(ITypeInfo *t2)
  1089. {
  1090. return (getTypeCode()==t2->getTypeCode());
  1091. {
  1092. //Not convinced any of this should be here...
  1093. ITypeInfo *c1 = queryChildType();
  1094. ITypeInfo *c2 = t2->queryChildType();
  1095. if (c1 == c2)
  1096. return true;
  1097. if (!c1 || !c2)
  1098. return false;
  1099. if (c1->assignableFrom(c2))
  1100. return true;
  1101. return false;
  1102. }
  1103. return queryChildType()->assignableFrom(t2);
  1104. }
  1105. bool CRowTypeInfo::assignableFrom(ITypeInfo *t2)
  1106. {
  1107. if (getTypeCode()==t2->getTypeCode())
  1108. {
  1109. ITypeInfo *c1 = queryChildType();
  1110. ITypeInfo *c2 = t2->queryChildType();
  1111. if (c1==NULL || c2==NULL || c1->assignableFrom(c2))
  1112. return true;
  1113. }
  1114. return false;
  1115. }
  1116. //===========================================================================
  1117. bool CDictionaryTypeInfo::assignableFrom(ITypeInfo *t2)
  1118. {
  1119. if (getTypeCode()==t2->getTypeCode())
  1120. {
  1121. ITypeInfo *c1 = queryChildType();
  1122. ITypeInfo *c2 = t2->queryChildType();
  1123. if (c1==NULL || c2==NULL || c1->assignableFrom(c2))
  1124. return true;
  1125. }
  1126. return false;
  1127. }
  1128. StringBuffer & CDictionaryTypeInfo::getECLType(StringBuffer & out)
  1129. {
  1130. ITypeInfo * recordType = ::queryRecordType(this);
  1131. out.append(queryTypeName());
  1132. if (recordType)
  1133. {
  1134. out.append(" of ");
  1135. recordType->getECLType(out);
  1136. }
  1137. return out;
  1138. }
  1139. void CDictionaryTypeInfo::serialize(MemoryBuffer &tgt)
  1140. {
  1141. CBasedTypeInfo::serializeSkipChild(tgt);
  1142. }
  1143. //===========================================================================
  1144. bool CTableTypeInfo::assignableFrom(ITypeInfo *t2)
  1145. {
  1146. if (getTypeCode()==t2->getTypeCode())
  1147. {
  1148. ITypeInfo *c1 = queryChildType();
  1149. ITypeInfo *c2 = t2->queryChildType();
  1150. if (c1==NULL || c2==NULL || c1->assignableFrom(c2))
  1151. return true;
  1152. }
  1153. return false;
  1154. }
  1155. StringBuffer & CTableTypeInfo::getECLType(StringBuffer & out)
  1156. {
  1157. ITypeInfo * recordType = ::queryRecordType(this);
  1158. out.append(queryTypeName());
  1159. if (recordType)
  1160. {
  1161. out.append(" of ");
  1162. recordType->getECLType(out);
  1163. }
  1164. return out;
  1165. }
  1166. void CTableTypeInfo::serialize(MemoryBuffer &tgt)
  1167. {
  1168. CBasedTypeInfo::serializeSkipChild(tgt);
  1169. }
  1170. bool CGroupedTableTypeInfo::assignableFrom(ITypeInfo *t2)
  1171. {
  1172. if (getTypeCode()==t2->getTypeCode())
  1173. {
  1174. ITypeInfo *c1 = queryChildType();
  1175. ITypeInfo *c2 = t2->queryChildType();
  1176. if (!c1 || !c2)
  1177. return c1==c2;
  1178. if (c1->assignableFrom(c2))
  1179. return true;
  1180. }
  1181. return false;
  1182. }
  1183. bool CSetTypeInfo::assignableFrom(ITypeInfo *t2)
  1184. {
  1185. return getTypeCode()==t2->getTypeCode() &&
  1186. (!queryChildType() || !t2->queryChildType() || queryChildType()->assignableFrom(t2->queryChildType()));
  1187. }
  1188. StringBuffer & CSetTypeInfo::getECLType(StringBuffer & out)
  1189. {
  1190. out.append(queryTypeName());
  1191. if (basetype)
  1192. {
  1193. out.append(" of ");
  1194. queryChildType()->getECLType(out);
  1195. }
  1196. else
  1197. out.append(" of any");
  1198. return out;
  1199. }
  1200. //===========================================================================
  1201. bool CFunctionTypeInfo::assignableFrom(ITypeInfo *t2)
  1202. {
  1203. return this == t2;
  1204. }
  1205. IInterface *CFunctionTypeInfo::queryModifierExtra()
  1206. {
  1207. return static_cast<IFunctionTypeExtra *>(this);
  1208. }
  1209. unsigned CFunctionTypeInfo::getHash() const
  1210. {
  1211. unsigned hashcode = CBasedTypeInfo::getHash();
  1212. HASHFIELD(parameters);
  1213. HASHFIELD(defaults);
  1214. return hashcode;
  1215. }
  1216. bool CFunctionTypeInfo::equals(const CTypeInfo & _other) const
  1217. {
  1218. if (!CBasedTypeInfo::equals(_other))
  1219. return false;
  1220. const CFunctionTypeInfo & other = static_cast<const CFunctionTypeInfo &>(_other);
  1221. return (parameters == other.parameters) && (defaults == other.defaults);
  1222. }
  1223. void CFunctionTypeInfo::serialize(MemoryBuffer &tgt)
  1224. {
  1225. throwUnexpected();
  1226. CBasedTypeInfo::serialize(tgt);
  1227. }
  1228. //===========================================================================
  1229. size32_t CArrayTypeInfo::getSize()
  1230. {
  1231. if (length == UNKNOWN_LENGTH)
  1232. return UNKNOWN_LENGTH;
  1233. if (basetype->isReference())
  1234. return length * sizeof(void *);
  1235. size32_t baseSize = basetype->getSize();
  1236. if (baseSize == UNKNOWN_LENGTH)
  1237. return UNKNOWN_LENGTH;
  1238. return baseSize * length;
  1239. }
  1240. //===========================================================================
  1241. unsigned CModifierTypeInfo::getHash() const
  1242. {
  1243. unsigned hashcode = CHashedTypeInfo::getHash();
  1244. HASHFIELD(baseType);
  1245. HASHFIELD(kind);
  1246. HASHFIELD(extra);
  1247. return hashcode;
  1248. }
  1249. bool CModifierTypeInfo::equals(const CTypeInfo & _other) const
  1250. {
  1251. if (!CHashedTypeInfo::equals(_other))
  1252. return false;
  1253. const CModifierTypeInfo & other = static_cast<const CModifierTypeInfo &>(_other);
  1254. return (baseType == other.baseType) && (kind == other.kind) && (extra == other.extra);
  1255. }
  1256. //===========================================================================
  1257. extern DEFTYPE_API ITypeInfo *makeStringType(unsigned len, ICharsetInfo * charset, ICollationInfo * collation)
  1258. {
  1259. if (!charset)
  1260. charset = getCharset(NULL);
  1261. if (!collation)
  1262. {
  1263. collation = charset->queryDefaultCollation();
  1264. collation->Link();
  1265. }
  1266. CStringTypeKey key;
  1267. key.length = len;
  1268. key.charset.set(charset);
  1269. key.collation.set(collation);
  1270. CriticalBlock procedure(*typeCS);
  1271. ITypeInfo *ret;
  1272. IInterface * * match = stt->getValue(key);
  1273. if (match)
  1274. {
  1275. ::Release(charset);
  1276. ::Release(collation);
  1277. ret = (ITypeInfo *)LINK(*match);
  1278. }
  1279. else
  1280. {
  1281. CStringTypeInfo* t = new CStringTypeInfo(len, charset, collation);
  1282. ret = t;
  1283. stt->setValue(key, ret);
  1284. }
  1285. return ret;
  1286. }
  1287. extern DEFTYPE_API ITypeInfo *makeVarStringType(unsigned len, ICharsetInfo * charset, ICollationInfo * collation)
  1288. {
  1289. //NB: Length passed is the number of characters....
  1290. unsigned size = (len != UNKNOWN_LENGTH) ? len + 1 : UNKNOWN_LENGTH;
  1291. //NB: Length passed is the number of characters....
  1292. if (!charset)
  1293. charset = getCharset(NULL);
  1294. if (!collation)
  1295. {
  1296. collation = charset->queryDefaultCollation();
  1297. collation->Link();
  1298. }
  1299. CStringTypeKey key;
  1300. key.length = size;
  1301. key.charset.set(charset);
  1302. key.collation.set(collation);
  1303. CriticalBlock procedure(*typeCS);
  1304. ITypeInfo *ret;
  1305. IInterface * * match = vstt->getValue(key);
  1306. if (match)
  1307. {
  1308. ::Release(charset);
  1309. ::Release(collation);
  1310. ret = (ITypeInfo *)LINK(*match);
  1311. }
  1312. else
  1313. {
  1314. ret = new CVarStringTypeInfo(size, charset, collation);
  1315. vstt->setValue(key, ret);
  1316. }
  1317. return ret;
  1318. }
  1319. extern DEFTYPE_API ITypeInfo *makeQStringType(int len)
  1320. {
  1321. CStringTypeKey key;
  1322. key.length = len;
  1323. key.charset.set(NULL);
  1324. key.collation.set(NULL);
  1325. CriticalBlock procedure(*typeCS);
  1326. ITypeInfo *ret;
  1327. IInterface * * match = qstt->getValue(key);
  1328. if (match)
  1329. {
  1330. ret = (ITypeInfo *)LINK(*match);
  1331. }
  1332. else
  1333. {
  1334. ret = new CQStringTypeInfo(len);
  1335. qstt->setValue(key, ret);
  1336. }
  1337. return ret;
  1338. }
  1339. extern DEFTYPE_API ITypeInfo *makeUnicodeType(unsigned len, IAtom * locale)
  1340. {
  1341. if(!locale)
  1342. locale = emptyAtom;
  1343. CUnicodeTypeKey key;
  1344. key.length = len;
  1345. key.locale.set(locale);
  1346. CriticalBlock procedure(*typeCS);
  1347. ITypeInfo *ret;
  1348. IInterface * * match = utt->getValue(key);
  1349. if(match)
  1350. ret = (ITypeInfo *)LINK(*match);
  1351. else
  1352. {
  1353. if(len == UNKNOWN_LENGTH)
  1354. ret = new CUnicodeTypeInfo(UNKNOWN_LENGTH, locale);
  1355. else
  1356. ret = new CUnicodeTypeInfo(len*2, locale);
  1357. utt->setValue(key, ret);
  1358. }
  1359. return ret;
  1360. }
  1361. extern DEFTYPE_API ITypeInfo *makeVarUnicodeType(unsigned len, IAtom * locale)
  1362. {
  1363. if(!locale)
  1364. locale = emptyAtom;
  1365. CUnicodeTypeKey key;
  1366. key.length = len;
  1367. key.locale.set(locale);
  1368. CriticalBlock procedure(*typeCS);
  1369. ITypeInfo *ret;
  1370. IInterface * * match = vutt->getValue(key);
  1371. if(match)
  1372. ret = (ITypeInfo *)LINK(*match);
  1373. else
  1374. {
  1375. if(len == UNKNOWN_LENGTH)
  1376. ret = new CVarUnicodeTypeInfo(UNKNOWN_LENGTH, locale);
  1377. else
  1378. ret = new CVarUnicodeTypeInfo((len+1)*2, locale);
  1379. vutt->setValue(key, ret);
  1380. }
  1381. return ret;
  1382. }
  1383. extern DEFTYPE_API ITypeInfo *makeUtf8Type(unsigned len, IAtom * locale)
  1384. {
  1385. if(!locale)
  1386. locale = emptyAtom;
  1387. CUnicodeTypeKey key;
  1388. key.length = len;
  1389. key.locale.set(locale);
  1390. CriticalBlock procedure(*typeCS);
  1391. ITypeInfo *ret;
  1392. IInterface * * match = u8tt->getValue(key);
  1393. if(match)
  1394. ret = (ITypeInfo *)LINK(*match);
  1395. else
  1396. {
  1397. if (len == UNKNOWN_LENGTH)
  1398. ret = new CUtf8TypeInfo(UNKNOWN_LENGTH, locale);
  1399. else
  1400. ret = new CUtf8TypeInfo(len*4, locale);
  1401. u8tt->setValue(key, ret);
  1402. }
  1403. return ret;
  1404. }
  1405. extern DEFTYPE_API ITypeInfo *makeDataType(int len)
  1406. {
  1407. CStringTypeKey key;
  1408. key.length = len;
  1409. key.charset.set(NULL);
  1410. key.collation.set(NULL);
  1411. CriticalBlock procedure(*typeCS);
  1412. ITypeInfo *ret;
  1413. IInterface * * match = datatt->getValue(key);
  1414. if (match)
  1415. {
  1416. ret = (ITypeInfo *)LINK(*match);
  1417. }
  1418. else
  1419. {
  1420. ret = new CDataTypeInfo(len);
  1421. datatt->setValue(key, ret);
  1422. }
  1423. return ret;
  1424. }
  1425. extern DEFTYPE_API ITypeInfo *makeIntType(int len, bool isSigned)
  1426. {
  1427. assertex(len>0 && len <= 8);
  1428. if (len <= 0 || len > 8)
  1429. return NULL;
  1430. CriticalBlock procedure(*typeCS);
  1431. CIntTypeInfo *ret = itt[isSigned][len-1];
  1432. if (ret==NULL)
  1433. ret = itt[isSigned][len-1] = new CIntTypeInfo(len, isSigned);
  1434. ::Link(ret);
  1435. return ret;
  1436. }
  1437. extern DEFTYPE_API ITypeInfo *makeSwapIntType(int len, bool isSigned)
  1438. {
  1439. assertex(len>0 && len <= 8);
  1440. if (len <= 0 || len > 8)
  1441. return NULL;
  1442. CriticalBlock procedure(*typeCS);
  1443. CIntTypeInfo *ret = sitt[isSigned][len-1];
  1444. if (ret==NULL)
  1445. ret = sitt[isSigned][len-1] = new CSwapIntTypeInfo(len, isSigned);
  1446. ::Link(ret);
  1447. return ret;
  1448. }
  1449. extern DEFTYPE_API ITypeInfo *makePackedIntType(ITypeInfo * basetype)
  1450. {
  1451. CriticalBlock procedure(*typeCS);
  1452. IInterface * * match = pitt->getValue(basetype);
  1453. if (match)
  1454. {
  1455. ::Release(basetype);
  1456. return (ITypeInfo *)LINK(*match);
  1457. }
  1458. ITypeInfo * next = new CPackedIntTypeInfo(basetype);
  1459. pitt->setValue(basetype, next);
  1460. return next;
  1461. }
  1462. extern DEFTYPE_API ITypeInfo *makePackedIntType(int len, bool isSigned)
  1463. {
  1464. return makePackedIntType(makeIntType(len, isSigned));
  1465. }
  1466. extern DEFTYPE_API ITypeInfo *makeRealType(int len)
  1467. {
  1468. assertex(len == 4 || len == 8);
  1469. if (len != 4 && len != 8)
  1470. return NULL;
  1471. CriticalBlock procedure(*typeCS);
  1472. CRealTypeInfo *ret = realtt[len-1];
  1473. if (ret==NULL)
  1474. ret = realtt[len-1] = new CRealTypeInfo(len);
  1475. ::Link(ret);
  1476. return ret;
  1477. }
  1478. /* Precondition: len>0 && len>64 */
  1479. extern DEFTYPE_API ITypeInfo *makeBitfieldType(int len, ITypeInfo * basetype)
  1480. {
  1481. assertex(len>0 && len <= 64);
  1482. if (len <= 0 || len > 64)
  1483. return NULL;
  1484. CriticalBlock procedure(*typeCS);
  1485. if (basetype)
  1486. {
  1487. assertex(basetype->getTypeCode() == type_int);
  1488. }
  1489. else
  1490. basetype = getPromotedBitfieldType(len);
  1491. unsigned baseSize=basetype->getSize();
  1492. CBitfieldTypeInfo *ret = bftt[len-1][baseSize-1];
  1493. if (ret==NULL)
  1494. ret = bftt[len-1][baseSize-1] = new CBitfieldTypeInfo(len, basetype);
  1495. else
  1496. ::Release(basetype);
  1497. ::Link(ret);
  1498. return ret;
  1499. }
  1500. extern DEFTYPE_API ITypeInfo *makeBoolType()
  1501. {
  1502. CriticalBlock procedure(*typeCS);
  1503. if (!btt)
  1504. btt = new CBoolTypeInfo();
  1505. ::Link(btt);
  1506. return btt;
  1507. }
  1508. extern DEFTYPE_API ITypeInfo *makeBlobType()
  1509. {
  1510. CriticalBlock procedure(*typeCS);
  1511. if (!bltt)
  1512. bltt = new CBlobTypeInfo();
  1513. ::Link(bltt);
  1514. return bltt;
  1515. }
  1516. extern DEFTYPE_API ITypeInfo *makeVoidType()
  1517. {
  1518. CriticalBlock procedure(*typeCS);
  1519. if (!vtt)
  1520. vtt = new CVoidTypeInfo();
  1521. ::Link(vtt);
  1522. return vtt;
  1523. }
  1524. extern DEFTYPE_API ITypeInfo *makeNullType()
  1525. {
  1526. CriticalBlock procedure(*typeCS);
  1527. if (!ntt)
  1528. ntt = new CNullTypeInfo();
  1529. ::Link(ntt);
  1530. return ntt;
  1531. }
  1532. extern DEFTYPE_API ITypeInfo *makeRecordType()
  1533. {
  1534. CriticalBlock procedure(*typeCS);
  1535. if (!rtt)
  1536. rtt = new CRecordTypeInfo();
  1537. ::Link(rtt);
  1538. return rtt;
  1539. }
  1540. extern DEFTYPE_API ITypeInfo *makePatternType()
  1541. {
  1542. CriticalBlock procedure(*typeCS);
  1543. if (!patt)
  1544. patt = new CPatternTypeInfo();
  1545. ::Link(patt);
  1546. return patt;
  1547. }
  1548. extern DEFTYPE_API ITypeInfo *makeTokenType()
  1549. {
  1550. CriticalBlock procedure(*typeCS);
  1551. if (!tokentt)
  1552. tokentt = new CTokenTypeInfo();
  1553. ::Link(tokentt);
  1554. return tokentt;
  1555. }
  1556. extern DEFTYPE_API ITypeInfo *makeFeatureType()
  1557. {
  1558. CriticalBlock procedure(*typeCS);
  1559. if (!featurett)
  1560. featurett = new CFeatureTypeInfo();
  1561. ::Link(featurett);
  1562. return featurett;
  1563. }
  1564. extern DEFTYPE_API ITypeInfo *makeEventType()
  1565. {
  1566. CriticalBlock procedure(*typeCS);
  1567. if (!ett)
  1568. ett = new CEventTypeInfo();
  1569. ::Link(ett);
  1570. return ett;
  1571. }
  1572. extern DEFTYPE_API ITypeInfo *makeAnyType()
  1573. {
  1574. CriticalBlock procedure(*typeCS);
  1575. if (!anytt)
  1576. anytt = new CAnyTypeInfo();
  1577. ::Link(anytt);
  1578. return anytt;
  1579. }
  1580. extern DEFTYPE_API ITypeInfo *makeCharType(bool caseSensitive)
  1581. {
  1582. CriticalBlock procedure(*typeCS);
  1583. if (!ctt[caseSensitive])
  1584. ctt[caseSensitive] = new CCharTypeInfo(caseSensitive);
  1585. ::Link(ctt[caseSensitive]);
  1586. return ctt[caseSensitive];
  1587. }
  1588. extern DEFTYPE_API ITypeInfo *makeSetType(ITypeInfo *basetype)
  1589. {
  1590. CriticalBlock procedure(*typeCS);
  1591. IInterface * * match = setTT->getValue(basetype);
  1592. if (match)
  1593. {
  1594. ::Release(basetype);
  1595. return (ITypeInfo *)LINK(*match);
  1596. }
  1597. ITypeInfo * next = new CSetTypeInfo(basetype);
  1598. setTT->setValue(basetype, next);
  1599. return next;
  1600. }
  1601. //-----------------------------
  1602. static ITypeInfo * commonUpType(CHashedTypeInfo * candidate)
  1603. {
  1604. ITypeInfo * match;
  1605. {
  1606. CriticalBlock block(*typeCS);
  1607. match = globalTypeCache->addOrFind(*candidate);
  1608. if (match == candidate)
  1609. return match;
  1610. match->Link();
  1611. if (!static_cast<CHashedTypeInfo *>(match)->isAlive())
  1612. {
  1613. globalTypeCache->replace(*candidate);
  1614. return candidate;
  1615. }
  1616. }
  1617. candidate->Release();
  1618. return match;
  1619. }
  1620. extern DEFTYPE_API ITypeInfo *makeDecimalType(unsigned digits, unsigned prec, bool isSigned)
  1621. {
  1622. assertex((digits == UNKNOWN_LENGTH) || (digits - prec <= MAX_DECIMAL_LEADING));
  1623. assertex((prec == UNKNOWN_LENGTH) || ((prec <= digits) && (prec <= MAX_DECIMAL_PRECISION)));
  1624. assertex((prec != UNKNOWN_LENGTH) || (digits == UNKNOWN_LENGTH));
  1625. return commonUpType(new CDecimalTypeInfo(digits, prec, isSigned));
  1626. }
  1627. extern DEFTYPE_API ITypeInfo *makeRuleType(ITypeInfo *basetype)
  1628. {
  1629. return commonUpType(new CRuleTypeInfo(basetype));
  1630. }
  1631. extern DEFTYPE_API ITypeInfo *makeTableType(ITypeInfo *basetype)
  1632. {
  1633. assertex(!basetype || basetype->getTypeCode() == type_row);
  1634. return commonUpType(new CTableTypeInfo(basetype));
  1635. }
  1636. extern DEFTYPE_API ITypeInfo *makeDictionaryType(ITypeInfo *basetype)
  1637. {
  1638. assertex(!basetype || basetype->getTypeCode() == type_row);
  1639. return commonUpType(new CDictionaryTypeInfo(basetype));
  1640. }
  1641. extern DEFTYPE_API ITypeInfo *makeGroupedTableType(ITypeInfo *basetype)
  1642. {
  1643. return commonUpType(new CGroupedTableTypeInfo(basetype));
  1644. }
  1645. extern DEFTYPE_API ITypeInfo *makeFunctionType(ITypeInfo *basetype, IInterface * parameters, IInterface * defaults, IInterface * attrs)
  1646. {
  1647. assertex(basetype->getTypeCode() != type_function); // not just yet anyway
  1648. if (!basetype || !parameters)
  1649. {
  1650. ::Release(basetype);
  1651. ::Release(parameters);
  1652. ::Release(defaults);
  1653. ::Release(attrs);
  1654. throwUnexpected();
  1655. }
  1656. return commonUpType(new CFunctionTypeInfo(basetype, parameters, defaults, attrs));
  1657. }
  1658. /* In basetype: linked. Return: linked */
  1659. extern DEFTYPE_API ITypeInfo *makeRowType(ITypeInfo *basetype)
  1660. {
  1661. assertex(!basetype || basetype->getTypeCode() == type_record);
  1662. return commonUpType(new CRowTypeInfo(basetype));
  1663. }
  1664. extern DEFTYPE_API ITypeInfo *makeTransformType(ITypeInfo *basetype)
  1665. {
  1666. assertex(!basetype || basetype->getTypeCode() == type_record);
  1667. return commonUpType(new CTransformTypeInfo(basetype));
  1668. }
  1669. extern DEFTYPE_API ITypeInfo *makeSortListType(ITypeInfo *basetype)
  1670. {
  1671. return commonUpType(new CSortListTypeInfo(basetype));
  1672. }
  1673. /* In basetype: linked. Return: linked */
  1674. ITypeInfo * makeArrayType(ITypeInfo * basetype, unsigned size)
  1675. {
  1676. return commonUpType(new CArrayTypeInfo(basetype, size));
  1677. }
  1678. /* In basetype: linked. Return: linked */
  1679. ITypeInfo * makePointerType(ITypeInfo * basetype)
  1680. {
  1681. return commonUpType(new CPointerTypeInfo(basetype));
  1682. }
  1683. /* In basetype: linked. Return: linked */
  1684. ITypeInfo * makeConstantModifier(ITypeInfo * basetype)
  1685. {
  1686. return makeModifier(basetype, typemod_const, NULL);
  1687. }
  1688. /* In basetype: linked. Return: linked */
  1689. ITypeInfo * makeReferenceModifier(ITypeInfo * basetype)
  1690. {
  1691. return makeModifier(basetype, typemod_ref, NULL);
  1692. }
  1693. ITypeInfo * makeWrapperModifier(ITypeInfo * basetype)
  1694. {
  1695. return makeModifier(basetype, typemod_wrapper, NULL);
  1696. }
  1697. ITypeInfo * makeModifier(ITypeInfo * basetype, typemod_t kind, IInterface * extra)
  1698. {
  1699. if (kind == typemod_none)
  1700. {
  1701. ::Release(extra);
  1702. return basetype;
  1703. }
  1704. #ifdef _DEBUG
  1705. ITypeInfo * cur = basetype;
  1706. loop
  1707. {
  1708. if (cur->queryModifier() == typemod_none)
  1709. break;
  1710. if (cur->queryModifier() == kind)
  1711. {
  1712. if (cur->queryModifierExtra() == extra)
  1713. throwUnexpected();
  1714. }
  1715. cur = cur->queryTypeBase();
  1716. }
  1717. #endif
  1718. return commonUpType(new CModifierTypeInfo(basetype, kind, extra));
  1719. }
  1720. /* In basetype: linked. Return: linked */
  1721. ITypeInfo * makeClassType(const char * name)
  1722. {
  1723. //MORE!!
  1724. return new CClassTypeInfo(name);
  1725. }
  1726. //===========================================================================
  1727. template <class T>
  1728. inline void ReleaseAndClear(T * & ptr)
  1729. {
  1730. if (ptr)
  1731. {
  1732. ptr->Release();
  1733. ptr = NULL;
  1734. }
  1735. }
  1736. void ClearTypeCache()
  1737. {
  1738. size32_t i;
  1739. stt->kill();
  1740. vstt->kill();
  1741. qstt->kill();
  1742. datatt->kill();
  1743. utt->kill();
  1744. vutt->kill();
  1745. u8tt->kill();
  1746. for (i = 0; i < 8; i++)
  1747. {
  1748. ReleaseAndClear(itt[false][i]);
  1749. ReleaseAndClear(itt[true][i]);
  1750. ReleaseAndClear(sitt[false][i]);
  1751. ReleaseAndClear(sitt[true][i]);
  1752. }
  1753. for (i = 0; i < _elements_in(bftt); i++)
  1754. {
  1755. int j;
  1756. for (j = 0; j < _elements_in(bftt[0]); j++)
  1757. ReleaseAndClear(bftt[i][j]);
  1758. }
  1759. for (i = 0; i < _elements_in(realtt); i++)
  1760. ReleaseAndClear(realtt[i]);
  1761. for (i = 0; i < _elements_in(ctt); i++)
  1762. ReleaseAndClear(ctt[i]);
  1763. ReleaseAndClear(btt);
  1764. ReleaseAndClear(bltt);
  1765. ReleaseAndClear(vtt);
  1766. ReleaseAndClear(ntt);
  1767. ReleaseAndClear(rtt);
  1768. ReleaseAndClear(patt);
  1769. ReleaseAndClear(tokentt);
  1770. ReleaseAndClear(featurett);
  1771. ReleaseAndClear(ett);
  1772. ReleaseAndClear(anytt);
  1773. pitt->kill();
  1774. setTT->kill();
  1775. globalTypeCache->kill();
  1776. ReleaseAndClear(dataCharset);
  1777. ReleaseAndClear(asciiCharset);
  1778. ReleaseAndClear(ebcdicCharset);
  1779. ReleaseAndClear(utf8Charset);
  1780. ReleaseAndClear(asciiCollation);
  1781. ReleaseAndClear(ebcdicCollation);
  1782. ReleaseAndClear(ascii2ebcdic);
  1783. ReleaseAndClear(ebcdic2ascii);
  1784. }
  1785. //===========================================================================
  1786. //This function is here for efficiency - if a particular case is not implemented,
  1787. //the default case handles it...
  1788. MemoryBuffer & appendBufferFromMem(MemoryBuffer & mem, ITypeInfo * type, const void * data)
  1789. {
  1790. unsigned len = type->getSize();
  1791. switch (type->getTypeCode())
  1792. {
  1793. case type_string:
  1794. case type_data:
  1795. case type_varstring:
  1796. case type_qstring:
  1797. case type_decimal:
  1798. mem.append(len, data);
  1799. break;
  1800. default:
  1801. mem.appendEndian(len, data);
  1802. break;
  1803. }
  1804. return mem;
  1805. }
  1806. //============================================================================
  1807. bool isNumericType(ITypeInfo * type)
  1808. {
  1809. switch (type->getTypeCode())
  1810. {
  1811. case type_bitfield:
  1812. case type_real:
  1813. case type_int:
  1814. case type_swapint:
  1815. case type_packedint:
  1816. case type_decimal:
  1817. return true;
  1818. }
  1819. return false;
  1820. }
  1821. bool isStringType(ITypeInfo * type)
  1822. {
  1823. switch (type->getTypeCode())
  1824. {
  1825. case type_data:
  1826. case type_string:
  1827. case type_varstring:
  1828. case type_qstring:
  1829. return true;
  1830. }
  1831. return false;
  1832. }
  1833. bool isSimpleStringType(ITypeInfo * type)
  1834. {
  1835. switch (type->getTypeCode())
  1836. {
  1837. case type_data:
  1838. case type_string:
  1839. case type_varstring:
  1840. return true;
  1841. }
  1842. return false;
  1843. }
  1844. bool isIntegralType(ITypeInfo * type)
  1845. {
  1846. switch (type->getTypeCode())
  1847. {
  1848. case type_bitfield:
  1849. case type_int:
  1850. case type_swapint:
  1851. case type_packedint:
  1852. return true;
  1853. }
  1854. return false;
  1855. }
  1856. bool isPatternType(ITypeInfo * type)
  1857. {
  1858. switch(type->getTypeCode())
  1859. {
  1860. case type_pattern:
  1861. case type_token:
  1862. case type_rule:
  1863. return true;
  1864. default:
  1865. return false;
  1866. }
  1867. }
  1868. bool isUnicodeType(ITypeInfo * type)
  1869. {
  1870. switch(type->getTypeCode())
  1871. {
  1872. case type_unicode:
  1873. case type_varunicode:
  1874. case type_utf8:
  1875. return true;
  1876. default:
  1877. return false;
  1878. }
  1879. }
  1880. bool isDatasetType(ITypeInfo * type)
  1881. {
  1882. switch(type->getTypeCode())
  1883. {
  1884. case type_table:
  1885. case type_groupedtable:
  1886. return true;
  1887. default:
  1888. return false;
  1889. }
  1890. }
  1891. bool isSingleValuedType(ITypeInfo * type)
  1892. {
  1893. if (!type)
  1894. return false;
  1895. switch (type->getTypeCode())
  1896. {
  1897. case type_boolean:
  1898. case type_int:
  1899. case type_real:
  1900. case type_decimal:
  1901. case type_string:
  1902. case type_date:
  1903. case type_bitfield:
  1904. case type_char:
  1905. case type_enumerated:
  1906. case type_varstring:
  1907. case type_data:
  1908. case type_alien:
  1909. case type_swapint:
  1910. case type_packedint:
  1911. case type_qstring:
  1912. case type_unicode:
  1913. case type_varunicode:
  1914. case type_utf8:
  1915. return true;
  1916. }
  1917. return false;
  1918. }
  1919. //============================================================================
  1920. ITypeInfo * getNumericType(ITypeInfo * type)
  1921. {
  1922. unsigned digits = 9;
  1923. switch (type->getTypeCode())
  1924. {
  1925. case type_real:
  1926. case type_int:
  1927. case type_swapint:
  1928. case type_decimal:
  1929. case type_packedint:
  1930. return LINK(type);
  1931. case type_bitfield:
  1932. {
  1933. ITypeInfo * promoted = type->queryPromotedType();
  1934. return LINK(promoted);
  1935. }
  1936. case type_varstring:
  1937. case type_qstring:
  1938. case type_string:
  1939. case type_unicode:
  1940. case type_utf8:
  1941. case type_varunicode:
  1942. case type_data:
  1943. digits = type->getDigits();
  1944. if (digits == UNKNOWN_LENGTH)
  1945. digits = 20;
  1946. break;
  1947. case type_boolean:
  1948. digits = 1;
  1949. break;
  1950. }
  1951. if (digits > 9)
  1952. return makeIntType(8, true);
  1953. if (digits > 4)
  1954. return makeIntType(4, true);
  1955. if (digits > 2)
  1956. return makeIntType(2, true);
  1957. return makeIntType(1, true);
  1958. }
  1959. ITypeInfo * getStringType(ITypeInfo * type)
  1960. {
  1961. switch (type->getTypeCode())
  1962. {
  1963. case type_string: case type_varstring:
  1964. return LINK(type);
  1965. }
  1966. return makeStringType(type->getStringLen(), NULL, NULL);
  1967. }
  1968. ITypeInfo * getVarStringType(ITypeInfo * type)
  1969. {
  1970. switch (type->getTypeCode())
  1971. {
  1972. case type_string: case type_varstring:
  1973. return LINK(type);
  1974. }
  1975. return makeVarStringType(type->getStringLen());
  1976. }
  1977. //============================================================================
  1978. static ITypeInfo * getPromotedSet(ITypeInfo * left, ITypeInfo * right, bool isCompare)
  1979. {
  1980. ITypeInfo * leftChild = left;
  1981. ITypeInfo * rightChild = right;
  1982. if (left->getTypeCode() == type_set)
  1983. leftChild = left->queryChildType();
  1984. if (right->getTypeCode() == type_set)
  1985. rightChild = right->queryChildType();
  1986. if (leftChild && rightChild)
  1987. return makeSetType(getPromotedType(leftChild, rightChild));
  1988. if (!leftChild)
  1989. return LINK(right);
  1990. return LINK(left);
  1991. }
  1992. static ITypeInfo * getPromotedUnicode(ITypeInfo * left, ITypeInfo * right)
  1993. {
  1994. unsigned lLen = left->getStringLen();
  1995. unsigned rLen = right->getStringLen();
  1996. if(lLen < rLen)
  1997. lLen = rLen;
  1998. return makeUnicodeType(lLen, getCommonLocale(left, right));
  1999. }
  2000. static ITypeInfo * getPromotedVarUnicode(ITypeInfo * left, ITypeInfo * right)
  2001. {
  2002. unsigned lLen = left->getStringLen();
  2003. unsigned rLen = right->getStringLen();
  2004. if(lLen < rLen)
  2005. lLen = rLen;
  2006. return makeVarUnicodeType(lLen, getCommonLocale(left, right));
  2007. }
  2008. static ITypeInfo * getPromotedUtf8(ITypeInfo * left, ITypeInfo * right)
  2009. {
  2010. unsigned lLen = left->getStringLen();
  2011. unsigned rLen = right->getStringLen();
  2012. if(lLen < rLen)
  2013. lLen = rLen;
  2014. return makeUtf8Type(lLen, getCommonLocale(left, right));
  2015. }
  2016. static ITypeInfo * getPromotedVarString(ITypeInfo * left, ITypeInfo * right)
  2017. {
  2018. unsigned lLen = left->getStringLen();
  2019. unsigned rLen = right->getStringLen();
  2020. if (lLen < rLen) lLen = rLen;
  2021. //MORE: Didn't this ought to have the charset logic of getPromotedString?
  2022. return makeVarStringType(lLen);
  2023. }
  2024. static ITypeInfo * getPromotedString(ITypeInfo * left, ITypeInfo * right)
  2025. {
  2026. unsigned lLen = left->getStringLen();
  2027. unsigned rLen = right->getStringLen();
  2028. if (lLen < rLen) lLen = rLen;
  2029. ICollationInfo * collation = left->queryCollation(); //MORE!!
  2030. ICharsetInfo * lCharset = left->queryCharset();
  2031. ICharsetInfo * rCharset = right->queryCharset();
  2032. if (!lCharset || (rCharset && (lCharset != rCharset) && (rCharset->queryName() == asciiAtom)))
  2033. {
  2034. lCharset = rCharset;
  2035. collation = right->queryCollation();
  2036. }
  2037. return makeStringType(lLen, LINK(lCharset), LINK(collation));
  2038. }
  2039. static ITypeInfo * getPromotedQString(ITypeInfo * left, ITypeInfo * right)
  2040. {
  2041. unsigned lLen = left->getStringLen();
  2042. unsigned rLen = right->getStringLen();
  2043. if (lLen < rLen) lLen = rLen;
  2044. return makeQStringType(lLen);
  2045. }
  2046. static ITypeInfo * getPromotedData(ITypeInfo * left, ITypeInfo * right)
  2047. {
  2048. unsigned lLen = left->getStringLen();
  2049. unsigned rLen = right->getStringLen();
  2050. assertex(lLen != rLen);
  2051. return makeDataType(UNKNOWN_LENGTH);
  2052. }
  2053. static ITypeInfo * makeUnknownLengthDecimal(bool isCompare)
  2054. {
  2055. if (isCompare)
  2056. return makeDecimalType(UNKNOWN_LENGTH, UNKNOWN_LENGTH, true);
  2057. return makeDecimalType(MAX_DECIMAL_DIGITS, MAX_DECIMAL_PRECISION, true);
  2058. }
  2059. static ITypeInfo * getPromotedDecimalReal(ITypeInfo * type, bool isCompare)
  2060. {
  2061. return makeUnknownLengthDecimal(isCompare);
  2062. }
  2063. static ITypeInfo * getPromotedDecimal(ITypeInfo * left, ITypeInfo * right, bool isCompare)
  2064. {
  2065. if (left->getTypeCode() == type_real)
  2066. return getPromotedDecimalReal(right, isCompare);
  2067. if (right->getTypeCode() == type_real)
  2068. return getPromotedDecimalReal(left, isCompare);
  2069. unsigned lDigits = left->getDigits();
  2070. unsigned rDigits = right->getDigits();
  2071. if (lDigits == UNKNOWN_LENGTH || rDigits == UNKNOWN_LENGTH)
  2072. return makeDecimalType(UNKNOWN_LENGTH, UNKNOWN_LENGTH, left->isSigned() || right->isSigned());
  2073. if (isCompare)
  2074. return makeUnknownLengthDecimal(isCompare);
  2075. unsigned lPrec = left->getPrecision();
  2076. unsigned rPrec = right->getPrecision();
  2077. unsigned lLead = lDigits - lPrec;
  2078. unsigned rLead = rDigits - rPrec;
  2079. if (lLead < rLead) lLead = rLead;
  2080. if (lPrec < rPrec) lPrec = rPrec;
  2081. return makeDecimalType(lLead + lPrec, lPrec, left->isSigned() || right->isSigned());
  2082. }
  2083. static ITypeInfo * getPromotedReal(ITypeInfo * left, ITypeInfo * right)
  2084. {
  2085. unsigned lDigits = left->getDigits();
  2086. unsigned rDigits = right->getDigits();
  2087. if (lDigits < rDigits) lDigits = rDigits;
  2088. if (lDigits >= DOUBLE_SIG_DIGITS)
  2089. return makeRealType(8);
  2090. return makeRealType(4);
  2091. }
  2092. static void getPromotedIntegerSize(ITypeInfo * left, ITypeInfo * right, unsigned & pSize, bool & pSigned)
  2093. {
  2094. unsigned lSize = left->getSize();
  2095. unsigned rSize = right->getSize();
  2096. bool lSigned = left->isSigned();
  2097. bool rSigned = right->isSigned();
  2098. //This assumes it's an addition! For other operands rules are not necessarily the same!
  2099. //Need to get the correct size and sign combination.
  2100. //Try and preserve value whenever possible.
  2101. //u1+s1=>s2 s1+u4=>s8 u2+u4=>u4 u1+s2=s2 b+s1->s1 b+u1=>u1
  2102. //Also needs to cope with integer6 etc...
  2103. if (left->getTypeCode() == type_boolean)
  2104. {
  2105. lSigned = rSigned;
  2106. lSize = rSize;
  2107. }
  2108. else if (right->getTypeCode() == type_boolean)
  2109. {
  2110. //don't need to do anything....
  2111. }
  2112. else if (lSigned != rSigned)
  2113. {
  2114. if (lSigned)
  2115. {
  2116. if (lSize <= rSize)
  2117. {
  2118. lSize = promotedIntSize[rSize];
  2119. if ((lSize == rSize) && (lSize != 8))
  2120. lSize += lSize;
  2121. }
  2122. }
  2123. else
  2124. {
  2125. lSigned = true;
  2126. if (lSize < rSize)
  2127. lSize = rSize;
  2128. else
  2129. {
  2130. if (lSize != promotedIntSize[lSize])
  2131. lSize = promotedIntSize[lSize];
  2132. else if (lSize != 8)
  2133. lSize += lSize;
  2134. }
  2135. }
  2136. }
  2137. else
  2138. {
  2139. if (lSize < rSize)
  2140. lSize = rSize;
  2141. }
  2142. pSize = lSize;
  2143. pSigned = lSigned;
  2144. }
  2145. static ITypeInfo * getPromotedInteger(ITypeInfo * left, ITypeInfo * right)
  2146. {
  2147. unsigned size;
  2148. bool isSigned;
  2149. getPromotedIntegerSize(left, right, size, isSigned);
  2150. return makeIntType(size, isSigned);
  2151. }
  2152. static ITypeInfo * getPromotedSwapInteger(ITypeInfo * left, ITypeInfo * right)
  2153. {
  2154. unsigned size;
  2155. bool isSigned;
  2156. getPromotedIntegerSize(left, right, size, isSigned);
  2157. return makeSwapIntType(size, isSigned);
  2158. }
  2159. static ITypeInfo * getPromotedPackedInteger(ITypeInfo * left, ITypeInfo * right)
  2160. {
  2161. unsigned size;
  2162. bool isSigned;
  2163. getPromotedIntegerSize(left, right, size, isSigned);
  2164. return makePackedIntType(size, isSigned);
  2165. }
  2166. //============================================================================
  2167. static ITypeInfo * getPromotedType(ITypeInfo * lType, ITypeInfo * rType, bool isCompare)
  2168. {
  2169. ITypeInfo * l = lType->queryPromotedType();
  2170. ITypeInfo * r = rType->queryPromotedType();
  2171. if (l == r)
  2172. return LINK(l);
  2173. type_t lcode = l->getTypeCode();
  2174. type_t rcode = r->getTypeCode();
  2175. if (lcode == type_any) return LINK(r);
  2176. if (rcode == type_any) return LINK(l);
  2177. if ((lcode == type_set) || (rcode == type_set))
  2178. return getPromotedSet(l, r, isCompare);
  2179. if ((lcode == type_unicode) || (rcode == type_unicode))
  2180. return getPromotedUnicode(l, r);
  2181. if ((lcode == type_utf8) || (rcode == type_utf8))
  2182. return getPromotedUtf8(l, r);
  2183. if ((lcode == type_varunicode) || (rcode == type_varunicode))
  2184. return getPromotedVarUnicode(l, r);
  2185. if ((lcode == type_string) || (rcode == type_string))
  2186. return getPromotedString(l, r);
  2187. if ((lcode == type_varstring) || (rcode == type_varstring))
  2188. return getPromotedVarString(l, r);
  2189. if ((lcode == type_data) || (rcode == type_data))
  2190. return getPromotedData(l, r);
  2191. if ((lcode == type_qstring) || (rcode == type_qstring))
  2192. return getPromotedQString(l, r);
  2193. if ((lcode == type_decimal) || (rcode == type_decimal))
  2194. return getPromotedDecimal(l, r, isCompare);
  2195. if ((lcode == type_real) || (rcode == type_real))
  2196. return getPromotedReal(l, r);
  2197. if ((lcode == type_int) || (rcode == type_int))
  2198. return getPromotedInteger(l, r);
  2199. if (lcode == type_boolean) return LINK(l);
  2200. if (rcode == type_boolean) return LINK(r);
  2201. if ((lcode == type_swapint) || (rcode == type_swapint))
  2202. return getPromotedSwapInteger(l, r);
  2203. if ((lcode == type_packedint) || (rcode == type_packedint))
  2204. return getPromotedPackedInteger(l, r);
  2205. //NB: Enumerations should come last...
  2206. if (l->getSize() >= r->getSize())
  2207. return LINK(l);
  2208. return LINK(r);
  2209. //MORE(!)
  2210. //return makeIntType(4);
  2211. }
  2212. ITypeInfo * getPromotedType(ITypeInfo * lType, ITypeInfo * rType)
  2213. {
  2214. return getPromotedType(lType, rType, false);
  2215. }
  2216. ITypeInfo * getPromotedNumericType(ITypeInfo * l_type, ITypeInfo * r_type)
  2217. {
  2218. Owned<ITypeInfo> l = getNumericType(l_type->queryPromotedType());
  2219. Owned<ITypeInfo> r = getNumericType(r_type->queryPromotedType());
  2220. return getPromotedType(l,r,false);
  2221. }
  2222. ITypeInfo * getPromotedAddSubType(ITypeInfo * lType, ITypeInfo * rType)
  2223. {
  2224. Owned<ITypeInfo> ret = getPromotedNumericType(lType, rType);
  2225. if (isDecimalType(ret) && !isUnknownSize(ret) && (ret->getDigits() - ret->getPrecision() < MAX_DECIMAL_LEADING))
  2226. return makeDecimalType(ret->getDigits()+1, ret->getPrecision(), ret->isSigned());
  2227. return ret.getClear();
  2228. }
  2229. ITypeInfo * getPromotedMulDivType(ITypeInfo * lType, ITypeInfo * rType)
  2230. {
  2231. Owned<ITypeInfo> ret = getPromotedNumericType(lType, rType);
  2232. if (isDecimalType(ret) && !isUnknownSize(ret))
  2233. return makeUnknownLengthDecimal(false);
  2234. return ret.getClear();
  2235. }
  2236. ITypeInfo * getPromotedCompareType(ITypeInfo * left, ITypeInfo * right)
  2237. {
  2238. Owned<ITypeInfo> promoted = getPromotedType(left, right, true);
  2239. if (left != right)
  2240. {
  2241. type_t ptc = promoted->getTypeCode();
  2242. switch (ptc)
  2243. {
  2244. case type_string:
  2245. {
  2246. if ((left->getTypeCode() == ptc) && (right->getTypeCode() == ptc))
  2247. {
  2248. if ((left->queryCollation() == right->queryCollation()) &&
  2249. (left->queryCharset() == right->queryCharset()))
  2250. {
  2251. promoted.setown(getStretchedType(UNKNOWN_LENGTH, left));
  2252. }
  2253. }
  2254. }
  2255. break;
  2256. case type_unicode:
  2257. case type_utf8:
  2258. {
  2259. }
  2260. break;
  2261. }
  2262. }
  2263. return promoted.getClear();
  2264. }
  2265. static bool preservesValue(ITypeInfo * after, ITypeInfo * before, bool preserveInformation)
  2266. {
  2267. type_t beforeType = before->getTypeCode();
  2268. type_t afterType = after->getTypeCode();
  2269. switch (beforeType)
  2270. {
  2271. case type_boolean:
  2272. return true;
  2273. case type_packedint:
  2274. before = before->queryPromotedType();
  2275. //fall through
  2276. case type_int:
  2277. case type_swapint:
  2278. case type_enumerated:
  2279. switch (afterType)
  2280. {
  2281. case type_packedint:
  2282. after = after->queryPromotedType();
  2283. //fall through.
  2284. case type_int: case type_swapint: case type_enumerated:
  2285. {
  2286. bool beforeSigned = before->isSigned();
  2287. bool afterSigned = after->isSigned();
  2288. size32_t beforeSize = before->getSize();
  2289. size32_t afterSize = after->getSize();
  2290. if (preserveInformation && (beforeSize <= afterSize))
  2291. return true; // sign doesn't matter...
  2292. return !((beforeSigned && !afterSigned) ||
  2293. (beforeSize > afterSize) ||
  2294. (!beforeSigned && afterSigned && (beforeSize == afterSize)));
  2295. }
  2296. case type_decimal:
  2297. {
  2298. bool beforeSigned = before->isSigned();
  2299. bool afterSigned = after->isSigned();
  2300. size32_t beforeSize, afterSize;
  2301. beforeSize = before->getDigits();
  2302. afterSize = after->getDigits() - after->getPrecision();
  2303. return ((!beforeSigned || afterSigned) && (beforeSize <= afterSize));
  2304. }
  2305. case type_real:
  2306. return (before->getSize() < after->getSize()); // I think this is correct for all instances
  2307. case type_string: case type_data: case type_varstring: case type_qstring: case type_unicode: case type_varunicode: case type_utf8:
  2308. return (after->getDigits() >= before->getDigits());
  2309. }
  2310. return false;
  2311. case type_decimal:
  2312. switch (afterType)
  2313. {
  2314. case type_decimal:
  2315. {
  2316. unsigned beforePrec = before->getPrecision();
  2317. unsigned afterPrec = after->getPrecision();
  2318. return (!before->isSigned() || after->isSigned()) &&
  2319. (beforePrec <= afterPrec) &&
  2320. (before->getDigits() - beforePrec <= after->getDigits() - afterPrec);
  2321. }
  2322. case type_real:
  2323. return before->getDigits() < after->getDigits(); //NB: Not <= since real errs on over estimation
  2324. case type_int: case type_swapint: case type_packedint:
  2325. return ((before->getPrecision() == 0) &&
  2326. (after->getDigits() > before->getDigits()) &&
  2327. (!before->isSigned() || after->isSigned()));
  2328. case type_string: case type_varstring: case type_data: case type_qstring: case type_unicode: case type_varunicode: case type_utf8:
  2329. return (after->getStringLen() >= before->getStringLen());
  2330. }
  2331. return false;
  2332. case type_varstring:
  2333. //casting from a var string may lose the length information, and so be irreversible.
  2334. switch (afterType)
  2335. {
  2336. case type_varstring: case type_varunicode:
  2337. return (before->getStringLen() <= after->getStringLen());
  2338. }
  2339. return false;
  2340. case type_string:
  2341. case type_data:
  2342. case type_qstring:
  2343. switch (afterType)
  2344. {
  2345. case type_string: case type_data: case type_varstring: case type_unicode: case type_varunicode: case type_utf8:
  2346. return (before->getStringLen() <= after->getStringLen());
  2347. case type_qstring:
  2348. return (beforeType == type_qstring) && (before->getStringLen() <= after->getStringLen());
  2349. }
  2350. return false;
  2351. case type_set:
  2352. if (afterType != type_set)
  2353. return false;
  2354. if (!before->queryChildType())
  2355. return true;
  2356. if (!after->queryChildType())
  2357. return false;
  2358. return preservesValue(after->queryChildType(), before->queryChildType());
  2359. case type_varunicode:
  2360. switch (afterType)
  2361. {
  2362. case type_varunicode:
  2363. return (before->getStringLen() <= after->getStringLen());
  2364. }
  2365. return false;
  2366. case type_unicode:
  2367. case type_utf8:
  2368. switch (afterType)
  2369. {
  2370. case type_unicode: case type_varunicode: case type_utf8:
  2371. return (before->getStringLen() <= after->getStringLen());
  2372. }
  2373. return false;
  2374. default:
  2375. return (beforeType == afterType) && (after->getSize() >= before->getSize());
  2376. }
  2377. }
  2378. bool preservesValue(ITypeInfo * after, ITypeInfo * before)
  2379. {
  2380. return preservesValue(after, before, false);
  2381. }
  2382. bool castLosesInformation(ITypeInfo * after, ITypeInfo * before)
  2383. {
  2384. return !preservesValue(after, before, true);
  2385. }
  2386. // should always call preservesValue first to determine if conversion is possible
  2387. bool preservesOrder(ITypeInfo * after, ITypeInfo * before)
  2388. {
  2389. type_t beforeType = before->getTypeCode();
  2390. type_t afterType = after->getTypeCode();
  2391. switch (beforeType)
  2392. {
  2393. case type_boolean:
  2394. return true;
  2395. case type_decimal:
  2396. switch (afterType)
  2397. {
  2398. case type_real: case type_decimal:
  2399. return true;
  2400. case type_int: case type_swapint: case type_packedint:
  2401. return (before->getPrecision() == 0);
  2402. }
  2403. return false;
  2404. case type_int:
  2405. case type_swapint:
  2406. case type_packedint:
  2407. switch (afterType)
  2408. {
  2409. case type_int: case type_swapint: case type_real: case type_enumerated: case type_decimal: case type_packedint:
  2410. return true;
  2411. }
  2412. return false;
  2413. case type_string:
  2414. case type_varstring:
  2415. case type_data:
  2416. case type_qstring:
  2417. switch (afterType)
  2418. {
  2419. case type_string: case type_varstring: case type_data: case type_enumerated:
  2420. return true;
  2421. case type_qstring:
  2422. return (beforeType == type_qstring);
  2423. }
  2424. return false;
  2425. case type_enumerated:
  2426. switch (afterType)
  2427. {
  2428. case type_string: case type_varstring: case type_data: case type_enumerated: case type_int: case type_swapint: case type_packedint:
  2429. return true;
  2430. }
  2431. return false;
  2432. default:
  2433. return (beforeType == afterType);
  2434. }
  2435. }
  2436. bool isSameBasicType(ITypeInfo * left, ITypeInfo * right)
  2437. {
  2438. if (!left || !right)
  2439. return left==right;
  2440. while (left->isReference())
  2441. left = left->queryTypeBase();
  2442. while (right->isReference())
  2443. right = right->queryTypeBase();
  2444. return queryUnqualifiedType(left)==queryUnqualifiedType(right);
  2445. }
  2446. extern DEFTYPE_API ITypeInfo * getRoundType(ITypeInfo * type)
  2447. {
  2448. if (type->getTypeCode() == type_decimal)
  2449. {
  2450. unsigned olddigits = type->getDigits();
  2451. if (olddigits == UNKNOWN_LENGTH)
  2452. return LINK(type);
  2453. //rounding could increase the number of digits by 1.
  2454. unsigned newdigits = (olddigits - type->getPrecision())+1;
  2455. if (newdigits > MAX_DECIMAL_LEADING)
  2456. newdigits = MAX_DECIMAL_LEADING;
  2457. return makeDecimalType(newdigits, 0, type->isSigned());
  2458. }
  2459. return makeIntType(8, true);
  2460. }
  2461. extern DEFTYPE_API ITypeInfo * getRoundToType(ITypeInfo * type)
  2462. {
  2463. if (type->getTypeCode() == type_decimal)
  2464. {
  2465. unsigned olddigits = type->getDigits();
  2466. unsigned oldPrecision = type->getPrecision();
  2467. if ((olddigits == UNKNOWN_LENGTH) || (olddigits-oldPrecision == MAX_DECIMAL_LEADING))
  2468. return LINK(type);
  2469. //rounding could increase the number of digits by 1.
  2470. return makeDecimalType(olddigits+1, oldPrecision, type->isSigned());
  2471. }
  2472. return makeRealType(8);
  2473. }
  2474. extern DEFTYPE_API ITypeInfo * getTruncType(ITypeInfo * type)
  2475. {
  2476. if (type->getTypeCode() == type_decimal)
  2477. {
  2478. unsigned olddigits = type->getDigits();
  2479. if (olddigits == UNKNOWN_LENGTH)
  2480. return LINK(type);
  2481. unsigned newdigits = (olddigits - type->getPrecision());
  2482. return makeDecimalType(newdigits, 0, type->isSigned());
  2483. }
  2484. return makeIntType(8, true);
  2485. }
  2486. //---------------------------------------------------------------------------
  2487. CCharsetInfo::~CCharsetInfo()
  2488. {
  2489. ::Release(defaultCollation);
  2490. }
  2491. ICollationInfo * CCharsetInfo::queryDefaultCollation()
  2492. {
  2493. if (!defaultCollation)
  2494. defaultCollation = getCollation(name);
  2495. return defaultCollation;
  2496. }
  2497. CCollationInfo::~CCollationInfo()
  2498. {
  2499. }
  2500. ICharsetInfo * CCollationInfo::getCharset()
  2501. {
  2502. return ::getCharset(name);
  2503. }
  2504. //---------------------------------------------------------------------------
  2505. CTranslationInfo::CTranslationInfo(IAtom * _name, ICharsetInfo * _src, ICharsetInfo * _tgt) : src(_src), tgt(_tgt)
  2506. {
  2507. name = _name;
  2508. }
  2509. IAtom * CTranslationInfo::queryName()
  2510. {
  2511. return name;
  2512. }
  2513. ICharsetInfo * CTranslationInfo::querySourceCharset()
  2514. {
  2515. return src;
  2516. }
  2517. ICharsetInfo * CTranslationInfo::queryTargetCharset()
  2518. {
  2519. return tgt;
  2520. }
  2521. //---------------------------------------------------------------------------
  2522. CAscii2EbcdicTranslationInfo::CAscii2EbcdicTranslationInfo() : CTranslationInfo(ascii2ebcdicAtom, getCharset(asciiAtom), getCharset(ebcdicAtom))
  2523. {
  2524. }
  2525. const char * CAscii2EbcdicTranslationInfo::queryRtlFunction()
  2526. {
  2527. return "ascii2ebcdic";
  2528. }
  2529. const char * CAscii2EbcdicTranslationInfo::queryVarRtlFunction()
  2530. {
  2531. return "ascii2ebcdicX";
  2532. }
  2533. StringBuffer & CAscii2EbcdicTranslationInfo::translate(StringBuffer & tgt, unsigned len, const char * src)
  2534. {
  2535. char * buf = (char*)malloc(len);
  2536. rtlStrToEStr(len, buf, len, src);
  2537. tgt.append(len, buf);
  2538. free(buf);
  2539. return tgt;
  2540. }
  2541. CEbcdic2AsciiTranslationInfo::CEbcdic2AsciiTranslationInfo() : CTranslationInfo(ebcdic2asciiAtom, getCharset(asciiAtom), getCharset(ebcdicAtom))
  2542. {
  2543. }
  2544. const char * CEbcdic2AsciiTranslationInfo::queryRtlFunction()
  2545. {
  2546. return "ebcdic2ascii";
  2547. }
  2548. const char * CEbcdic2AsciiTranslationInfo::queryVarRtlFunction()
  2549. {
  2550. return "ebcdic2asciiX";
  2551. }
  2552. StringBuffer & CEbcdic2AsciiTranslationInfo::translate(StringBuffer & tgt, unsigned len, const char * src)
  2553. {
  2554. char * buf = (char*)malloc(len);
  2555. rtlEStrToStr(len, buf, len, src);
  2556. tgt.append(len, buf);
  2557. free(buf);
  2558. return tgt;
  2559. }
  2560. //---------------------------------------------------------------------------
  2561. ICharsetInfo * getCharset(IAtom * atom)
  2562. {
  2563. if ((atom == NULL) || (atom == asciiAtom))
  2564. {
  2565. if (!asciiCharset)
  2566. asciiCharset = new CCharsetInfo(asciiAtom, 0x20, asciiCodepageAtom);
  2567. return LINK(asciiCharset);
  2568. }
  2569. else if (atom == dataAtom)
  2570. {
  2571. if (!dataCharset)
  2572. dataCharset = new CCharsetInfo(dataAtom, 0, asciiCodepageAtom);
  2573. return LINK(dataCharset);
  2574. }
  2575. else if (atom == ebcdicAtom)
  2576. {
  2577. if (!ebcdicCharset)
  2578. ebcdicCharset = new CCharsetInfo(ebcdicAtom, 0x40, ebcdicCodepageAtom);
  2579. return LINK(ebcdicCharset);
  2580. }
  2581. else if (atom == utf8Atom)
  2582. {
  2583. if (!utf8Charset)
  2584. utf8Charset = new CCharsetInfo(utf8Atom, 0x20, utf8Atom);
  2585. return LINK(utf8Charset);
  2586. }
  2587. return NULL;
  2588. }
  2589. ICollationInfo * getCollation(IAtom * atom)
  2590. {
  2591. #if _DEBUG
  2592. const char* name = str(atom);
  2593. #endif
  2594. if ((atom == NULL) || (atom == asciiAtom) || (atom == dataAtom) || (atom == utf8Atom))
  2595. {
  2596. if (!asciiCollation)
  2597. asciiCollation = new CSimpleCollationInfo(asciiAtom);
  2598. return LINK(asciiCollation);
  2599. }
  2600. else if (atom == ebcdicAtom)
  2601. {
  2602. if (!ebcdicCollation)
  2603. ebcdicCollation = new CSimpleCollationInfo(ebcdicAtom);
  2604. return LINK(ebcdicCollation);
  2605. }
  2606. return NULL;
  2607. }
  2608. ITranslationInfo * queryDefaultTranslation(ICharsetInfo * tgt, ICharsetInfo * src)
  2609. {
  2610. if ((src == asciiCharset) && (tgt == ebcdicCharset))
  2611. {
  2612. if (!ascii2ebcdic)
  2613. ascii2ebcdic = new CAscii2EbcdicTranslationInfo;
  2614. return ascii2ebcdic;
  2615. }
  2616. if ((tgt == asciiCharset) && (src == ebcdicCharset))
  2617. {
  2618. if (!ebcdic2ascii)
  2619. ebcdic2ascii = new CEbcdic2AsciiTranslationInfo;
  2620. return ebcdic2ascii;
  2621. }
  2622. return NULL;
  2623. }
  2624. ITranslationInfo * getDefaultTranslation(ICharsetInfo * tgt, ICharsetInfo * src)
  2625. {
  2626. ITranslationInfo *translator = queryDefaultTranslation(tgt, src);
  2627. ::Link(translator);
  2628. return translator;
  2629. }
  2630. //---------------------------------------------------------------------------
  2631. ITypeInfo * getStretchedType(unsigned newLen, ITypeInfo * type)
  2632. {
  2633. switch (type->getTypeCode())
  2634. {
  2635. case type_string:
  2636. return makeStringType(newLen, LINK(type->queryCharset()), LINK(type->queryCollation()));
  2637. case type_varstring:
  2638. return makeVarStringType(newLen, LINK(type->queryCharset()), LINK(type->queryCollation()));
  2639. case type_unicode:
  2640. return makeUnicodeType(newLen, type->queryLocale());
  2641. case type_varunicode:
  2642. return makeVarUnicodeType(newLen, type->queryLocale());
  2643. case type_utf8:
  2644. return makeUtf8Type(newLen, type->queryLocale());
  2645. case type_qstring:
  2646. return makeQStringType(newLen);
  2647. case type_data:
  2648. return makeDataType(newLen);
  2649. case type_int:
  2650. return makeIntType(newLen, type->isSigned());
  2651. default:
  2652. throw MakeStringException(99, "Internal error: getStretchedType");
  2653. }
  2654. return NULL;
  2655. }
  2656. ITypeInfo * getMaxLengthType(ITypeInfo * type)
  2657. {
  2658. switch (type->getTypeCode())
  2659. {
  2660. case type_boolean:
  2661. return LINK(type);
  2662. case type_int:
  2663. return makeIntType(8, type->isSigned());
  2664. case type_string:
  2665. case type_varstring:
  2666. case type_unicode:
  2667. case type_varunicode:
  2668. case type_utf8:
  2669. case type_qstring:
  2670. case type_data:
  2671. return getStretchedType(UNKNOWN_LENGTH, type);
  2672. default:
  2673. return LINK(type);
  2674. }
  2675. return NULL;
  2676. }
  2677. ITypeInfo * getAsciiType(ITypeInfo * type)
  2678. {
  2679. ICharsetInfo * charset = type->queryCharset();
  2680. if (charset && (charset->queryName() != asciiAtom))
  2681. {
  2682. switch (type->getTypeCode())
  2683. {
  2684. case type_string:
  2685. return makeStringType(type->getSize(), NULL, NULL);
  2686. case type_varstring:
  2687. return makeVarStringType(type->getStringLen(), NULL, NULL);
  2688. }
  2689. }
  2690. return LINK(type);
  2691. }
  2692. ITypeInfo * getBandType(ITypeInfo * lType, ITypeInfo * rType)
  2693. {
  2694. if (lType->isBoolean() && rType->isBoolean())
  2695. return LINK(lType);
  2696. unsigned lSize = lType->getSize();
  2697. unsigned rSize = rType->getSize();
  2698. return makeIntType(std::min(lSize,rSize),lType->isSigned()&&rType->isSigned());
  2699. }
  2700. ITypeInfo * getBorType(ITypeInfo * lType, ITypeInfo * rType)
  2701. {
  2702. if (lType->isBoolean() && rType->isBoolean())
  2703. return LINK(lType);
  2704. unsigned lSize = lType->getSize();
  2705. unsigned rSize = rType->getSize();
  2706. return makeIntType(std::max(lSize,rSize),lType->isSigned()&&rType->isSigned());
  2707. }
  2708. bool hasDefaultLocale(ITypeInfo * type)
  2709. {
  2710. return ((type->queryLocale() == 0) || (*str(type->queryLocale()) == 0));
  2711. }
  2712. bool haveCommonLocale(ITypeInfo * type1, ITypeInfo * type2)
  2713. {
  2714. //for the moment, disallow binary ops unless locales identical or one is default --- may later change, e.g. to use common parent where present
  2715. return ((type1->queryLocale() == type2->queryLocale()) || hasDefaultLocale(type1) || hasDefaultLocale(type2));
  2716. }
  2717. IAtom * getCommonLocale(ITypeInfo * type1, ITypeInfo * type2)
  2718. {
  2719. //for the moment, disallow binary ops unless locales identical or one is default --- may later change, e.g. to use common parent where present
  2720. if(!hasDefaultLocale(type1))
  2721. return type1->queryLocale();
  2722. return type2->queryLocale();
  2723. }
  2724. bool isLittleEndian(ITypeInfo * type)
  2725. {
  2726. switch (type->getTypeCode())
  2727. {
  2728. case type_packedint:
  2729. return true;
  2730. case type_int:
  2731. #if __BYTE_ORDER == __LITTLE_ENDIAN
  2732. return true;
  2733. #else
  2734. return false;
  2735. #endif
  2736. case type_swapint:
  2737. #if __BYTE_ORDER == __LITTLE_ENDIAN
  2738. return false;
  2739. #else
  2740. return true;
  2741. #endif
  2742. default:
  2743. return true;
  2744. }
  2745. }
  2746. inline ITypeInfo * queryChildType(ITypeInfo * t, type_t search)
  2747. {
  2748. while (t)
  2749. {
  2750. type_t code = t->getTypeCode();
  2751. if (code == search)
  2752. return t;
  2753. switch (code)
  2754. {
  2755. case type_set:
  2756. case type_dictionary:
  2757. case type_groupedtable:
  2758. case type_row:
  2759. case type_table:
  2760. case type_rule:
  2761. case type_transform:
  2762. case type_function:
  2763. case type_pointer:
  2764. case type_array:
  2765. t = t->queryChildType();
  2766. break;
  2767. default:
  2768. return NULL;
  2769. }
  2770. }
  2771. return NULL;
  2772. }
  2773. ITypeInfo * queryRowType(ITypeInfo * t)
  2774. {
  2775. return queryChildType(t, type_row);
  2776. }
  2777. ITypeInfo * queryRecordType(ITypeInfo * t)
  2778. {
  2779. return queryChildType(t, type_record);
  2780. }
  2781. ITypeInfo * queryUnqualifiedType(ITypeInfo * t)
  2782. {
  2783. if (!t)
  2784. return t;
  2785. loop
  2786. {
  2787. ITypeInfo * base = t->queryTypeBase();
  2788. if (base == t)
  2789. return t;
  2790. t = base;
  2791. }
  2792. }
  2793. ITypeInfo * getFullyUnqualifiedType(ITypeInfo * t)
  2794. {
  2795. if (!t)
  2796. return t;
  2797. loop
  2798. {
  2799. ITypeInfo * base = t->queryTypeBase();
  2800. if (base == t)
  2801. {
  2802. ITypeInfo * child = t->queryChildType();
  2803. if (!child)
  2804. return LINK(t);
  2805. Owned<ITypeInfo> newChild = getFullyUnqualifiedType(child);
  2806. return replaceChildType(t, newChild);
  2807. }
  2808. t = base;
  2809. }
  2810. }
  2811. ITypeInfo * removeModifier(ITypeInfo * t, typemod_t modifier)
  2812. {
  2813. typemod_t curModifier = t->queryModifier();
  2814. if (curModifier == typemod_none)
  2815. return LINK(t);
  2816. ITypeInfo * base = t->queryTypeBase();
  2817. if (curModifier == modifier)
  2818. return LINK(base);
  2819. OwnedITypeInfo newBase = removeModifier(base, modifier);
  2820. if (newBase == base)
  2821. return LINK(t);
  2822. return makeModifier(newBase.getClear(), curModifier, LINK(t->queryModifierExtra()));
  2823. }
  2824. bool hasModifier(ITypeInfo * t, typemod_t modifier)
  2825. {
  2826. loop
  2827. {
  2828. typemod_t curModifier = t->queryModifier();
  2829. if (curModifier == modifier)
  2830. return true;
  2831. if (curModifier == typemod_none)
  2832. return false;
  2833. t = t->queryTypeBase();
  2834. }
  2835. }
  2836. ITypeInfo * queryModifier(ITypeInfo * t, typemod_t modifier)
  2837. {
  2838. loop
  2839. {
  2840. typemod_t curModifier = t->queryModifier();
  2841. if (curModifier == modifier)
  2842. return t;
  2843. if (curModifier == typemod_none)
  2844. return NULL;
  2845. t = t->queryTypeBase();
  2846. }
  2847. }
  2848. ITypeInfo * cloneModifier(ITypeInfo * donorModifier, ITypeInfo * srcType)
  2849. {
  2850. typemod_t curModifier = donorModifier->queryModifier();
  2851. assertex(curModifier != typemod_none);
  2852. return makeModifier(LINK(srcType), curModifier, LINK(donorModifier->queryModifierExtra()));
  2853. }
  2854. ITypeInfo * cloneModifiers(ITypeInfo * donorType, ITypeInfo * srcType)
  2855. {
  2856. typemod_t curModifier = donorType->queryModifier();
  2857. if (curModifier == typemod_none)
  2858. return LINK(srcType);
  2859. ITypeInfo * base = donorType->queryTypeBase();
  2860. return makeModifier(cloneModifiers(base, srcType), curModifier, LINK(donorType->queryModifierExtra()));
  2861. }
  2862. ITypeInfo * replaceChildType(ITypeInfo * type, ITypeInfo * newChild)
  2863. {
  2864. if (type->queryChildType() == newChild)
  2865. return LINK(type);
  2866. OwnedITypeInfo newType;
  2867. switch (type->getTypeCode())
  2868. {
  2869. case type_dictionary:
  2870. newType.setown(makeDictionaryType(LINK(newChild)));
  2871. break;
  2872. case type_table:
  2873. newType.setown(makeTableType(LINK(newChild)));
  2874. break;
  2875. case type_groupedtable:
  2876. newType.setown(makeGroupedTableType(LINK(newChild)));
  2877. break;
  2878. case type_row:
  2879. newType.setown(makeRowType(LINK(newChild)));
  2880. break;
  2881. case type_set:
  2882. newType.setown(makeSetType(LINK(newChild)));
  2883. break;
  2884. case type_transform:
  2885. newType.setown(makeTransformType(LINK(newChild)));
  2886. break;
  2887. case type_sortlist:
  2888. newType.setown(makeSortListType(LINK(newChild)));
  2889. break;
  2890. case type_rule:
  2891. newType.setown(makeRuleType(LINK(newChild)));
  2892. break;
  2893. default:
  2894. throwUnexpected();
  2895. }
  2896. return cloneModifiers(type, newType);
  2897. }
  2898. //---------------------------------------------------------------------------
  2899. extern unsigned getClarionResultType(ITypeInfo *type)
  2900. {
  2901. if (type)
  2902. {
  2903. return type->getTypeCode() | (type->getSize() << 16) |
  2904. (type->isInteger() && !type->isSigned() ? type_unsigned : 0) |
  2905. (type->queryCharset() && type->queryCharset()->queryName()==ebcdicAtom ? type_ebcdic : 0);
  2906. }
  2907. else
  2908. return 0;
  2909. }
  2910. //---------------------------------------------------------------------------
  2911. extern DEFTYPE_API ICharsetInfo * deserializeCharsetInfo(MemoryBuffer &src)
  2912. {
  2913. StringAttr name;
  2914. src.read(name);
  2915. return getCharset(createLowerCaseAtom(name));
  2916. }
  2917. extern DEFTYPE_API ICollationInfo * deserializeCollationInfo(MemoryBuffer &src)
  2918. {
  2919. StringAttr name;
  2920. src.read(name);
  2921. return getCollation(createLowerCaseAtom(name));
  2922. }
  2923. extern DEFTYPE_API ITypeInfo * deserializeType(MemoryBuffer &src)
  2924. {
  2925. unsigned char tc;
  2926. src.read(tc);
  2927. switch(tc)
  2928. {
  2929. case type_none:
  2930. return NULL;
  2931. case type_int:
  2932. {
  2933. unsigned char size;
  2934. bool isSigned;
  2935. src.read(size);
  2936. src.read(isSigned);
  2937. return makeIntType(size, isSigned);
  2938. }
  2939. case type_swapint:
  2940. {
  2941. unsigned char size;
  2942. bool isSigned;
  2943. src.read(size);
  2944. src.read(isSigned);
  2945. return makeSwapIntType(size, isSigned);
  2946. }
  2947. case type_packedint:
  2948. {
  2949. unsigned char size;
  2950. bool isSigned;
  2951. src.read(size);
  2952. src.read(isSigned);
  2953. return makePackedIntType(size, isSigned);
  2954. }
  2955. case type_char:
  2956. {
  2957. bool isCaseSensitive;
  2958. src.read(isCaseSensitive);
  2959. return makeCharType(isCaseSensitive);
  2960. }
  2961. case type_real:
  2962. {
  2963. unsigned char size;
  2964. src.read(size);
  2965. return makeRealType(size);
  2966. }
  2967. case type_boolean:
  2968. return makeBoolType();
  2969. case type_blob:
  2970. return makeBlobType();
  2971. case type_void:
  2972. return makeVoidType();
  2973. case type_null:
  2974. return makeNullType();
  2975. case type_pattern:
  2976. return makePatternType();
  2977. case type_rule:
  2978. {
  2979. ITypeInfo *base = deserializeType(src);
  2980. return makeRuleType(base);
  2981. }
  2982. case type_token:
  2983. return makeTokenType();
  2984. case type_feature:
  2985. return makeFeatureType();
  2986. case type_event:
  2987. return makeEventType();
  2988. case type_string:
  2989. case type_varstring:
  2990. {
  2991. size32_t size;
  2992. bool b;
  2993. src.read(size);
  2994. src.read(b);
  2995. ICollationInfo *collation = b ? deserializeCollationInfo(src) : NULL;
  2996. src.read(b);
  2997. ICharsetInfo *charset = b ? deserializeCharsetInfo(src) : NULL;
  2998. if (tc==type_string)
  2999. return makeStringType(size, charset, collation);
  3000. else
  3001. {
  3002. if (size != UNKNOWN_LENGTH) size--;
  3003. return makeVarStringType(size, charset, collation);
  3004. }
  3005. }
  3006. case type_unicode:
  3007. {
  3008. size32_t size;
  3009. StringAttr locale;
  3010. src.read(size);
  3011. src.read(locale);
  3012. return makeUnicodeType(size, createLowerCaseAtom(locale.get()));
  3013. }
  3014. case type_varunicode:
  3015. {
  3016. size32_t size;
  3017. StringAttr locale;
  3018. src.read(size);
  3019. src.read(locale);
  3020. return makeVarUnicodeType(size, createLowerCaseAtom(locale.get()));
  3021. }
  3022. case type_utf8:
  3023. {
  3024. size32_t size;
  3025. StringAttr locale;
  3026. src.read(size);
  3027. src.read(locale);
  3028. return makeUtf8Type(size, createLowerCaseAtom(locale.get()));
  3029. }
  3030. case type_qstring:
  3031. {
  3032. size32_t size;
  3033. src.read(size);
  3034. return makeQStringType(size);
  3035. }
  3036. case type_data:
  3037. {
  3038. size32_t size;
  3039. src.read(size);
  3040. return makeDataType(size);
  3041. }
  3042. case type_decimal:
  3043. {
  3044. unsigned char prec, digits;
  3045. bool isSigned;
  3046. src.read(prec);
  3047. src.read(digits);
  3048. src.read(isSigned);
  3049. unsigned fulldigits = (digits == CDecimalTypeInfo::UNKNOWN_DIGITS) ? UNKNOWN_LENGTH : digits;
  3050. unsigned fullprec = (prec == CDecimalTypeInfo::UNKNOWN_DIGITS) ? UNKNOWN_LENGTH : prec;
  3051. return makeDecimalType(fulldigits, fullprec, isSigned);
  3052. }
  3053. case type_bitfield:
  3054. {
  3055. int bitLength;
  3056. src.read(bitLength);
  3057. ITypeInfo *base = deserializeType(src);
  3058. return makeBitfieldType(bitLength, base);
  3059. }
  3060. case type_set:
  3061. {
  3062. ITypeInfo *base = deserializeType(src);
  3063. return makeSetType(base);
  3064. }
  3065. case type_pointer:
  3066. {
  3067. ITypeInfo *base = deserializeType(src);
  3068. return makePointerType(base);
  3069. }
  3070. case type_array:
  3071. {
  3072. size32_t size;
  3073. src.read(size);
  3074. ITypeInfo *base = deserializeType(src);
  3075. return makeArrayType(base, size);
  3076. }
  3077. case type_class:
  3078. {
  3079. StringAttr name;
  3080. src.read(name);
  3081. return makeClassType(name);
  3082. }
  3083. case type_record:
  3084. return makeRecordType();
  3085. case type_table:
  3086. {
  3087. ITypeInfo *base = deserializeType(src);
  3088. return makeTableType(makeRowType(base));
  3089. }
  3090. case type_groupedtable:
  3091. {
  3092. ITypeInfo *base = deserializeType(src);
  3093. return makeGroupedTableType(base);
  3094. }
  3095. }
  3096. assertex(false);
  3097. return NULL;
  3098. }
  3099. void serializeType(MemoryBuffer &tgt, ITypeInfo * type)
  3100. {
  3101. if (type)
  3102. type->serialize(tgt);
  3103. else
  3104. tgt.append((byte)type_none);
  3105. }
  3106. bool getNormalizedLocaleName(unsigned len, char const * str, StringBuffer & buff)
  3107. {
  3108. return rtlGetNormalizedUnicodeLocaleName(len, str, buff.reserve(len));
  3109. }
  3110. //---------------------------------------------------------------------------
  3111. static bool alreadyHadSize(int size, IntArray &sizes)
  3112. {
  3113. ForEachItemIn(idx, sizes)
  3114. {
  3115. if (sizes.item(idx)==size)
  3116. return true;
  3117. }
  3118. sizes.append(size);
  3119. return false;
  3120. }
  3121. StringBuffer &appendStartComplexType(StringBuffer &xml, bool hasMixedContent, unsigned *updatePos)
  3122. {
  3123. xml.append("<xs:complexType");
  3124. if (hasMixedContent || updatePos)
  3125. xml.append(" mixed=\"").append(hasMixedContent ? '1' : '0').append('\"');
  3126. if (updatePos)
  3127. *updatePos = xml.length()-2;
  3128. return xml.append('>');
  3129. }
  3130. void XmlSchemaBuilder::addSchemaPrefix(bool hasMixedContent)
  3131. {
  3132. if (addHeader)
  3133. xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
  3134. xml.append(
  3135. "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:hpcc=\"urn:hpccsystems:xsd:appinfo\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\">\n"
  3136. "<xs:element name=\"Dataset\">"
  3137. "<xs:complexType>"
  3138. "<xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">\n"
  3139. "<xs:element name=\"Row\">");
  3140. appendStartComplexType(xml, hasMixedContent, NULL).append("<xs:sequence>\n");
  3141. attributes.append(*new StringBufferItem);
  3142. }
  3143. void XmlSchemaBuilder::addSchemaSuffix()
  3144. {
  3145. xml.append( "</xs:sequence>");
  3146. xml.append(attributes.tos());
  3147. attributes.pop();
  3148. xml.append( "</xs:complexType>"
  3149. "</xs:element>\n"
  3150. "</xs:sequence>"
  3151. "</xs:complexType>"
  3152. "</xs:element>\n");
  3153. xml.append(typesXml);
  3154. xml.append("</xs:schema>");
  3155. }
  3156. void XmlSchemaBuilder::getXmlTypeName(StringBuffer & xmlType, ITypeInfo & type)
  3157. {
  3158. size32_t len = type.getStringLen();
  3159. switch (type.getTypeCode())
  3160. {
  3161. case type_boolean:
  3162. xmlType.append("xs:boolean"); break;
  3163. case type_real:
  3164. xmlType.append("xs:double"); break;
  3165. case type_int:
  3166. case type_swapint:
  3167. case type_packedint:
  3168. case type_bitfield:
  3169. //MORE: Could generate different types depending on the size of the fields (e.g., long/unsignedLong)
  3170. if (type.isSigned())
  3171. xmlType.append("xs:integer");
  3172. else
  3173. xmlType.append("xs:nonNegativeInteger");
  3174. break;
  3175. case type_data:
  3176. if (len == UNKNOWN_LENGTH)
  3177. xmlType.append("xs:hexBinary");
  3178. else
  3179. {
  3180. xmlType.append("data").append(len);
  3181. if (!alreadyHadSize(len, dataSizes))
  3182. {
  3183. typesXml.appendf(
  3184. "<xs:simpleType name=\"data%d\">"
  3185. "<xs:restriction base=\"xs:hexBinary\">"
  3186. "<xs:length value=\"%d\"/>"
  3187. "</xs:restriction>"
  3188. "</xs:simpleType>", len, len).newline();
  3189. }
  3190. }
  3191. break;
  3192. case type_decimal:
  3193. type.getECLType(xmlType);
  3194. len = type.getDigits()*255 + type.getPrecision();
  3195. if (!alreadyHadSize(len, decimalSizes))
  3196. {
  3197. typesXml.append("<xs:simpleType name=\"");
  3198. type.getECLType(typesXml);
  3199. typesXml.append("\"><xs:restriction base=\"xs:decimal\">");
  3200. typesXml.appendf("<xs:totalDigits value=\"%d\"/>", type.getDigits());
  3201. typesXml.appendf("<xs:fractionalDigits value=\"%d\" fixed=\"true\"/>", type.getPrecision());
  3202. typesXml.append("</xs:restriction></xs:simpleType>").newline();
  3203. }
  3204. break;
  3205. case type_string:
  3206. case type_qstring:
  3207. case type_unicode:
  3208. case type_varstring:
  3209. case type_varunicode:
  3210. case type_utf8:
  3211. //NB: xs::maxLength is in unicode characters...
  3212. if (len==UNKNOWN_LENGTH)
  3213. xmlType.append("xs:string");
  3214. else
  3215. {
  3216. xmlType.append("string").append(len);
  3217. if (!alreadyHadSize(len, stringSizes))
  3218. {
  3219. typesXml.appendf("<xs:simpleType name=\"string%d\">"
  3220. "<xs:restriction base=\"xs:string\">"
  3221. "<xs:maxLength value=\"%d\"/>"
  3222. "</xs:restriction>"
  3223. "</xs:simpleType>", len, len).newline();
  3224. }
  3225. }
  3226. break;
  3227. case type_set:
  3228. {
  3229. StringBuffer elementName;
  3230. getXmlTypeName(elementName, *type.queryChildType());
  3231. unsigned typeIndex = setTypes.find(type);
  3232. if (typeIndex == NotFound)
  3233. {
  3234. typeIndex = setTypes.ordinality();
  3235. setTypes.append(type);
  3236. typesXml.appendf("<xs:complexType name=\"setof_%s_%d\"><xs:sequence>"
  3237. "<xs:element name=\"All\" minOccurs=\"0\"><xs:complexType/></xs:element>"
  3238. "<xs:element name=\"Item\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"%s\"/>"
  3239. "</xs:sequence></xs:complexType>", elementName.str(), typeIndex, elementName.str()).newline();
  3240. }
  3241. //%d is to ensure it is unique e.g., integers come back as the same xml type.
  3242. xmlType.appendf("setof_%s_%d", elementName.str(), typeIndex);
  3243. break;
  3244. }
  3245. default:
  3246. UNIMPLEMENTED;
  3247. }
  3248. }
  3249. void XmlSchemaBuilder::appendField(StringBuffer &s, const char * name, ITypeInfo & type, bool keyed)
  3250. {
  3251. const char * tag = name;
  3252. if (*tag == '@')
  3253. {
  3254. s.append("<xs:attribute");
  3255. tag++;
  3256. }
  3257. else
  3258. s.append("<xs:element");
  3259. s.append(" name=\"").append(tag).append("\" type=\"");
  3260. getXmlTypeName(s, type);
  3261. s.append("\"");
  3262. if (optionalNesting)
  3263. {
  3264. if (*name == '@')
  3265. s.append(" use=\"optional\"");
  3266. else
  3267. s.append(" minOccurs=\"0\"");
  3268. }
  3269. else
  3270. {
  3271. if (*name == '@')
  3272. s.append(" use=\"required\"");
  3273. }
  3274. if (keyed)
  3275. {
  3276. s.append("><xs:annotation><xs:appinfo hpcc:keyed=\"true\"/></xs:annotation>");
  3277. if (*name == '@')
  3278. s.append("</xs:attribute>\n");
  3279. else
  3280. s.append("</xs:element>\n");
  3281. }
  3282. else
  3283. s.append("/>\n");
  3284. }
  3285. void XmlSchemaBuilder::addField(const char * name, ITypeInfo & type, bool keyed)
  3286. {
  3287. if (xml.length() == 0)
  3288. addSchemaPrefix();
  3289. if (!*name)
  3290. return;
  3291. if (*name == '@')
  3292. {
  3293. if (attributes.length())
  3294. appendField(attributes.tos(), name, type, keyed);
  3295. }
  3296. else
  3297. appendField(xml, name, type, keyed);
  3298. }
  3299. void XmlSchemaBuilder::addSetField(const char * name, const char * itemname, ITypeInfo & type)
  3300. {
  3301. if (xml.length() == 0)
  3302. addSchemaPrefix();
  3303. if (!name || !*name) //xpath('') content inherited by parent
  3304. return;
  3305. StringBuffer elementType;
  3306. getXmlTypeName(elementType, *type.queryChildType());
  3307. if (!itemname || !*itemname) // xpaths 'Name', '/Name', and 'Name/' seem to be equivalent
  3308. {
  3309. itemname = name;
  3310. name = NULL;
  3311. }
  3312. if (name && *name)
  3313. {
  3314. xml.append("<xs:element name=\"").append(name).append("\"");
  3315. if (optionalNesting)
  3316. xml.append(" minOccurs=\"0\"");
  3317. xml.append(">").newline();
  3318. xml.append("<xs:complexType><xs:sequence>"); // could use xs::choice instead
  3319. xml.append("<xs:element name=\"All\" minOccurs=\"0\"/>").newline();
  3320. }
  3321. xml.append("<xs:element name=\"").append(itemname).append("\" minOccurs=\"0\" maxOccurs=\"unbounded\" type=\"").append(elementType).append("\"/>").newline();
  3322. if (name && *name)
  3323. xml.append("</xs:sequence></xs:complexType></xs:element>").newline();
  3324. }
  3325. void XmlSchemaBuilder::beginRecord(const char * name, bool hasMixedContent, unsigned *updatePos)
  3326. {
  3327. if (!name || !*name)
  3328. return;
  3329. if (xml.length() == 0)
  3330. addSchemaPrefix(hasMixedContent);
  3331. attributes.append(*new StringBufferItem);
  3332. xml.append("<xs:element name=\"").append(name).append("\"");
  3333. if (optionalNesting)
  3334. xml.append(" minOccurs=\"0\"");
  3335. xml.append(">").newline();
  3336. appendStartComplexType(xml, hasMixedContent, updatePos);
  3337. xml.append("<xs:sequence>").newline();
  3338. nesting.append(optionalNesting);
  3339. optionalNesting = 0;
  3340. }
  3341. void XmlSchemaBuilder::updateMixedRecord(unsigned updatePos, bool hasMixedContent)
  3342. {
  3343. if (updatePos)
  3344. xml.setCharAt(updatePos, hasMixedContent ? '1' : '0');
  3345. }
  3346. void XmlSchemaBuilder::endRecord(const char * name)
  3347. {
  3348. if (!name || !*name)
  3349. return;
  3350. xml.append("</xs:sequence>").newline();
  3351. xml.append(attributes.tos());
  3352. attributes.pop();
  3353. xml.append("</xs:complexType>").newline();
  3354. xml.append("</xs:element>").newline();
  3355. optionalNesting = nesting.popGet();
  3356. }
  3357. bool XmlSchemaBuilder::beginDataset(const char * name, const char * row, bool hasMixedContent, unsigned *updatePos)
  3358. {
  3359. if (xml.length() == 0)
  3360. addSchemaPrefix();
  3361. if ((!name || !*name) && row) // xpath("Name") and xpath("/Name") seem to be equivalent
  3362. {
  3363. name = row;
  3364. row = NULL;
  3365. }
  3366. if (name && *name)
  3367. {
  3368. xml.append("<xs:element name=\"").append(name).append("\"");
  3369. if (!row || !*row)
  3370. xml.append(" minOccurs=\"0\" maxOccurs=\"unbounded\"");
  3371. else if (optionalNesting)
  3372. xml.append(" minOccurs=\"0\"");
  3373. xml.append(">").newline();
  3374. if (row && *row)
  3375. appendStartComplexType(xml, false, NULL);
  3376. else
  3377. appendStartComplexType(xml, hasMixedContent, updatePos);
  3378. xml.newline();
  3379. }
  3380. xml.append("<xs:sequence");
  3381. if (!name || !*name || (row && *row))
  3382. xml.append(" minOccurs=\"0\" maxOccurs=\"unbounded\"");
  3383. xml.append('>').newline();
  3384. if (row && *row)
  3385. {
  3386. attributes.append(*new StringBufferItem);
  3387. xml.append("<xs:element name=\"").append(row).append("\">").newline();
  3388. appendStartComplexType(xml, hasMixedContent, updatePos);
  3389. xml.append("<xs:sequence>").newline();
  3390. }
  3391. nesting.append(optionalNesting);
  3392. optionalNesting = 0;
  3393. return true;
  3394. }
  3395. void XmlSchemaBuilder::endDataset(const char * name, const char * row)
  3396. {
  3397. if ((!name || !*name) && row) // xpath("Name") and xpath("/Name") seem to be equivalent
  3398. {
  3399. name = row;
  3400. row = NULL;
  3401. }
  3402. if (row && *row)
  3403. {
  3404. xml.append("</xs:sequence>").newline();
  3405. xml.append(attributes.tos());
  3406. attributes.pop();
  3407. xml.append("</xs:complexType></xs:element>").newline();
  3408. }
  3409. xml.append("</xs:sequence>").newline();
  3410. if (name && *name)
  3411. {
  3412. xml.append("</xs:complexType>").newline();
  3413. xml.append("</xs:element>").newline();
  3414. }
  3415. optionalNesting = nesting.popGet();
  3416. }
  3417. bool XmlSchemaBuilder::addSingleFieldDataset(const char * name, const char * childname, ITypeInfo & type)
  3418. {
  3419. if (xml.length() == 0)
  3420. addSchemaPrefix();
  3421. if (name && *name)
  3422. {
  3423. xml.append("<xs:element name=\"").append(name).append("\"");
  3424. if (optionalNesting)
  3425. xml.append(" minOccurs=\"0\"");
  3426. xml.append(">").newline();
  3427. xml.append("<xs:complexType>").newline();
  3428. }
  3429. xml.append("<xs:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">").newline();
  3430. addField(childname, type, false);
  3431. xml.append("</xs:sequence>").newline();
  3432. if (name && *name)
  3433. {
  3434. xml.append("</xs:complexType>").newline();
  3435. xml.append("</xs:element>").newline();
  3436. }
  3437. return true;
  3438. }
  3439. void XmlSchemaBuilder::clear()
  3440. {
  3441. xml.clear();
  3442. dataSizes.kill();
  3443. stringSizes.kill();
  3444. decimalSizes.kill();
  3445. nesting.kill();
  3446. optionalNesting = 0;
  3447. }
  3448. void XmlSchemaBuilder::getXml(StringBuffer & results)
  3449. {
  3450. if (xml.length() != 0)
  3451. {
  3452. addSchemaSuffix();
  3453. results.append(xml);
  3454. clear();
  3455. }
  3456. }
  3457. void XmlSchemaBuilder::getXml(IStringVal & results)
  3458. {
  3459. if (xml.length() != 0)
  3460. {
  3461. addSchemaSuffix();
  3462. results.set(xml);
  3463. clear();
  3464. }
  3465. else
  3466. results.clear();
  3467. }