rtlbcd.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  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 "rtlbcd.hpp"
  16. #include "nbcd.hpp"
  17. #include "jmutex.hpp"
  18. #include "jexcept.hpp"
  19. #ifdef __APPLE__
  20. //Apple does not currently support thread_local (very strange), so need to use __thread.
  21. static __thread Decimal stack[32];
  22. static __thread unsigned curStack = 0;
  23. #else
  24. //gcc needs to use thread_local because it doesn't support __thread on arrays of constexpr objects
  25. static thread_local Decimal stack[32];
  26. static thread_local unsigned curStack = 0;
  27. #endif
  28. //---------------------------------------------------------------------------------------------------------------------
  29. //These functions are retained to that old work units will load, and then report a version mismatch, rather than a
  30. //confusing unresolved symbol error.
  31. void DecLock()
  32. {
  33. throwUnexpected();
  34. }
  35. void DecUnlock()
  36. {
  37. throwUnexpected();
  38. }
  39. unsigned DecMarkStack()
  40. {
  41. return curStack;
  42. }
  43. void DecReleaseStack(unsigned mark)
  44. {
  45. curStack = mark;
  46. }
  47. //---------------------------------------------------------------------------------------------------------------------
  48. static void setDivideByZero(Decimal & tos, DBZaction dbz)
  49. {
  50. switch (dbz)
  51. {
  52. case DBZfail:
  53. rtlFailDivideByZero();
  54. break;
  55. case DBZnan:
  56. case DBZzero:
  57. tos.setZero();
  58. break;
  59. default:
  60. throwUnexpected();
  61. }
  62. }
  63. void DecAbs()
  64. {
  65. stack[curStack-1].abs();
  66. }
  67. void DecAdd()
  68. {
  69. curStack--;
  70. stack[curStack-1].add(stack[curStack]);
  71. }
  72. int DecCompareNull()
  73. {
  74. curStack--;
  75. return stack[curStack].compareNull();
  76. }
  77. int DecDistinct()
  78. {
  79. curStack -= 2;
  80. return stack[curStack].compare(stack[curStack+1]);
  81. }
  82. int DecDistinctR()
  83. {
  84. curStack -= 2;
  85. return stack[curStack+1].compare(stack[curStack]);
  86. }
  87. void DecDivide(byte dbz)
  88. {
  89. curStack--;
  90. if (stack[curStack].isZero())
  91. setDivideByZero(stack[curStack-1], (DBZaction)dbz);
  92. else
  93. stack[curStack-1].divide(stack[curStack]);
  94. }
  95. void DecDivideR(byte dbz)
  96. {
  97. DecSwap();
  98. DecDivide(dbz);
  99. }
  100. void DecDup()
  101. {
  102. stack[curStack].set(stack[curStack-1]);
  103. curStack++;
  104. }
  105. void DecSetPrecision(unsigned char declen, unsigned char prec)
  106. {
  107. stack[curStack-1].round(prec).setPrecision(declen, prec);
  108. }
  109. void DecSub()
  110. {
  111. curStack--;
  112. stack[curStack-1].subtract(stack[curStack]);
  113. }
  114. void DecSubR()
  115. {
  116. DecSwap();
  117. DecSub();
  118. }
  119. void DecInfo (unsigned & digits, unsigned & prec)
  120. {
  121. stack[curStack-1].getPrecision(digits, prec);
  122. }
  123. void DecClipInfo (unsigned & digits, unsigned & prec)
  124. {
  125. stack[curStack-1].getClipPrecision(digits, prec);
  126. }
  127. void DecLongPower(long pow)
  128. {
  129. stack[curStack-1].power((int)pow);
  130. }
  131. void DecUlongPower(unsigned long pow)
  132. {
  133. stack[curStack-1].power((unsigned)pow);
  134. }
  135. void DecModulus(byte dbz)
  136. {
  137. curStack--;
  138. if (stack[curStack].isZero())
  139. setDivideByZero(stack[curStack-1], (DBZaction)dbz);
  140. else
  141. stack[curStack-1].modulus(stack[curStack]);
  142. }
  143. void DecMul()
  144. {
  145. curStack--;
  146. stack[curStack-1].multiply(stack[curStack]);
  147. }
  148. void DecNegate()
  149. {
  150. stack[curStack-1].negate();
  151. }
  152. void DecPopCString (unsigned length, char * buffer)
  153. {
  154. stack[--curStack].getCString(length, buffer);
  155. }
  156. char * DecPopCStringX()
  157. {
  158. return stack[--curStack].getCString();
  159. }
  160. __int64 DecPopInt64()
  161. {
  162. return stack[--curStack].getInt64();
  163. }
  164. void DecPopDecimal(void * buffer,unsigned char declen,unsigned char prec)
  165. {
  166. stack[--curStack].round(prec).getDecimal(declen, prec, buffer);
  167. }
  168. void DecPopUDecimal(void * buffer,unsigned char declen,unsigned char prec)
  169. {
  170. stack[--curStack].round(prec).getUDecimal(declen, prec, buffer);
  171. }
  172. int DecPopLong()
  173. {
  174. return stack[--curStack].getInt();
  175. }
  176. unsigned long DecPopUlong()
  177. {
  178. return stack[--curStack].getUInt();
  179. }
  180. double DecPopReal()
  181. {
  182. return stack[--curStack].getReal();
  183. }
  184. unsigned DecPopString( unsigned length, char * buffer)
  185. {
  186. stack[--curStack].getString(length, buffer);
  187. return length; // significant length??
  188. }
  189. void DecPopStringX( unsigned & length, char * & buffer)
  190. {
  191. stack[--curStack].getStringX(length, buffer);
  192. }
  193. void DecPushCString(const char *s)
  194. {
  195. stack[curStack++].setCString(s);
  196. }
  197. void DecPushInt64(__int64 value)
  198. {
  199. stack[curStack++].setInt64(value);
  200. }
  201. void DecPushUInt64(unsigned __int64 value)
  202. {
  203. stack[curStack++].setUInt64(value);
  204. }
  205. void DecPushLong( long value)
  206. {
  207. stack[curStack++].setInt(value);
  208. }
  209. void DecPushDecimal(const void * buffer,unsigned char declen,unsigned char prec)
  210. {
  211. stack[curStack++].setDecimal(declen, prec, buffer);
  212. }
  213. void DecPushUDecimal(const void * buffer,unsigned char declen,unsigned char prec)
  214. {
  215. stack[curStack++].setUDecimal(declen, prec, buffer);
  216. }
  217. void DecPushReal( double value )
  218. {
  219. stack[curStack++].setReal(value);
  220. }
  221. void DecPushString(unsigned length, const char * text)
  222. {
  223. stack[curStack++].setString(length, text);
  224. }
  225. void DecPushUlong( unsigned long value)
  226. {
  227. stack[curStack++].setUInt(value);
  228. }
  229. void DecRound()
  230. {
  231. stack[curStack-1].round(0);
  232. }
  233. void DecRoundUp()
  234. {
  235. stack[curStack-1].roundup(0);
  236. }
  237. void DecRoundTo(unsigned places)
  238. {
  239. stack[curStack-1].round(places);
  240. }
  241. void DecSwap()
  242. {
  243. char temp[sizeof(Decimal)];
  244. memcpy(&temp, &stack[curStack-1], sizeof(Decimal));
  245. memcpy(&stack[curStack-1], &stack[curStack-2], sizeof(Decimal));
  246. memcpy(&stack[curStack-2], &temp, sizeof(Decimal));
  247. }
  248. void DecTruncate()
  249. {
  250. stack[curStack-1].truncate(0);
  251. }
  252. void DecTruncateAt(unsigned places)
  253. {
  254. stack[curStack-1].truncate(places);
  255. }
  256. bool DecValid(bool isSigned, unsigned digits, const void * data)
  257. {
  258. return decValid(isSigned, digits, data);
  259. }
  260. bool DecValidTos()
  261. {
  262. return stack[--curStack].isValid();
  263. }
  264. bool Dec2Bool(size32_t bytes, const void * data)
  265. {
  266. return dec2Bool(bytes, data);
  267. }
  268. bool UDec2Bool(size32_t bytes, const void * data)
  269. {
  270. return udec2Bool(bytes, data);
  271. }
  272. int DecCompareDecimal(size32_t bytes, const void * _left, const void * _right)
  273. {
  274. return decCompareDecimal(bytes, _left, _right);
  275. }
  276. int DecCompareUDecimal(size32_t bytes, const void * _left, const void * _right)
  277. {
  278. return decCompareUDecimal(bytes, _left, _right);
  279. }
  280. // internal