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
21 private final static int[] TRIPLET_TO_CHARS = new int[1000];
22
23 static {
24
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
52
53
56 public static int outputInt(int v, char[] b, int off)
57 {
58 if (v < 0) {
59 if (v == Integer.MIN_VALUE) {
60
61
62 return _outputSmallestI(b, off);
63 }
64 b[off++] = '-';
65 v = -v;
66 }
67
68 if (v < MILLION) {
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);
78 off = _leading3(thousands, b, off);
79 off = _full3(v, b, off);
80 return off;
81 }
82
83
84
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));
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
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) {
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);
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));
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
157 public static int outputLong(long v, char[] b, int off)
158 {
159
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
176 long upper = v / BILLION_L;
177 v -= (upper * BILLION_L);
178
179
180 if (upper < BILLION_L) {
181 off = _outputUptoBillion((int) upper, b, off);
182 } else {
183
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
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
210 long upper = v / BILLION_L;
211 v -= (upper * BILLION_L);
212
213
214 if (upper < BILLION_L) {
215 off = _outputUptoBillion((int) upper, b, off);
216 } else {
217
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
231
232
235 public static String toString(int v)
236 {
237
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
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
257 public static String toString(double v) {
258 return Double.toString(v);
259 }
260
261
264 public static String toString(float v) {
265 return Float.toString(v);
266 }
267
268
273
274
282 public static boolean notFinite(double value) {
283
284 return Double.isNaN(value) || Double.isInfinite(value);
285 }
286
287
295 public static boolean notFinite(float value) {
296
297 return Float.isNaN(value) || Float.isInfinite(value);
298 }
299
300
305
306 private static int _outputUptoBillion(int v, char[] b, int off)
307 {
308 if (v < MILLION) {
309 if (v < 1000) {
310 return _leading3(v, b, off);
311 }
312 int thousands = v / 1000;
313 int ones = v - (thousands * 1000);
314 return _outputUptoMillion(b, off, thousands, ones);
315 }
316 int thousands = v / 1000;
317 int ones = (v - (thousands * 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
336 private static int _outputFullBillion(int v, char[] b, int off)
337 {
338 int thousands = v / 1000;
339 int ones = (v - (thousands * 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
361 private static int _outputUptoBillion(int v, byte[] b, int off)
362 {
363 if (v < MILLION) {
364 if (v < 1000) {
365 return _leading3(v, b, off);
366 }
367 int thousands = v / 1000;
368 int ones = v - (thousands * 1000);
369 return _outputUptoMillion(b, off, thousands, ones);
370 }
371 int thousands = v / 1000;
372 int ones = (v - (thousands * 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
391 private static int _outputFullBillion(int v, byte[] b, int off)
392 {
393 int thousands = v / 1000;
394 int ones = (v - (thousands * 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
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
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
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
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
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
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
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
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
497
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
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
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
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