deftype.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  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. #ifndef _DEFTYPE_INCL
  14. #define _DEFTYPE_INCL
  15. #include "jcomp.hpp"
  16. #include "rtlconst.hpp"
  17. #ifdef DEFTYPE_EXPORTS
  18. #define DEFTYPE_API DECL_EXPORT
  19. #else
  20. #define DEFTYPE_API DECL_IMPORT
  21. #endif
  22. #define CHEAP_UCHAR_DEF
  23. #ifdef _WIN32
  24. typedef wchar_t UChar;
  25. #else //_WIN32
  26. typedef unsigned short UChar;
  27. #endif //_WIN32
  28. interface ITypeInfo;
  29. interface IValue;
  30. interface IHqlExpression;
  31. interface IHqlScope;
  32. #if __BYTE_ORDER == __LITTLE_ENDIAN
  33. #define type_bigendianint type_swapint
  34. #define type_littleendianint type_int
  35. #else
  36. #define type_bigendianint type_int
  37. #define type_littleendianint type_swapint
  38. #endif
  39. enum typemod_t
  40. {
  41. typemod_none = 0,
  42. typemod_const = 1,
  43. typemod_ref = 2,
  44. typemod_wrapper = 3,
  45. typemod_builder = 4,
  46. typemod_original = 5,
  47. typemod_member = 6,
  48. typemod_serialized = 7,
  49. typemod_outofline = 8,
  50. typemod_attr = 9,
  51. typemod_indirect = 10, // type definition needs to go via an ecl definition
  52. typemod_mutable = 11,
  53. typemod_nonconst = 12,
  54. typemod_max
  55. };
  56. #define INFINITE_LENGTH 0xFFFFFFF0
  57. #define UNKNOWN_LENGTH 0xFFFFFFF1
  58. typedef enum type_vals type_t;
  59. //MORE: Something like this should replace caseSensitive for strings...
  60. interface ICollationInfo;
  61. interface ICharsetInfo : public serializable
  62. {
  63. public:
  64. virtual IAtom * queryName() = 0;
  65. virtual ICollationInfo * queryDefaultCollation() = 0;
  66. virtual unsigned char queryFillChar() = 0;
  67. virtual char const * queryCodepageName() = 0;
  68. };
  69. interface ICollationInfo : public serializable
  70. {
  71. public:
  72. virtual IAtom * queryName() = 0;
  73. virtual ICharsetInfo * getCharset() = 0;
  74. virtual int compare(const char * left, const char * right, unsigned len) = 0;
  75. virtual const char * getCompareName(bool varLength) = 0;
  76. };
  77. interface ITranslationInfo : public IInterface
  78. {
  79. public:
  80. virtual IAtom * queryName() = 0;
  81. virtual const char * queryRtlFunction() = 0;
  82. virtual const char * queryVarRtlFunction() = 0;
  83. virtual ICharsetInfo * querySourceCharset() = 0;
  84. virtual ICharsetInfo * queryTargetCharset() = 0;
  85. virtual StringBuffer & translate(StringBuffer & tgt, unsigned len, const char * src) = 0;
  86. };
  87. interface IValue;
  88. interface ITypeInfo : public serializable
  89. {
  90. public:
  91. virtual type_t getTypeCode() const = 0;
  92. virtual size32_t getSize() = 0;
  93. virtual unsigned getAlignment() = 0;
  94. virtual unsigned getBitSize() = 0;
  95. virtual unsigned getPrecision() = 0;
  96. virtual unsigned getStringLen() = 0;
  97. virtual unsigned getDigits() = 0;
  98. virtual bool assignableFrom(ITypeInfo * source) = 0;
  99. virtual IValue * castFrom(bool isSignedValue, __int64 value) = 0;
  100. virtual IValue * castFrom(double value) = 0;
  101. virtual IValue * castFrom(size32_t len, const char * text) = 0;
  102. virtual IValue * castFrom(size32_t len, const UChar * text) = 0;
  103. virtual StringBuffer &getECLType(StringBuffer & out) = 0;
  104. virtual StringBuffer &getDescriptiveType(StringBuffer & out) = 0;
  105. virtual const char *queryTypeName() = 0;
  106. virtual unsigned getCardinality() = 0;
  107. virtual bool isInteger() = 0;
  108. virtual bool isReference() = 0;
  109. virtual bool isScalar() = 0;
  110. virtual bool isSigned() = 0;
  111. virtual bool isSwappedEndian() = 0;
  112. virtual ITypeInfo * queryChildType() = 0;
  113. virtual ICharsetInfo * queryCharset() = 0;
  114. virtual ICollationInfo * queryCollation() = 0;
  115. virtual IAtom * queryLocale() = 0;
  116. virtual ITypeInfo * queryPromotedType() = 0;
  117. virtual ITypeInfo * queryTypeBase() = 0;
  118. virtual unsigned getCrc() = 0; // must be run independant.
  119. virtual typemod_t queryModifier() = 0;
  120. virtual IInterface * queryModifierExtra() = 0;
  121. virtual IHqlExpression * castToExpression() = 0; // Here to avoid dynamic casts
  122. virtual IHqlScope * castToScope() = 0;
  123. inline bool isBoolean() const { return getTypeCode() == type_boolean; }
  124. inline bool isUnsignedNumeric() { return (isInteger() || getTypeCode()==type_decimal) && !isSigned(); }
  125. };
  126. interface IFunctionTypeExtra : public IInterface
  127. {
  128. virtual IInterface * queryParameters() const = 0;
  129. virtual IInterface * queryDefaults() const = 0;
  130. virtual IInterface * queryAttributes() const = 0;
  131. };
  132. interface IEnumeratedTypeBuilder : public IInterface
  133. {
  134. public:
  135. virtual ITypeInfo *getTypeInfo() = 0;
  136. virtual int addValue(IValue *val, size32_t frequency) = 0;
  137. };
  138. extern DEFTYPE_API ITypeInfo *makeStringType(unsigned size, ICharsetInfo * _charset = NULL, ICollationInfo * _collation = NULL);
  139. extern DEFTYPE_API ITypeInfo *makeVarStringType(unsigned size, ICharsetInfo * _charset = NULL, ICollationInfo * _collation = NULL); //NB: size is numchars+1
  140. extern DEFTYPE_API ITypeInfo *makeQStringType(int len);
  141. extern DEFTYPE_API ITypeInfo *makeUnicodeType(unsigned len, IAtom * locale); // takes length in UChars, i.e. bytes/2 if known; locale is like fr_BE_EURO, or 0 for default
  142. extern DEFTYPE_API ITypeInfo *makeVarUnicodeType(unsigned len, IAtom * locale); // takes length in UChars + 1, i.e. bytes/2 + 1 if known; locale is like fr_BE_EURO, or 0 for default
  143. extern DEFTYPE_API ITypeInfo *makeUtf8Type(unsigned len, IAtom * locale); // takes length in UChars, i.e. bytes/4 if known; locale is like fr_BE_EURO, or 0 for default
  144. extern DEFTYPE_API ITypeInfo *makeCharType(bool caseSensitive = false);
  145. extern DEFTYPE_API ITypeInfo *makeIntType(int size, bool isSigned);
  146. extern DEFTYPE_API ITypeInfo *makeSwapIntType(int size, bool isSigned);
  147. extern DEFTYPE_API ITypeInfo *makePackedIntType(ITypeInfo * basetype);
  148. extern DEFTYPE_API ITypeInfo *makePackedIntType(int size, bool isSigned);
  149. extern DEFTYPE_API ITypeInfo *makeFilePosType(ITypeInfo *basetype);
  150. extern DEFTYPE_API ITypeInfo *makeKeyedIntType(ITypeInfo *basetype);
  151. extern DEFTYPE_API ITypeInfo *makeRealType(int size);
  152. extern DEFTYPE_API ITypeInfo *makeDataType(int size);
  153. extern DEFTYPE_API ITypeInfo *makeBitfieldType(int sizeInBits, ITypeInfo * basetype = NULL);
  154. extern DEFTYPE_API ITypeInfo *makeBoolType();
  155. extern DEFTYPE_API ITypeInfo *makeBlobType();
  156. extern DEFTYPE_API ITypeInfo *makeKeyedBlobType(ITypeInfo * basetype);
  157. extern DEFTYPE_API ITypeInfo *makeRecordType(); // not used by any IHqlExpressions
  158. extern DEFTYPE_API ITypeInfo *makeVoidType();
  159. extern DEFTYPE_API ITypeInfo *makeNullType();
  160. extern DEFTYPE_API ITypeInfo *makeEventType();
  161. extern DEFTYPE_API ITypeInfo *makeAnyType();
  162. extern DEFTYPE_API IEnumeratedTypeBuilder *makeEnumeratedTypeBuilder(ITypeInfo *base, aindex_t numvalues);
  163. extern DEFTYPE_API ITypeInfo *makeDecimalType(unsigned digits, unsigned prec, bool isSigned);
  164. extern DEFTYPE_API ITypeInfo *makeDictionaryType(ITypeInfo *basetype);
  165. extern DEFTYPE_API ITypeInfo *makeTableType(ITypeInfo *basetype);
  166. extern DEFTYPE_API ITypeInfo *makeGroupedTableType(ITypeInfo *basetype);
  167. extern DEFTYPE_API ITypeInfo *makeRowType(ITypeInfo *basetype);
  168. extern DEFTYPE_API ITypeInfo *makeSetType(ITypeInfo *basetype);
  169. extern DEFTYPE_API ITypeInfo *makeTransformType(ITypeInfo *basetype);
  170. extern DEFTYPE_API ITypeInfo *makeSortListType(ITypeInfo *basetype);
  171. extern DEFTYPE_API ITypeInfo *makeFunctionType(ITypeInfo *basetype, IInterface * args, IInterface * defaults, IInterface * attrs);
  172. extern DEFTYPE_API ITypeInfo * makePointerType(ITypeInfo * basetype);
  173. extern DEFTYPE_API ITypeInfo * makeArrayType(ITypeInfo * basetype, unsigned size=0);
  174. extern DEFTYPE_API ITypeInfo * makeClassType(const char * className);
  175. extern DEFTYPE_API ITypeInfo * makeConstantModifier(ITypeInfo * basetype);
  176. extern DEFTYPE_API ITypeInfo * makeNonConstantModifier(ITypeInfo * basetype);
  177. extern DEFTYPE_API ITypeInfo * makeReferenceModifier(ITypeInfo * basetype);
  178. extern DEFTYPE_API ITypeInfo * makeWrapperModifier(ITypeInfo * basetype);
  179. extern DEFTYPE_API ITypeInfo * makeModifier(ITypeInfo * basetype, typemod_t modifier, IInterface * extra=NULL);
  180. extern DEFTYPE_API ITypeInfo * makePatternType();
  181. extern DEFTYPE_API ITypeInfo * makeRuleType(ITypeInfo * attrType);
  182. extern DEFTYPE_API ITypeInfo * makeTokenType();
  183. extern DEFTYPE_API ITypeInfo * makeFeatureType();
  184. inline ITypeInfo * makeOutOfLineModifier(ITypeInfo * basetype) { return makeModifier(basetype, typemod_outofline); }
  185. inline ITypeInfo * makeOriginalModifier(ITypeInfo * basetype, IInterface * extra) { return makeModifier(basetype, typemod_original, extra); }
  186. inline ITypeInfo * makeAttributeModifier(ITypeInfo * basetype, IInterface * extra) { return makeModifier(basetype, typemod_attr, extra); }
  187. extern DEFTYPE_API MemoryBuffer & appendBufferFromMem(MemoryBuffer & mem, ITypeInfo * type, const void * data);
  188. extern DEFTYPE_API void ClearTypeCache();
  189. extern DEFTYPE_API ICharsetInfo * getCharset(IAtom * charset);
  190. extern DEFTYPE_API ICollationInfo * getCollation(IAtom * collation);
  191. extern DEFTYPE_API ITranslationInfo * getDefaultTranslation(ICharsetInfo * tgt, ICharsetInfo * src);
  192. extern DEFTYPE_API ITranslationInfo * queryDefaultTranslation(ICharsetInfo * tgt, ICharsetInfo * src);
  193. extern DEFTYPE_API bool isAscii(ITypeInfo * type);
  194. //---------------------------------------------------------------------------
  195. extern DEFTYPE_API ITypeInfo * getStretchedType(unsigned newLen, ITypeInfo * type);
  196. extern DEFTYPE_API ITypeInfo * getMaxLengthType(ITypeInfo * type);
  197. extern DEFTYPE_API ITypeInfo * getNumericType(ITypeInfo * type);
  198. extern DEFTYPE_API ITypeInfo * getStringType(ITypeInfo * type);
  199. extern DEFTYPE_API ITypeInfo * getVarStringType(ITypeInfo * type);
  200. extern DEFTYPE_API ITypeInfo * getPromotedType(ITypeInfo * l_type, ITypeInfo * r_type);
  201. extern DEFTYPE_API ITypeInfo * getPromotedAddSubType(ITypeInfo * l_type, ITypeInfo * r_type);
  202. extern DEFTYPE_API ITypeInfo * getPromotedMulDivType(ITypeInfo * l_type, ITypeInfo * r_type);
  203. extern DEFTYPE_API ITypeInfo * getPromotedDivType(ITypeInfo * l_type, ITypeInfo * r_type);
  204. extern DEFTYPE_API ITypeInfo * getPromotedNumericType(ITypeInfo * l_type, ITypeInfo * r_type);
  205. extern DEFTYPE_API unsigned getClarionResultType(ITypeInfo *type);
  206. extern DEFTYPE_API ITypeInfo * getAsciiType(ITypeInfo * type);
  207. extern DEFTYPE_API ITypeInfo * getBandType(ITypeInfo * type1, ITypeInfo * type2);
  208. extern DEFTYPE_API ITypeInfo * getBorType(ITypeInfo * type1, ITypeInfo * type2);
  209. extern DEFTYPE_API bool haveCommonLocale(ITypeInfo * type1, ITypeInfo * type2);
  210. extern DEFTYPE_API IAtom * getCommonLocale(ITypeInfo * type1, ITypeInfo * type2);
  211. extern DEFTYPE_API ITypeInfo * getPromotedCompareType(ITypeInfo * left, ITypeInfo * right);
  212. extern DEFTYPE_API bool isNumericType(ITypeInfo * type);
  213. extern DEFTYPE_API bool isStringType(ITypeInfo * type);
  214. extern DEFTYPE_API bool isSimpleStringType(ITypeInfo * type);
  215. extern DEFTYPE_API bool isSimpleIntegralType(ITypeInfo * type);
  216. extern DEFTYPE_API bool isIntegralType(ITypeInfo * type);
  217. extern DEFTYPE_API bool isPatternType(ITypeInfo * type);
  218. extern DEFTYPE_API bool isUnicodeType(ITypeInfo * type);
  219. extern DEFTYPE_API bool isLittleEndian(ITypeInfo * type);
  220. extern DEFTYPE_API bool isDatasetType(ITypeInfo * type);
  221. extern DEFTYPE_API bool isSingleValuedType(ITypeInfo * type);
  222. extern DEFTYPE_API bool isStandardSizeInt(ITypeInfo * type); // Is this an int type that can be represented by a c++ int?
  223. inline bool isFixedSize(ITypeInfo * type) { return type && (type->getSize() != UNKNOWN_LENGTH); }
  224. inline bool isUnknownSize(ITypeInfo * type) { return type && (type->getSize() == UNKNOWN_LENGTH); }
  225. inline bool isAnyType(ITypeInfo * type) { return type && (type->getTypeCode() == type_any); }
  226. inline bool isDecimalType(ITypeInfo * type) { return type && (type->getTypeCode() == type_decimal); }
  227. inline bool isDictionaryType(ITypeInfo * type) { return type && (type->getTypeCode() == type_dictionary); }
  228. //If casting a value from type before to type after is the value preserved.
  229. //If the value is not preserved then it means more than one source value can match a target value.
  230. extern DEFTYPE_API bool preservesValue(ITypeInfo * after, ITypeInfo * before);
  231. extern DEFTYPE_API bool preservesOrder(ITypeInfo * after, ITypeInfo * before);
  232. // not quite the same as !preservesValue() since cast between integers of the same size are ok
  233. // if it loses information then multiple before can may to the same after
  234. extern DEFTYPE_API bool castLosesInformation(ITypeInfo * after, ITypeInfo * before);
  235. extern DEFTYPE_API ICharsetInfo * deserializeCharsetInfo(MemoryBuffer &src);
  236. extern DEFTYPE_API ICollationInfo * deserializeCollationInfo(MemoryBuffer &src);
  237. extern DEFTYPE_API ITypeInfo * deserializeType(MemoryBuffer &src);
  238. extern DEFTYPE_API void serializeType(MemoryBuffer &src, ITypeInfo * type);
  239. extern DEFTYPE_API bool getNormalizedLocaleName(unsigned len, char const * str, StringBuffer & buff);
  240. extern DEFTYPE_API bool isSameBasicType(ITypeInfo * left, ITypeInfo * right);
  241. extern DEFTYPE_API ITypeInfo * queryRecordType(ITypeInfo * t);
  242. extern DEFTYPE_API ITypeInfo * queryRowType(ITypeInfo * t);
  243. extern DEFTYPE_API ITypeInfo * queryUnqualifiedType(ITypeInfo * t);
  244. extern DEFTYPE_API ITypeInfo * getFullyUnqualifiedType(ITypeInfo * t);
  245. extern DEFTYPE_API ITypeInfo * removeModifier(ITypeInfo * t, typemod_t modifier); // don't link inputs
  246. extern DEFTYPE_API ITypeInfo * cloneModifier(ITypeInfo * donorType, ITypeInfo * srcType); // don't link inputs
  247. extern DEFTYPE_API ITypeInfo * cloneModifiers(ITypeInfo * donorType, ITypeInfo * srcType); // don't link inputs
  248. extern DEFTYPE_API bool hasModifier(ITypeInfo * t, typemod_t modifier);
  249. extern DEFTYPE_API ITypeInfo * queryModifier(ITypeInfo * t, typemod_t modifier);
  250. extern DEFTYPE_API ITypeInfo * replaceChildType(ITypeInfo * type, ITypeInfo * newChild);
  251. extern DEFTYPE_API ITypeInfo * getRoundType(ITypeInfo * type);
  252. extern DEFTYPE_API ITypeInfo * getRoundToType(ITypeInfo * type);
  253. extern DEFTYPE_API ITypeInfo * getTruncType(ITypeInfo * type);
  254. inline bool hasConstModifier(ITypeInfo * t) { return hasModifier(t, typemod_const); }
  255. inline bool hasReferenceModifier(ITypeInfo * t) { return hasModifier(t, typemod_ref); }
  256. inline bool hasWrapperModifier(ITypeInfo * t) { return hasModifier(t, typemod_wrapper); }
  257. inline bool hasNonconstModifier(ITypeInfo * t) { return hasModifier(t, typemod_nonconst); }
  258. inline bool hasOutOfLineModifier(ITypeInfo * t) { return hasModifier(t, typemod_outofline); }
  259. inline bool sameUnqualifiedType(ITypeInfo * t1, ITypeInfo * t2) { return queryUnqualifiedType(t1) == queryUnqualifiedType(t2); }
  260. inline ITypeInfo * stripFunctionType(ITypeInfo * type)
  261. {
  262. if (type->getTypeCode() == type_function)
  263. return type->queryChildType();
  264. return type;
  265. }
  266. typedef Linked<ITypeInfo> TypeInfoAttr;
  267. typedef Owned<ITypeInfo> OwnedITypeInfo;
  268. typedef IArrayOf<ITypeInfo> TypeInfoArray;
  269. interface ISchemaBuilder
  270. {
  271. public:
  272. virtual void addField(const char * name, ITypeInfo & type, bool keyed) = 0;
  273. virtual void addSetField(const char * name, const char * itemname, ITypeInfo & type) = 0;
  274. virtual void beginIfBlock() = 0;
  275. virtual bool beginDataset(const char * name, const char * childname, bool hasMixedContent, unsigned *updateMixed) = 0;
  276. virtual void beginRecord(const char * name, bool hasMixedContent, unsigned *updateMixed) = 0;
  277. virtual void updateMixedRecord(unsigned updateToken, bool hasMixedContent) = 0;
  278. virtual void endIfBlock() = 0;
  279. virtual void endDataset(const char * name, const char * childname) = 0;
  280. virtual void endRecord(const char * name) = 0;
  281. virtual bool addSingleFieldDataset(const char * name, const char * childname, ITypeInfo & type) = 0; // return true if supported
  282. };
  283. class DEFTYPE_API XmlSchemaBuilder : public ISchemaBuilder
  284. {
  285. public:
  286. XmlSchemaBuilder(bool _addHeader) { optionalNesting = 0; addHeader = _addHeader; }
  287. virtual void addField(const char * name, ITypeInfo & type, bool keyed);
  288. virtual void addSetField(const char * name, const char * itemname, ITypeInfo & type);
  289. virtual void beginIfBlock() { optionalNesting++; }
  290. virtual bool beginDataset(const char * name, const char * childname, bool hasMixedContent, unsigned *updateMixed);
  291. virtual void beginRecord(const char * name, bool hasMixedContent, unsigned *updateMixed);
  292. virtual void updateMixedRecord(unsigned updateToken, bool hasMixedContent);
  293. virtual void endIfBlock() { optionalNesting--; }
  294. virtual void endDataset(const char * name, const char * childname);
  295. virtual void endRecord(const char * name);
  296. virtual bool addSingleFieldDataset(const char * name, const char * childname, ITypeInfo & type);
  297. void getXml(StringBuffer & results);
  298. void getXml(IStringVal & results);
  299. private:
  300. void addSchemaPrefix(bool hasMixedContent=false);
  301. void addSchemaSuffix();
  302. void clear();
  303. void getXmlTypeName(StringBuffer & xmlType, ITypeInfo & type);
  304. void appendField(StringBuffer &xml, const char * name, ITypeInfo & type, bool keyed);
  305. protected:
  306. StringBuffer xml;
  307. StringBufferArray attributes;
  308. StringBuffer typesXml;
  309. IntArray dataSizes;
  310. IntArray stringSizes;
  311. IntArray decimalSizes;
  312. UnsignedArray nesting;
  313. ICopyArray setTypes;
  314. unsigned optionalNesting;
  315. bool addHeader;
  316. };
  317. #endif