• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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