deftype.cpp 105 KB

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