/activemq-cpp-library-3.4.1/src/main/decaf/lang/Long.cpp

# · C++ · 486 lines · 335 code · 95 blank · 56 comment · 82 complexity · ce1376af600a3a0e7f58c49c640decf5 MD5 · raw file

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "Long.h"
  18. #include <decaf/lang/Character.h>
  19. #include <sstream>
  20. using namespace decaf;
  21. using namespace decaf::lang;
  22. ////////////////////////////////////////////////////////////////////////////////
  23. Long::Long( long long value ) : value(value) {
  24. }
  25. ////////////////////////////////////////////////////////////////////////////////
  26. Long::Long( const std::string& value ) : value(0) {
  27. this->value = parseLong( value );
  28. }
  29. ////////////////////////////////////////////////////////////////////////////////
  30. int Long::compareTo( const Long& l ) const {
  31. return this->value < l.value ? -1 : this->value == l.value ? 0 : 1;
  32. }
  33. ////////////////////////////////////////////////////////////////////////////////
  34. int Long::compareTo( const long long& l ) const {
  35. return this->value < l ? -1 : this->value == l ? 0 : 1;
  36. }
  37. ////////////////////////////////////////////////////////////////////////////////
  38. int Long::bitCount( long long value ) {
  39. if( value == 0 ) {
  40. return 0;
  41. }
  42. unsigned long long uvalue = (unsigned long long)value;
  43. uvalue = (uvalue & 0x5555555555555555LL) + ((uvalue >> 1) & 0x5555555555555555LL);
  44. uvalue = (uvalue & 0x3333333333333333LL) + ((uvalue >> 2) & 0x3333333333333333LL);
  45. // adjust for 64-bit integer
  46. unsigned int i = (unsigned int)( (uvalue >> 32) + uvalue );
  47. i = (i & 0x0F0F0F0F) + ((i >> 4) & 0x0F0F0F0F);
  48. i = (i & 0x00FF00FF) + ((i >> 8) & 0x00FF00FF);
  49. i = (i & 0x0000FFFF) + ((i >> 16) & 0x0000FFFF);
  50. return i;
  51. }
  52. ////////////////////////////////////////////////////////////////////////////////
  53. Long Long::decode( const std::string& value ) {
  54. int length = (int)value.length(), i = 0;
  55. if( length == 0 ) {
  56. throw exceptions::NumberFormatException(
  57. __FILE__, __LINE__,
  58. "Long::decode - Zero length string given." );
  59. }
  60. char firstDigit = value[i];
  61. bool negative = firstDigit == '-';
  62. if( negative ) {
  63. if( length == 1 ) {
  64. throw exceptions::NumberFormatException(
  65. __FILE__, __LINE__,
  66. "Long::decode - Invalid length string given.",
  67. value.c_str() );
  68. }
  69. firstDigit = value[++i];
  70. }
  71. int base = 10;
  72. if( firstDigit == '0' ) {
  73. if( ++i == length ) {
  74. return valueOf( 0LL );
  75. }
  76. if( ( firstDigit = value[i] ) == 'x' || firstDigit == 'X' ) {
  77. if ( i == length ) {
  78. throw exceptions::NumberFormatException(
  79. __FILE__, __LINE__,
  80. "Long::decode - Invalid length string given.",
  81. value.c_str() );
  82. }
  83. i++;
  84. base = 16;
  85. } else {
  86. base = 8;
  87. }
  88. } else if( firstDigit == '#' ) {
  89. if( i == length ) {
  90. throw exceptions::NumberFormatException(
  91. __FILE__, __LINE__,
  92. "Long::decode - Invalid length string given.",
  93. value.c_str() );
  94. }
  95. i++;
  96. base = 16;
  97. }
  98. long long result = parse( value, i, base, negative );
  99. return valueOf( result );
  100. }
  101. ////////////////////////////////////////////////////////////////////////////////
  102. long long Long::highestOneBit( long long value ) {
  103. if( value == 0 ) {
  104. return 0;
  105. }
  106. unsigned long long uvalue = (unsigned long long)value;
  107. uvalue |= (uvalue >> 1);
  108. uvalue |= (uvalue >> 2);
  109. uvalue |= (uvalue >> 4);
  110. uvalue |= (uvalue >> 8);
  111. uvalue |= (uvalue >> 16);
  112. uvalue |= (uvalue >> 32);
  113. return ( uvalue & ~( uvalue >> 1 ) );
  114. }
  115. ////////////////////////////////////////////////////////////////////////////////
  116. long long Long::lowestOneBit( long long value ) {
  117. if( value == 0 ) {
  118. return 0;
  119. }
  120. unsigned long long uvalue = (unsigned long long)value;
  121. return ( uvalue & (-1 * uvalue) );
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////
  124. int Long::numberOfLeadingZeros( long long value ) {
  125. if( value == 0 ) {
  126. return 0;
  127. }
  128. unsigned long long uvalue = (unsigned long long)value;
  129. value |= value >> 1;
  130. value |= value >> 2;
  131. value |= value >> 4;
  132. value |= value >> 8;
  133. value |= value >> 16;
  134. value |= value >> 32;
  135. return Long::bitCount( ~uvalue );
  136. }
  137. ////////////////////////////////////////////////////////////////////////////////
  138. int Long::numberOfTrailingZeros( long long value ) {
  139. if( value == 0 ) {
  140. return 0;
  141. }
  142. unsigned long long uvalue = (unsigned long long)value;
  143. return Long::bitCount( (uvalue & (-1 * uvalue)) - 1 );
  144. }
  145. ////////////////////////////////////////////////////////////////////////////////
  146. long long Long::parseLong( const std::string& value ) {
  147. return Long::parseLong( value, 10 );
  148. }
  149. ////////////////////////////////////////////////////////////////////////////////
  150. long long Long::parseLong( const std::string& value, int radix ) {
  151. if( radix < Character::MIN_RADIX ||
  152. radix > Character::MAX_RADIX ) {
  153. throw exceptions::NumberFormatException(
  154. __FILE__, __LINE__,
  155. "Long::parseLong - Given Radix is out of range." );
  156. }
  157. int length = (int)value.length();
  158. int i = 0;
  159. if( length == 0 ) {
  160. throw exceptions::NumberFormatException(
  161. __FILE__, __LINE__,
  162. "Long::parseLong - Zero length string is illegal." );
  163. }
  164. bool negative = value[i] == '-';
  165. if( negative && ++i == length ) {
  166. throw exceptions::NumberFormatException(
  167. __FILE__, __LINE__,
  168. "Long::parseLong - Only a minus given, string is invalid." );
  169. }
  170. return Long::parse( value, i, radix, negative );
  171. }
  172. ////////////////////////////////////////////////////////////////////////////////
  173. long long Long::parse( const std::string& value, int offset,
  174. int radix, bool negative ) {
  175. long long max = Long::MIN_VALUE / radix;
  176. long long result = 0;
  177. long long length = value.length();
  178. while( offset < length ) {
  179. int digit = Character::digit( value[offset++], radix );
  180. if( digit == -1 ) {
  181. throw exceptions::NumberFormatException(
  182. __FILE__, __LINE__,
  183. "Long::parseLong - String contains no digit characters." );
  184. }
  185. if( max > result ) {
  186. throw exceptions::NumberFormatException(
  187. __FILE__, __LINE__,
  188. "Long::parseLong - Parsed value greater than max for radix." );
  189. }
  190. long long next = result * radix - digit;
  191. if( next > result ) {
  192. throw exceptions::NumberFormatException(
  193. __FILE__, __LINE__,
  194. "Long::parseLong - Only a minus given, string is invalid." );
  195. }
  196. result = next;
  197. }
  198. if( !negative ) {
  199. result = -result;
  200. if( result < 0 ) {
  201. throw exceptions::NumberFormatException(
  202. __FILE__, __LINE__,
  203. "Long::parseLong - Value less than zero, but no minus sign." );
  204. }
  205. }
  206. return result;
  207. }
  208. ////////////////////////////////////////////////////////////////////////////////
  209. long long Long::reverseBytes( long long value ) {
  210. if( value == 0 ) {
  211. return 0;
  212. }
  213. unsigned long long uvalue = (unsigned long long)value;
  214. long long b7 = (uvalue >> 56);
  215. long long b6 = (uvalue >> 40) & 0xFF00ULL;
  216. long long b5 = (uvalue >> 24) & 0xFF0000ULL;
  217. long long b4 = (uvalue >> 8) & 0xFF000000ULL;
  218. long long b3 = (uvalue & 0xFF000000ULL) << 8;
  219. long long b2 = (uvalue & 0xFF0000ULL) << 24;
  220. long long b1 = (uvalue & 0xFF00ULL) << 40;
  221. long long b0 = (uvalue << 56);
  222. return ( b0 | b1 | b2 | b3 | b4 | b5 | b6 | b7 );
  223. }
  224. ////////////////////////////////////////////////////////////////////////////////
  225. long long Long::reverse( long long value ) {
  226. if( value == 0 ) {
  227. return 0;
  228. }
  229. unsigned long long uvalue = (unsigned long long)value;
  230. // From Hacker's Delight, 7-1, Figure 7-1
  231. uvalue = ( ( uvalue & 0x5555555555555555ULL ) << 1 ) | ( (uvalue >> 1) &
  232. 0x5555555555555555ULL );
  233. uvalue = ( ( uvalue & 0x3333333333333333ULL ) << 2 ) | ( (uvalue >> 2) &
  234. 0x3333333333333333ULL );
  235. uvalue = ( ( uvalue & 0x0F0F0F0F0F0F0F0FULL ) << 4 ) | ( (uvalue >> 4) &
  236. 0x0F0F0F0F0F0F0F0FULL );
  237. return reverseBytes( uvalue );
  238. }
  239. ////////////////////////////////////////////////////////////////////////////////
  240. long long Long::rotateLeft( long long value, int distance ) {
  241. unsigned long long i = (unsigned long long)value;
  242. int j = distance & 0x1F;
  243. return ( i << j ) | ( i >> (-j & 0x1F ) );
  244. }
  245. ////////////////////////////////////////////////////////////////////////////////
  246. long long Long::rotateRight( long long value, int distance ) {
  247. unsigned long long i = (unsigned long long)value;
  248. int j = distance & 0x1F;
  249. return ( i >> j ) | ( i << (-j & 0x1F ) );
  250. }
  251. ////////////////////////////////////////////////////////////////////////////////
  252. int Long::signum( long long value ) {
  253. return ( value == 0 ? 0 : ( value < 0 ? -1 : 1 ) );
  254. }
  255. ////////////////////////////////////////////////////////////////////////////////
  256. std::string Long::toString() const {
  257. return Long::toString( this->value, 10 );
  258. }
  259. ////////////////////////////////////////////////////////////////////////////////
  260. std::string Long::toString( long long value ) {
  261. return Long::toString( value, 10 );
  262. }
  263. ////////////////////////////////////////////////////////////////////////////////
  264. std::string Long::toString( long long value, int radix ) {
  265. if( radix < Character::MIN_RADIX || radix > Character::MAX_RADIX ) {
  266. radix = 10;
  267. }
  268. if( value == 0 ) {
  269. return "0";
  270. }
  271. int count = 2;
  272. long long j = value;
  273. bool negative = value < 0;
  274. if( !negative ) {
  275. count = 1;
  276. j = -value;
  277. }
  278. while( (value /= radix) != 0 ) {
  279. count++;
  280. }
  281. // Save length and allocate a new buffer for the string, add one
  282. // more for the null character.
  283. int length = count;
  284. char* buffer = new char[length + 1];
  285. do {
  286. int ch = (int)( 0 - ( j % radix ) );
  287. if( ch > 9 ) {
  288. ch = ch - 10 + 'a';
  289. } else {
  290. ch += '0';
  291. }
  292. buffer[--count] = (char)ch;
  293. } while( (j /= radix) != 0 );
  294. if( negative ) {
  295. buffer[0] = '-';
  296. }
  297. // Ensure there's a null
  298. buffer[length] = 0;
  299. std::string result( &buffer[0] );
  300. delete [] buffer;
  301. return result;
  302. }
  303. ////////////////////////////////////////////////////////////////////////////////
  304. std::string Long::toBinaryString( long long value ) {
  305. int count = 1;
  306. long long j = value;
  307. if( value < 0 ) {
  308. count = 32;
  309. } else {
  310. while ( (j >>= 1) != 0) {
  311. count++;
  312. }
  313. }
  314. // Save length and allocate a new buffer for the string, add one
  315. // more for the null character.
  316. int length = count;
  317. char* buffer = new char[length + 1];
  318. do {
  319. buffer[--count] = (char)( (value & 1) + '0' );
  320. value >>= 1;
  321. } while( count > 0 );
  322. // Ensure there's a null
  323. buffer[length] = 0;
  324. std::string result( &buffer[0] );
  325. delete [] buffer;
  326. return result;
  327. }
  328. ////////////////////////////////////////////////////////////////////////////////
  329. std::string Long::toOctalString( long long value ) {
  330. int count = 1;
  331. long long j = value;
  332. if( value < 0 ) {
  333. count = 11;
  334. } else {
  335. while ( (j >>= 3) != 0 ) {
  336. count++;
  337. }
  338. }
  339. // Save length and allocate a new buffer for the string, add one
  340. // more for the null character.
  341. int length = count;
  342. char* buffer = new char[length + 1];
  343. do {
  344. buffer[--count] = (char)( (value & 7) + '0' );
  345. value >>= 3;
  346. } while( count > 0 );
  347. // Ensure there's a null
  348. buffer[length] = 0;
  349. std::string result( &buffer[0] );
  350. delete [] buffer;
  351. return result;
  352. }
  353. ////////////////////////////////////////////////////////////////////////////////
  354. std::string Long::toHexString( long long value ) {
  355. int count = 1;
  356. long long j = value;
  357. if( value < 0 ) {
  358. count = 8;
  359. } else {
  360. while( (j >>= 4) != 0 ) {
  361. count++;
  362. }
  363. }
  364. // Save length and allocate a new buffer for the string, add one
  365. // more for the null character.
  366. int length = count;
  367. char* buffer = new char[length + 1];
  368. do {
  369. int t = (int)( value & 15 );
  370. if( t > 9 ) {
  371. t = t - 10 + 'a';
  372. } else {
  373. t += '0';
  374. }
  375. buffer[--count] = (char)t;
  376. value >>= 4;
  377. } while( count > 0 );
  378. // Ensure there's a null
  379. buffer[length] = 0;
  380. std::string result( &buffer[0] );
  381. delete [] buffer;
  382. return result;
  383. }
  384. ////////////////////////////////////////////////////////////////////////////////
  385. Long Long::valueOf( const std::string& value ) {
  386. return Long( Long::parseLong( value ) );
  387. }
  388. ////////////////////////////////////////////////////////////////////////////////
  389. Long Long::valueOf( const std::string& value, int radix ) {
  390. return Long( Long::parseLong( value, radix ) );
  391. }