jlib.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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 JLIB_HPP
  14. #define JLIB_HPP
  15. #define EXPLICIT_INIT
  16. #ifdef _MSC_VER
  17. //disable these throughout the system because they occur a lot
  18. #pragma warning(disable : 4275 ) // should get link errors if something is wrong...
  19. #pragma warning(disable : 4251 ) // should get link errors if something is wrong...
  20. #pragma warning(disable : 4786 ) // identifier was truncated to '255' characters in the debug information
  21. #pragma warning(disable : 4355 ) // 'this' : used in base member initializer list
  22. #endif
  23. #include "modinit.h"
  24. #include "jiface.hpp"
  25. #include <assert.h>
  26. #include "jarray.hpp"
  27. #define _elements_in(a) (sizeof(a)/sizeof((a)[0]))
  28. #define _memclr(s, n) memset(s, 0, n)
  29. #define _clear(a) memset(&a, 0, sizeof(a))
  30. #define _copy(dest, src) memcpy(&dest, &src, sizeof(src))
  31. class jlib_decl ICopyArray : public CopyReferenceArrayOf<IInterface> {};
  32. class jlib_decl IArray : public OwnedReferenceArrayOf<IInterface> {};
  33. class jlib_decl IPointerArray : public OwnedPointerArrayOf<IInterface> {};
  34. class jlib_decl IConstPointerArray : public OwnedConstPointerArrayOf<IInterface> {};
  35. class jlib_decl CICopyArray : public CopyReferenceArrayOf<CInterface> {};
  36. class jlib_decl CIArray : public OwnedReferenceArrayOf<CInterface> {};
  37. class jlib_decl CharArray : public ArrayOf<char> { };
  38. class jlib_decl IntArray : public ArrayOf<int> { };
  39. class jlib_decl ShortArray : public ArrayOf<short> { };
  40. class jlib_decl FloatArray : public ArrayOf<float> { };
  41. class jlib_decl DoubleArray : public ArrayOf<double> { };
  42. class jlib_decl UnsignedArray : public ArrayOf<unsigned> { };
  43. class jlib_decl UnsignedShortArray : public ArrayOf<unsigned short> { };
  44. class jlib_decl PointerArray : public ArrayOf<void *> { };
  45. class jlib_decl ConstPointerArray : public ArrayOf<const void *> { };
  46. #ifdef _WIN32
  47. class jlib_decl BoolArray : public ArrayOf<bool> { };
  48. #else
  49. typedef CharArray BoolArray;
  50. #endif
  51. class jlib_decl Int64Array : public ArrayOf<__int64> { };
  52. class jlib_decl UInt64Array : public ArrayOf<unsigned __int64> { };
  53. template <class A, class C, class IITER>
  54. class ArrayIIteratorOf : implements IITER, public CInterface
  55. {
  56. protected:
  57. ArrayIteratorOf <A, C &> iterator;
  58. public:
  59. IMPLEMENT_IINTERFACE;
  60. ArrayIIteratorOf(A &array) : iterator(array) { }
  61. virtual bool first() { return iterator.first(); }
  62. virtual bool next() { return iterator.next(); }
  63. virtual bool isValid() { return iterator.isValid(); }
  64. virtual C & query() { return iterator.query(); }
  65. };
  66. template <class TYPE>
  67. class CIArrayOf : public CIArray
  68. {
  69. public:
  70. inline TYPE & item(aindex_t pos) const { return (TYPE &)CIArray::item(pos); }
  71. inline TYPE & popGet() { return (TYPE &)CIArray::popGet(); }
  72. inline TYPE & tos(void) const { return (TYPE &)CIArray::tos(); }
  73. inline TYPE & tos(aindex_t num) const { return (TYPE &)CIArray::tos(num); }
  74. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)CIArray::getArray(pos); }
  75. inline TYPE **detach() { return (TYPE **)CIArray::detach(); }
  76. inline void append(TYPE& obj) { assert(&obj); CIArray::append(obj); }
  77. inline void appendUniq(TYPE& obj) { assert(&obj); CIArray::appendUniq(obj); }
  78. inline void add(TYPE& obj, aindex_t pos) { assert(&obj); CIArray::add(obj, pos); }
  79. inline NoBool<aindex_t> find(TYPE & obj) const { assert(&obj); return CIArray::find(obj); }
  80. inline void replace(TYPE &obj, aindex_t pos, bool nodel=false) { assert(&obj); CIArray::replace(obj, pos, nodel); }
  81. inline bool zap(TYPE & obj, bool nodel=false) { assert(&obj); return CIArray::zap(obj, nodel); }
  82. };
  83. template <class TYPE>
  84. class CICopyArrayOf : public CICopyArray
  85. {
  86. public:
  87. inline TYPE & item(aindex_t pos) const { return (TYPE &)CICopyArray::item(pos); }
  88. inline TYPE & popGet() { return (TYPE &)CICopyArray::popGet(); }
  89. inline TYPE & tos(void) const { return (TYPE &)CICopyArray::tos(); }
  90. inline TYPE & tos(aindex_t num) const { return (TYPE &)CICopyArray::tos(num); }
  91. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)CICopyArray::getArray(pos); }
  92. inline TYPE **detach() { return (TYPE **)CICopyArray::detach(); }
  93. inline void append(TYPE& obj) { assert(&obj); CICopyArray::append(obj); }
  94. inline void appendUniq(TYPE& obj) { assert(&obj); CICopyArray::appendUniq(obj); }
  95. inline void add(TYPE& obj, aindex_t pos) { assert(&obj); CICopyArray::add(obj, pos); }
  96. inline NoBool<aindex_t> find(TYPE & obj) const { assert(&obj); return CICopyArray::find(obj); }
  97. inline void replace(TYPE &obj, aindex_t pos) { assert(&obj); CICopyArray::replace(obj, pos); }
  98. inline bool zap(TYPE & obj) { assert(&obj); return CICopyArray::zap(obj); }
  99. };
  100. template <class TYPE>
  101. class IArrayOf : public IArray
  102. {
  103. public:
  104. inline TYPE & item(aindex_t pos) const { return (TYPE &)IArray::item(pos); }
  105. inline TYPE & popGet() { return (TYPE &)IArray::popGet(); }
  106. inline TYPE & tos(void) const { return (TYPE &)IArray::tos(); }
  107. inline TYPE & tos(aindex_t num) const { return (TYPE &)IArray::tos(num); }
  108. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)IArray::getArray(pos); }
  109. inline TYPE **detach() { return (TYPE **)IArray::detach(); }
  110. inline void append(TYPE& obj) { assert(&obj); IArray::append(obj); }
  111. inline void appendUniq(TYPE& obj) { assert(&obj); IArray::appendUniq(obj); }
  112. inline void add(TYPE& obj, aindex_t pos) { assert(&obj); IArray::add(obj, pos); }
  113. inline NoBool<aindex_t> find(TYPE & obj) const { assert(&obj); return IArray::find(obj); }
  114. inline void replace(TYPE &obj, aindex_t pos, bool nodel=false) { assert(&obj); IArray::replace(obj, pos, nodel); }
  115. inline bool zap(TYPE & obj, bool nodel=false) { assert(&obj); return IArray::zap(obj, nodel); }
  116. };
  117. template <class BTYPE>
  118. class IConstArrayOf : public IArray
  119. {
  120. typedef const BTYPE TYPE;
  121. public:
  122. inline TYPE & item(aindex_t pos) const { return (TYPE &)IArray::item(pos); }
  123. inline TYPE & popGet() { return (TYPE &)IArray::popGet(); }
  124. inline TYPE & tos(void) const { return (TYPE &)IArray::tos(); }
  125. inline TYPE & tos(aindex_t num) const { return (TYPE &)IArray::tos(num); }
  126. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)IArray::getArray(pos); }
  127. inline TYPE **detach() { return (TYPE **)IArray::detach(); }
  128. inline void append(TYPE& obj) { assert(&obj); IArray::append((BTYPE &) obj); }
  129. inline void appendUniq(TYPE& obj) { assert(&obj); IArray::appendUniq((BTYPE &) obj); }
  130. inline void add(TYPE& obj, aindex_t pos) { assert(&obj); IArray::add((BTYPE &) obj, pos); }
  131. inline NoBool<aindex_t> find(TYPE & obj) const { assert(&obj); return IArray::find((BTYPE &) obj); }
  132. inline void replace(TYPE &obj, aindex_t pos, bool nodel=false) { assert(&obj); IArray::replace((BTYPE &) obj, pos, nodel); }
  133. inline bool zap(TYPE & obj, bool nodel=false) { assert(&obj); return IArray::zap((BTYPE &) obj, nodel); }
  134. };
  135. template <class TYPE, class BASE>
  136. class IBasedArrayOf : public IArray
  137. {
  138. public:
  139. inline TYPE & item(aindex_t pos) const { return (TYPE &)(BASE &)IArray::item(pos); }
  140. inline TYPE & popGet() { return (TYPE &)(BASE &)IArray::popGet(); }
  141. inline TYPE & tos(void) const { return (TYPE &)(BASE &)IArray::tos(); }
  142. inline TYPE & tos(aindex_t num) const { return (TYPE &)(BASE &)IArray::tos(num); }
  143. inline void append(TYPE& obj) { assert(&obj); IArray::append((BASE &)obj); }
  144. inline void appendUniq(TYPE& obj) { assert(&obj); IArray::appendUniq((BASE &)obj); }
  145. inline void add(TYPE& obj, aindex_t pos) { assert(&obj); IArray::add((BASE &)obj, pos); }
  146. inline NoBool<aindex_t> find(TYPE & obj) const { assert(&obj); return IArray::find((BASE&)obj); }
  147. inline void replace(TYPE &obj, aindex_t pos, bool nodel=false) { assert(&obj); IArray::replace((BASE &)obj, pos, nodel); }
  148. inline bool zap(TYPE & obj, bool nodel=false) { assert(&obj); return IArray::zap((BASE &)obj, nodel); }
  149. };
  150. template <class TYPE>
  151. class ICopyArrayOf : public ICopyArray
  152. {
  153. public:
  154. inline TYPE & item(aindex_t pos) const { return (TYPE &)ICopyArray::item(pos); }
  155. inline TYPE & popGet() { return (TYPE &)ICopyArray::popGet(); }
  156. inline TYPE & tos(void) const { return (TYPE &)ICopyArray::tos(); }
  157. inline TYPE & tos(aindex_t num) const { return (TYPE &)ICopyArray::tos(num); }
  158. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)ICopyArray::getArray(pos); }
  159. inline TYPE **detach() { return (TYPE **)ICopyArray::detach(); }
  160. inline void append(TYPE& obj) { assert(&obj); ICopyArray::append(obj); }
  161. inline void appendUniq(TYPE& obj) { assert(&obj); ICopyArray::appendUniq(obj); }
  162. inline void add(TYPE& obj, aindex_t pos) { assert(&obj); ICopyArray::add(obj, pos); }
  163. inline NoBool<aindex_t> find(TYPE & obj) const { assert(&obj); return ICopyArray::find(obj); }
  164. inline void replace(TYPE &obj, aindex_t pos) { assert(&obj); ICopyArray::replace(obj, pos); }
  165. inline bool zap(TYPE & obj) { assert(&obj); return ICopyArray::zap(obj); }
  166. };
  167. template <class TYPE>
  168. class IPointerArrayOf : public IPointerArray
  169. {
  170. public:
  171. inline TYPE * item(aindex_t pos) const { return (TYPE *)IPointerArray::item(pos); }
  172. inline TYPE * popGet() { return (TYPE *)IPointerArray::popGet(); }
  173. inline TYPE * tos(void) const { return (TYPE *)IPointerArray::tos(); }
  174. inline TYPE * tos(aindex_t num) const { return (TYPE *)IPointerArray::tos(num); }
  175. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)IPointerArray::getArray(pos); }
  176. inline TYPE **detach() { return (TYPE **)IPointerArray::detach(); }
  177. inline void append(TYPE * obj) { IPointerArray::append(obj); }
  178. inline void appendUniq(TYPE * obj) { IPointerArray::appendUniq(obj); }
  179. inline void add(TYPE * obj, aindex_t pos) { IPointerArray::add(obj, pos); }
  180. inline NoBool<aindex_t> find(TYPE * obj) const { return IPointerArray::find(obj); }
  181. inline void replace(TYPE * obj, aindex_t pos, bool nodel=false) { IPointerArray::replace(obj, pos, nodel); }
  182. inline bool zap(TYPE * obj, bool nodel=false) { return IPointerArray::zap(obj, nodel); }
  183. };
  184. template <class BTYPE>
  185. class IConstPointerArrayOf : public IConstPointerArray
  186. {
  187. typedef const BTYPE TYPE;
  188. public:
  189. inline TYPE * item(aindex_t pos) const { return (TYPE *)IConstPointerArray::item(pos); }
  190. inline TYPE * popGet() { return (TYPE *)IConstPointerArray::popGet(); }
  191. inline TYPE * tos(void) const { return (TYPE *)IConstPointerArray::tos(); }
  192. inline TYPE * tos(aindex_t num) const { return (TYPE *)IConstPointerArray::tos(num); }
  193. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)IConstPointerArray::getArray(pos); }
  194. inline TYPE **detach() { return (TYPE **)IConstPointerArray::detach(); }
  195. inline void append(TYPE * obj) { IConstPointerArray::append(obj); }
  196. inline void appendUniq(TYPE * obj) { IConstPointerArray::appendUniq(obj); }
  197. inline void add(TYPE * obj, aindex_t pos) { IConstPointerArray::add(obj, pos); }
  198. inline NoBool<aindex_t> find(TYPE * obj) const { return IConstPointerArray::find(obj); }
  199. inline void replace(TYPE * obj, aindex_t pos, bool nodel=false) { IConstPointerArray::replace(obj, pos, nodel); }
  200. inline bool zap(TYPE * obj, bool nodel=false) { return IConstPointerArray::zap(obj, nodel); }
  201. };
  202. template <class TYPE>
  203. class PointerArrayOf : public PointerArray
  204. {
  205. typedef int (*PointerOfCompareFunc)(TYPE **, TYPE **);
  206. public:
  207. inline void add(TYPE * x, aindex_t pos) { PointerArray::add(x, pos); }
  208. inline void append(TYPE * x) { PointerArray::append(x); }
  209. inline aindex_t bAdd(TYPE * & newItem, PointerOfCompareFunc f, bool & isNew) { return PointerArray::bAdd(*(void * *)&newItem, (CompareFunc)f, isNew); }
  210. inline aindex_t bSearch(const TYPE * & key, PointerOfCompareFunc f) const { return PointerArray:: bSearch(*(void * const *)&key, (CompareFunc)f); }
  211. inline NoBool<aindex_t> find(TYPE * x) const { return PointerArray::find(x); }
  212. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)PointerArray::getArray(pos); }
  213. inline TYPE **detach() { return (TYPE **)PointerArray::detach(); }
  214. inline TYPE * item(aindex_t pos) const { return (TYPE *)PointerArray::item(pos); }
  215. inline TYPE * popGet() { return (TYPE *)PointerArray::popGet(); }
  216. inline void replace(TYPE * x, aindex_t pos) { PointerArray::replace(x, pos); }
  217. inline TYPE * tos(void) const { return (TYPE *)PointerArray::tos(); }
  218. inline TYPE * tos(aindex_t num) const { return (TYPE *)PointerArray::tos(num); }
  219. inline bool zap(TYPE * x) { return PointerArray::zap(x); }
  220. };
  221. template <class BTYPE>
  222. class ConstPointerArrayOf : public ConstPointerArray
  223. {
  224. typedef const BTYPE TYPE;
  225. typedef int (*PointerOfCompareFunc)(TYPE **, TYPE **);
  226. public:
  227. inline void add(TYPE * x, aindex_t pos) { ConstPointerArray::add(x, pos); }
  228. inline void append(TYPE * x) { ConstPointerArray::append(x); }
  229. inline aindex_t bAdd(TYPE * & newItem, PointerOfCompareFunc f, bool & isNew) { return ConstPointerArray::bAdd(*(const void * *)&newItem, (CompareFunc)f, isNew); }
  230. inline aindex_t bSearch(const TYPE * & key, PointerOfCompareFunc f) const { return ConstPointerArray:: bSearch(*(const void * const *)&key, (CompareFunc)f); }
  231. inline NoBool<aindex_t> find(TYPE * x) const { return ConstPointerArray::find(x); }
  232. inline TYPE **getArray(aindex_t pos = 0) { return (TYPE **)ConstPointerArray::getArray(pos); }
  233. inline TYPE **detach() { return (TYPE **)ConstPointerArray::detach(); }
  234. inline TYPE * item(aindex_t pos) const { return (TYPE *)ConstPointerArray::item(pos); }
  235. inline TYPE * popGet() { return (TYPE *)ConstPointerArray::popGet(); }
  236. inline void replace(TYPE * x, aindex_t pos) { ConstPointerArray::replace(x, pos); }
  237. inline TYPE * tos(void) const { return (TYPE *)ConstPointerArray::tos(); }
  238. inline TYPE * tos(aindex_t num) const { return (TYPE *)ConstPointerArray::tos(num); }
  239. inline bool zap(TYPE * x) { return ConstPointerArray::zap(x); }
  240. };
  241. enum DAFSConnectCfg { SSLNone = 0, SSLOnly, SSLFirst, UnsecureFirst };
  242. #include "jstring.hpp"
  243. #include "jarray.hpp"
  244. #include "jhash.hpp"
  245. #include "jstream.hpp"
  246. #include "jutil.hpp"
  247. template <class ARRAY>
  248. inline void appendArray(ARRAY & target, const ARRAY & source)
  249. {
  250. unsigned max = source.ordinality();
  251. if (max)
  252. {
  253. target.ensure(target.ordinality() + max);
  254. for (unsigned i=0; i < max; ++i)
  255. target.append(OLINK(source.item(i)));
  256. }
  257. }
  258. inline void appendArray(IArray & target, const IArray & source)
  259. {
  260. unsigned max = source.ordinality();
  261. if (max)
  262. {
  263. target.ensure(target.ordinality() + max);
  264. for (unsigned i=0; i < max; ++i)
  265. target.append(OLINK(source.item(i)));
  266. }
  267. }
  268. typedef bool (*boolFunc)(void);
  269. typedef void (*voidFunc)(void);
  270. typedef HINSTANCE SoContext;
  271. class ModExit;
  272. enum InitializerState { ITS_Uninitialized, ITS_Initialized };
  273. struct InitializerType
  274. {
  275. boolFunc initFunc;
  276. ModExit *modExit;
  277. unsigned int priority;
  278. unsigned int modpriority;
  279. SoContext soCtx;
  280. byte state;
  281. bool operator == (const InitializerType & other) const { return this == &other; }
  282. };
  283. class jlib_decl InitializerArray : public StructArrayOf<InitializerType> { };
  284. class jlib_decl InitTable
  285. {
  286. public:
  287. InitializerArray initializers;
  288. static int sortFuncDescending(InitializerType const *i1, InitializerType const *i2);
  289. static int sortFuncAscending(InitializerType const *i1, InitializerType const *i2);
  290. public:
  291. InitTable();
  292. void init(SoContext soCtx=0);
  293. void exit(SoContext soCtx=0);
  294. void add(InitializerType &iT);
  295. void add(boolFunc func, unsigned int priority, unsigned int modpriority, byte state=ITS_Uninitialized);
  296. count_t items() { return initializers.ordinality(); }
  297. InitializerType & element(aindex_t i) { return initializers.element(i); }
  298. };
  299. class jlib_decl ModInit
  300. {
  301. public:
  302. ModInit(boolFunc func, unsigned int _priority, unsigned int _modprio);
  303. };
  304. class jlib_decl ModExit
  305. {
  306. public:
  307. ModExit(voidFunc func);
  308. #if !defined(EXPLICIT_INIT)
  309. ~ModExit();
  310. #endif
  311. voidFunc func;
  312. };
  313. #ifndef MODULE_PRIORITY
  314. #define MODULE_PRIORITY 1
  315. #endif
  316. #define __glue(a,b) a ## b
  317. #define glue(a,b) __glue(a,b)
  318. #define MODULE_INIT(PRIORITY) \
  319. static bool glue(_modInit,__LINE__) (); \
  320. static ModInit glue(modInit, __LINE__) (& glue(_modInit, __LINE__), PRIORITY, MODULE_PRIORITY); \
  321. static bool glue(_modInit, __LINE__) ()
  322. // Assumes related MODULE_INIT preceded the use of MODULE_EXIT
  323. #define MODULE_EXIT() \
  324. static void glue(_modExit, __LINE__)(); \
  325. static ModExit glue(modExit, __LINE__)(& glue(_modExit, __LINE__)); \
  326. static void glue(_modExit, __LINE__)()
  327. extern jlib_decl void _InitModuleObjects();
  328. extern jlib_decl void ExitModuleObjects();
  329. extern jlib_decl void ExitModuleObjects(SoContext soCtx);
  330. #define InitModuleObjects() { _InitModuleObjects(); atexit(&ExitModuleObjects); }
  331. struct DynamicScopeCtx
  332. {
  333. DynamicScopeCtx();
  334. ~DynamicScopeCtx();
  335. void processInitialization(SoContext soCtx);
  336. InitTable initTable;
  337. };
  338. typedef CIArrayOf<StringAttrItem> StringAttrArray;
  339. typedef CIArrayOf<StringBufferItem> StringBufferArray;
  340. //These could be template definitions, but that would potentially affect too many classes.
  341. #define BITMASK_ENUM(X) \
  342. inline constexpr X operator | (X l, X r) { return (X)((unsigned)l | (unsigned)r); } \
  343. inline constexpr X operator ~ (X l) { return (X)(~(unsigned)l); } \
  344. inline X & operator |= (X & l, X r) { l = l | r; return l; } \
  345. inline X & operator &= (X & l, X r) { l = (X)(l & r); return l; }
  346. #endif