1 package com.fasterxml.jackson.core.io; 2 3 public final class NumberOutput 4 { 5 private static int MILLION = 1000000; 6 private static int BILLION = 1000000000; 7 private static long BILLION_L = 1000000000L; 8 9 private static long MIN_INT_AS_LONG = (long) Integer.MIN_VALUE; 10 private static long MAX_INT_AS_LONG = (long) Integer.MAX_VALUE; 11 12 final static String SMALLEST_INT = String.valueOf(Integer.MIN_VALUE); 13 final static String SMALLEST_LONG = String.valueOf(Long.MIN_VALUE); 14 15 /** 16 * Encoded representations of 3-decimal-digit indexed values, where 17 * 3 LSB are ascii characters 18 * 19 * @since 2.8.2 20 */ 21 private final static int[] TRIPLET_TO_CHARS = new int[1000]; 22 23 static { 24 /* Let's fill it with NULLs for ignorable leading digits, 25 * and digit chars for others 26 */ 27 int fullIx = 0; 28 for (int i1 = 0; i1 < 10; ++i1) { 29 for (int i2 = 0; i2 < 10; ++i2) { 30 for (int i3 = 0; i3 < 10; ++i3) { 31 int enc = ((i1 + '0') << 16) 32 | ((i2 + '0') << 8) 33 | (i3 + '0'); 34 TRIPLET_TO_CHARS[fullIx++] = enc; 35 } 36 } 37 } 38 } 39 40 private final static String[] sSmallIntStrs = new String[] { 41 "0","1","2","3","4","5","6","7","8","9","10" 42 }; 43 private final static String[] sSmallIntStrs2 = new String[] { 44 "-1","-2","-3","-4","-5","-6","-7","-8","-9","-10" 45 }; 46 47 /* 48 /********************************************************** 49 /* Efficient serialization methods using raw buffers 50 /********************************************************** 51 */ 52 53 /** 54 * @return Offset within buffer after outputting int 55 */ outputInt(int v, char[] b, int off)56 public static int outputInt(int v, char[] b, int off) 57 { 58 if (v < 0) { 59 if (v == Integer.MIN_VALUE) { 60 // Special case: no matching positive value within range; 61 // let's then "upgrade" to long and output as such. 62 return _outputSmallestI(b, off); 63 } 64 b[off++] = '-'; 65 v = -v; 66 } 67 68 if (v < MILLION) { // at most 2 triplets... 69 if (v < 1000) { 70 if (v < 10) { 71 b[off] = (char) ('0' + v); 72 return off+1; 73 } 74 return _leading3(v, b, off); 75 } 76 int thousands = v / 1000; 77 v -= (thousands * 1000); // == value % 1000 78 off = _leading3(thousands, b, off); 79 off = _full3(v, b, off); 80 return off; 81 } 82 83 // ok, all 3 triplets included 84 /* Let's first hand possible billions separately before 85 * handling 3 triplets. This is possible since we know we 86 * can have at most '2' as billion count. 87 */ 88 if (v >= BILLION) { 89 v -= BILLION; 90 if (v >= BILLION) { 91 v -= BILLION; 92 b[off++] = '2'; 93 } else { 94 b[off++] = '1'; 95 } 96 return _outputFullBillion(v, b, off); 97 } 98 int newValue = v / 1000; 99 int ones = (v - (newValue * 1000)); // == value % 1000 100 v = newValue; 101 newValue /= 1000; 102 int thousands = (v - (newValue * 1000)); 103 104 off = _leading3(newValue, b, off); 105 off = _full3(thousands, b, off); 106 return _full3(ones, b, off); 107 } 108 outputInt(int v, byte[] b, int off)109 public static int outputInt(int v, byte[] b, int off) 110 { 111 if (v < 0) { 112 if (v == Integer.MIN_VALUE) { 113 return _outputSmallestI(b, off); 114 } 115 b[off++] = '-'; 116 v = -v; 117 } 118 119 if (v < MILLION) { // at most 2 triplets... 120 if (v < 1000) { 121 if (v < 10) { 122 b[off++] = (byte) ('0' + v); 123 } else { 124 off = _leading3(v, b, off); 125 } 126 } else { 127 int thousands = v / 1000; 128 v -= (thousands * 1000); // == value % 1000 129 off = _leading3(thousands, b, off); 130 off = _full3(v, b, off); 131 } 132 return off; 133 } 134 if (v >= BILLION) { 135 v -= BILLION; 136 if (v >= BILLION) { 137 v -= BILLION; 138 b[off++] = '2'; 139 } else { 140 b[off++] = '1'; 141 } 142 return _outputFullBillion(v, b, off); 143 } 144 int newValue = v / 1000; 145 int ones = (v - (newValue * 1000)); // == value % 1000 146 v = newValue; 147 newValue /= 1000; 148 int thousands = (v - (newValue * 1000)); 149 off = _leading3(newValue, b, off); 150 off = _full3(thousands, b, off); 151 return _full3(ones, b, off); 152 } 153 154 /** 155 * @return Offset within buffer after outputting int 156 */ outputLong(long v, char[] b, int off)157 public static int outputLong(long v, char[] b, int off) 158 { 159 // First: does it actually fit in an int? 160 if (v < 0L) { 161 if (v > MIN_INT_AS_LONG) { 162 return outputInt((int) v, b, off); 163 } 164 if (v == Long.MIN_VALUE) { 165 return _outputSmallestL(b, off); 166 } 167 b[off++] = '-'; 168 v = -v; 169 } else { 170 if (v <= MAX_INT_AS_LONG) { 171 return outputInt((int) v, b, off); 172 } 173 } 174 175 // Ok, let's separate last 9 digits (3 x full sets of 3) 176 long upper = v / BILLION_L; 177 v -= (upper * BILLION_L); 178 179 // two integers? 180 if (upper < BILLION_L) { 181 off = _outputUptoBillion((int) upper, b, off); 182 } else { 183 // no, two ints and bits; hi may be about 16 or so 184 long hi = upper / BILLION_L; 185 upper -= (hi * BILLION_L); 186 off = _leading3((int) hi, b, off); 187 off = _outputFullBillion((int) upper, b, off); 188 } 189 return _outputFullBillion((int) v, b, off); 190 } 191 outputLong(long v, byte[] b, int off)192 public static int outputLong(long v, byte[] b, int off) 193 { 194 if (v < 0L) { 195 if (v > MIN_INT_AS_LONG) { 196 return outputInt((int) v, b, off); 197 } 198 if (v == Long.MIN_VALUE) { 199 return _outputSmallestL(b, off); 200 } 201 b[off++] = '-'; 202 v = -v; 203 } else { 204 if (v <= MAX_INT_AS_LONG) { 205 return outputInt((int) v, b, off); 206 } 207 } 208 209 // Ok, let's separate last 9 digits (3 x full sets of 3) 210 long upper = v / BILLION_L; 211 v -= (upper * BILLION_L); 212 213 // two integers? 214 if (upper < BILLION_L) { 215 off = _outputUptoBillion((int) upper, b, off); 216 } else { 217 // no, two ints and bits; hi may be about 16 or so 218 long hi = upper / BILLION_L; 219 upper -= (hi * BILLION_L); 220 off = _leading3((int) hi, b, off); 221 off = _outputFullBillion((int) upper, b, off); 222 } 223 return _outputFullBillion((int) v, b, off); 224 } 225 226 /* 227 /********************************************************** 228 /* Convenience serialization methods 229 /********************************************************** 230 */ 231 232 /* !!! 05-Aug-2008, tatus: Any ways to further optimize 233 * these? (or need: only called by diagnostics methods?) 234 */ toString(int v)235 public static String toString(int v) 236 { 237 // Lookup table for small values 238 if (v < sSmallIntStrs.length) { 239 if (v >= 0) { 240 return sSmallIntStrs[v]; 241 } 242 int v2 = -v - 1; 243 if (v2 < sSmallIntStrs2.length) { 244 return sSmallIntStrs2[v2]; 245 } 246 } 247 return Integer.toString(v); 248 } 249 toString(long v)250 public static String toString(long v) { 251 if (v <= Integer.MAX_VALUE && v >= Integer.MIN_VALUE) { 252 return toString((int) v); 253 } 254 return Long.toString(v); 255 } 256 toString(double v)257 public static String toString(double v) { 258 return Double.toString(v); 259 } 260 261 /** 262 * @since 2.6.0 263 */ toString(float v)264 public static String toString(float v) { 265 return Float.toString(v); 266 } 267 268 /* 269 /********************************************************** 270 /* Other convenience methods 271 /********************************************************** 272 */ 273 274 /** 275 * Helper method to verify whether given {@code double} value is finite 276 * (regular rational number} or not (NaN or Infinity). 277 * 278 * @return True if number is NOT finite (is Infinity or NaN); false otherwise 279 * 280 * Since 2.10 281 */ notFinite(double value)282 public static boolean notFinite(double value) { 283 // before Java 8 need separate checks 284 return Double.isNaN(value) || Double.isInfinite(value); 285 } 286 287 /** 288 * Helper method to verify whether given {@code float} value is finite 289 * (regular rational number} or not (NaN or Infinity). 290 * 291 * @return True if number is NOT finite (is Infinity or NaN); false otherwise 292 * 293 * Since 2.10 294 */ notFinite(float value)295 public static boolean notFinite(float value) { 296 // before Java 8 need separate checks 297 return Float.isNaN(value) || Float.isInfinite(value); 298 } 299 300 /* 301 /********************************************************** 302 /* Internal helper methods 303 /********************************************************** 304 */ 305 _outputUptoBillion(int v, char[] b, int off)306 private static int _outputUptoBillion(int v, char[] b, int off) 307 { 308 if (v < MILLION) { // at most 2 triplets... 309 if (v < 1000) { 310 return _leading3(v, b, off); 311 } 312 int thousands = v / 1000; 313 int ones = v - (thousands * 1000); // == value % 1000 314 return _outputUptoMillion(b, off, thousands, ones); 315 } 316 int thousands = v / 1000; 317 int ones = (v - (thousands * 1000)); // == value % 1000 318 int millions = thousands / 1000; 319 thousands -= (millions * 1000); 320 321 off = _leading3(millions, b, off); 322 323 int enc = TRIPLET_TO_CHARS[thousands]; 324 b[off++] = (char) (enc >> 16); 325 b[off++] = (char) ((enc >> 8) & 0x7F); 326 b[off++] = (char) (enc & 0x7F); 327 328 enc = TRIPLET_TO_CHARS[ones]; 329 b[off++] = (char) (enc >> 16); 330 b[off++] = (char) ((enc >> 8) & 0x7F); 331 b[off++] = (char) (enc & 0x7F); 332 333 return off; 334 } 335 _outputFullBillion(int v, char[] b, int off)336 private static int _outputFullBillion(int v, char[] b, int off) 337 { 338 int thousands = v / 1000; 339 int ones = (v - (thousands * 1000)); // == value % 1000 340 int millions = thousands / 1000; 341 342 int enc = TRIPLET_TO_CHARS[millions]; 343 b[off++] = (char) (enc >> 16); 344 b[off++] = (char) ((enc >> 8) & 0x7F); 345 b[off++] = (char) (enc & 0x7F); 346 347 thousands -= (millions * 1000); 348 enc = TRIPLET_TO_CHARS[thousands]; 349 b[off++] = (char) (enc >> 16); 350 b[off++] = (char) ((enc >> 8) & 0x7F); 351 b[off++] = (char) (enc & 0x7F); 352 353 enc = TRIPLET_TO_CHARS[ones]; 354 b[off++] = (char) (enc >> 16); 355 b[off++] = (char) ((enc >> 8) & 0x7F); 356 b[off++] = (char) (enc & 0x7F); 357 358 return off; 359 } 360 _outputUptoBillion(int v, byte[] b, int off)361 private static int _outputUptoBillion(int v, byte[] b, int off) 362 { 363 if (v < MILLION) { // at most 2 triplets... 364 if (v < 1000) { 365 return _leading3(v, b, off); 366 } 367 int thousands = v / 1000; 368 int ones = v - (thousands * 1000); // == value % 1000 369 return _outputUptoMillion(b, off, thousands, ones); 370 } 371 int thousands = v / 1000; 372 int ones = (v - (thousands * 1000)); // == value % 1000 373 int millions = thousands / 1000; 374 thousands -= (millions * 1000); 375 376 off = _leading3(millions, b, off); 377 378 int enc = TRIPLET_TO_CHARS[thousands]; 379 b[off++] = (byte) (enc >> 16); 380 b[off++] = (byte) (enc >> 8); 381 b[off++] = (byte) enc; 382 383 enc = TRIPLET_TO_CHARS[ones]; 384 b[off++] = (byte) (enc >> 16); 385 b[off++] = (byte) (enc >> 8); 386 b[off++] = (byte) enc; 387 388 return off; 389 } 390 _outputFullBillion(int v, byte[] b, int off)391 private static int _outputFullBillion(int v, byte[] b, int off) 392 { 393 int thousands = v / 1000; 394 int ones = (v - (thousands * 1000)); // == value % 1000 395 int millions = thousands / 1000; 396 thousands -= (millions * 1000); 397 398 int enc = TRIPLET_TO_CHARS[millions]; 399 b[off++] = (byte) (enc >> 16); 400 b[off++] = (byte) (enc >> 8); 401 b[off++] = (byte) enc; 402 403 enc = TRIPLET_TO_CHARS[thousands]; 404 b[off++] = (byte) (enc >> 16); 405 b[off++] = (byte) (enc >> 8); 406 b[off++] = (byte) enc; 407 408 enc = TRIPLET_TO_CHARS[ones]; 409 b[off++] = (byte) (enc >> 16); 410 b[off++] = (byte) (enc >> 8); 411 b[off++] = (byte) enc; 412 413 return off; 414 } 415 _outputUptoMillion(char[] b, int off, int thousands, int ones)416 private static int _outputUptoMillion(char[] b, int off, int thousands, int ones) 417 { 418 int enc = TRIPLET_TO_CHARS[thousands]; 419 if (thousands > 9) { 420 if (thousands > 99) { 421 b[off++] = (char) (enc >> 16); 422 } 423 b[off++] = (char) ((enc >> 8) & 0x7F); 424 } 425 b[off++] = (char) (enc & 0x7F); 426 // and then full 427 enc = TRIPLET_TO_CHARS[ones]; 428 b[off++] = (char) (enc >> 16); 429 b[off++] = (char) ((enc >> 8) & 0x7F); 430 b[off++] = (char) (enc & 0x7F); 431 return off; 432 } 433 _outputUptoMillion(byte[] b, int off, int thousands, int ones)434 private static int _outputUptoMillion(byte[] b, int off, int thousands, int ones) 435 { 436 int enc = TRIPLET_TO_CHARS[thousands]; 437 if (thousands > 9) { 438 if (thousands > 99) { 439 b[off++] = (byte) (enc >> 16); 440 } 441 b[off++] = (byte) (enc >> 8); 442 } 443 b[off++] = (byte) enc; 444 // and then full 445 enc = TRIPLET_TO_CHARS[ones]; 446 b[off++] = (byte) (enc >> 16); 447 b[off++] = (byte) (enc >> 8); 448 b[off++] = (byte) enc; 449 return off; 450 } 451 _leading3(int t, char[] b, int off)452 private static int _leading3(int t, char[] b, int off) 453 { 454 int enc = TRIPLET_TO_CHARS[t]; 455 if (t > 9) { 456 if (t > 99) { 457 b[off++] = (char) (enc >> 16); 458 } 459 b[off++] = (char) ((enc >> 8) & 0x7F); 460 } 461 b[off++] = (char) (enc & 0x7F); 462 return off; 463 } 464 _leading3(int t, byte[] b, int off)465 private static int _leading3(int t, byte[] b, int off) 466 { 467 int enc = TRIPLET_TO_CHARS[t]; 468 if (t > 9) { 469 if (t > 99) { 470 b[off++] = (byte) (enc >> 16); 471 } 472 b[off++] = (byte) (enc >> 8); 473 } 474 b[off++] = (byte) enc; 475 return off; 476 } 477 _full3(int t, char[] b, int off)478 private static int _full3(int t, char[] b, int off) 479 { 480 int enc = TRIPLET_TO_CHARS[t]; 481 b[off++] = (char) (enc >> 16); 482 b[off++] = (char) ((enc >> 8) & 0x7F); 483 b[off++] = (char) (enc & 0x7F); 484 return off; 485 } 486 _full3(int t, byte[] b, int off)487 private static int _full3(int t, byte[] b, int off) 488 { 489 int enc = TRIPLET_TO_CHARS[t]; 490 b[off++] = (byte) (enc >> 16); 491 b[off++] = (byte) (enc >> 8); 492 b[off++] = (byte) enc; 493 return off; 494 } 495 496 // // // Special cases for where we can not flip the sign bit 497 _outputSmallestL(char[] b, int off)498 private static int _outputSmallestL(char[] b, int off) 499 { 500 int len = SMALLEST_LONG.length(); 501 SMALLEST_LONG.getChars(0, len, b, off); 502 return (off + len); 503 } 504 _outputSmallestL(byte[] b, int off)505 private static int _outputSmallestL(byte[] b, int off) 506 { 507 int len = SMALLEST_LONG.length(); 508 for (int i = 0; i < len; ++i) { 509 b[off++] = (byte) SMALLEST_LONG.charAt(i); 510 } 511 return off; 512 } 513 _outputSmallestI(char[] b, int off)514 private static int _outputSmallestI(char[] b, int off) 515 { 516 int len = SMALLEST_INT.length(); 517 SMALLEST_INT.getChars(0, len, b, off); 518 return (off + len); 519 } 520 _outputSmallestI(byte[] b, int off)521 private static int _outputSmallestI(byte[] b, int off) 522 { 523 int len = SMALLEST_INT.length(); 524 for (int i = 0; i < len; ++i) { 525 b[off++] = (byte) SMALLEST_INT.charAt(i); 526 } 527 return off; 528 } 529 } 530