rtlbcd.cpp 6.4 KB

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