1 package com.fasterxml.jackson.core.io;
2
3 import java.math.BigDecimal;
4
5 public final class NumberInput
6 {
7
11 public final static String NASTY_SMALL_DOUBLE = "2.2250738585072012e-308";
12
13
16 final static long L_BILLION = 1000000000;
17
18 final static String MIN_LONG_STR_NO_SIGN = String.valueOf(Long.MIN_VALUE).substring(1);
19 final static String MAX_LONG_STR = String.valueOf(Long.MAX_VALUE);
20
21
28 public static int parseInt(char[] ch, int off, int len)
29 {
30 int num = ch[off + len - 1] - '0';
31
32 switch(len) {
33 case 9:
34 num += (ch[off++] - '0') * 100000000;
35 case 8:
36 num += (ch[off++] - '0') * 10000000;
37 case 7:
38 num += (ch[off++] - '0') * 1000000;
39 case 6:
40 num += (ch[off++] - '0') * 100000;
41 case 5:
42 num += (ch[off++] - '0') * 10000;
43 case 4:
44 num += (ch[off++] - '0') * 1000;
45 case 3:
46 num += (ch[off++] - '0') * 100;
47 case 2:
48 num += (ch[off] - '0') * 10;
49 }
50 return num;
51 }
52
53
57 public static int parseInt(String s)
58 {
59
63 char c = s.charAt(0);
64 int len = s.length();
65 boolean neg = (c == '-');
66 int offset = 1;
67
68
69 if (neg) {
70 if (len == 1 || len > 10) {
71 return Integer.parseInt(s);
72 }
73 c = s.charAt(offset++);
74 } else {
75 if (len > 9) {
76 return Integer.parseInt(s);
77 }
78 }
79 if (c > '9' || c < '0') {
80 return Integer.parseInt(s);
81 }
82 int num = c - '0';
83 if (offset < len) {
84 c = s.charAt(offset++);
85 if (c > '9' || c < '0') {
86 return Integer.parseInt(s);
87 }
88 num = (num * 10) + (c - '0');
89 if (offset < len) {
90 c = s.charAt(offset++);
91 if (c > '9' || c < '0') {
92 return Integer.parseInt(s);
93 }
94 num = (num * 10) + (c - '0');
95
96 if (offset < len) {
97 do {
98 c = s.charAt(offset++);
99 if (c > '9' || c < '0') {
100 return Integer.parseInt(s);
101 }
102 num = (num * 10) + (c - '0');
103 } while (offset < len);
104 }
105 }
106 }
107 return neg ? -num : num;
108 }
109
110 public static long parseLong(char[] ch, int off, int len)
111 {
112
113 int len1 = len-9;
114 long val = parseInt(ch, off, len1) * L_BILLION;
115 return val + (long) parseInt(ch, off+len1, 9);
116 }
117
118 public static long parseLong(String s)
119 {
120
123 int length = s.length();
124 if (length <= 9) {
125 return (long) parseInt(s);
126 }
127
128 return Long.parseLong(s);
129 }
130
131
140 public static boolean inLongRange(char[] ch, int off, int len,
141 boolean negative)
142 {
143 String cmpStr = negative ? MIN_LONG_STR_NO_SIGN : MAX_LONG_STR;
144 int cmpLen = cmpStr.length();
145 if (len < cmpLen) return true;
146 if (len > cmpLen) return false;
147
148 for (int i = 0; i < cmpLen; ++i) {
149 int diff = ch[off+i] - cmpStr.charAt(i);
150 if (diff != 0) {
151 return (diff < 0);
152 }
153 }
154 return true;
155 }
156
157
164 public static boolean inLongRange(String s, boolean negative)
165 {
166 String cmp = negative ? MIN_LONG_STR_NO_SIGN : MAX_LONG_STR;
167 int cmpLen = cmp.length();
168 int alen = s.length();
169 if (alen < cmpLen) return true;
170 if (alen > cmpLen) return false;
171
172
173 for (int i = 0; i < cmpLen; ++i) {
174 int diff = s.charAt(i) - cmp.charAt(i);
175 if (diff != 0) {
176 return (diff < 0);
177 }
178 }
179 return true;
180 }
181
182 public static int parseAsInt(String s, int def)
183 {
184 if (s == null) {
185 return def;
186 }
187 s = s.trim();
188 int len = s.length();
189 if (len == 0) {
190 return def;
191 }
192
193 int i = 0;
194 if (i < len) {
195 char c = s.charAt(0);
196 if (c == '+') {
197 s = s.substring(1);
198 len = s.length();
199 } else if (c == '-') {
200 ++i;
201 }
202 }
203 for (; i < len; ++i) {
204 char c = s.charAt(i);
205
206 if (c > '9' || c < '0') {
207 try {
208 return (int) parseDouble(s);
209 } catch (NumberFormatException e) {
210 return def;
211 }
212 }
213 }
214 try {
215 return Integer.parseInt(s);
216 } catch (NumberFormatException e) { }
217 return def;
218 }
219
220 public static long parseAsLong(String s, long def)
221 {
222 if (s == null) {
223 return def;
224 }
225 s = s.trim();
226 int len = s.length();
227 if (len == 0) {
228 return def;
229 }
230
231 int i = 0;
232 if (i < len) {
233 char c = s.charAt(0);
234 if (c == '+') {
235 s = s.substring(1);
236 len = s.length();
237 } else if (c == '-') {
238 ++i;
239 }
240 }
241 for (; i < len; ++i) {
242 char c = s.charAt(i);
243
244 if (c > '9' || c < '0') {
245 try {
246 return (long) parseDouble(s);
247 } catch (NumberFormatException e) {
248 return def;
249 }
250 }
251 }
252 try {
253 return Long.parseLong(s);
254 } catch (NumberFormatException e) { }
255 return def;
256 }
257
258 public static double parseAsDouble(String s, double def)
259 {
260 if (s == null) { return def; }
261 s = s.trim();
262 int len = s.length();
263 if (len == 0) {
264 return def;
265 }
266 try {
267 return parseDouble(s);
268 } catch (NumberFormatException e) { }
269 return def;
270 }
271
272 public static double parseDouble(String s) throws NumberFormatException {
273
274
277 if (NASTY_SMALL_DOUBLE.equals(s)) {
278 return Double.MIN_VALUE;
279 }
280 return Double.parseDouble(s);
281 }
282
283 public static BigDecimal parseBigDecimal(String s) throws NumberFormatException {
284 try { return new BigDecimal(s); } catch (NumberFormatException e) {
285 throw _badBD(s);
286 }
287 }
288
289 public static BigDecimal parseBigDecimal(char[] b) throws NumberFormatException {
290 return parseBigDecimal(b, 0, b.length);
291 }
292
293 public static BigDecimal parseBigDecimal(char[] b, int off, int len) throws NumberFormatException {
294 try { return new BigDecimal(b, off, len); } catch (NumberFormatException e) {
295 throw _badBD(new String(b, off, len));
296 }
297 }
298
299 private static NumberFormatException _badBD(String s) {
300 return new NumberFormatException("Value \""+s+"\" can not be represented as BigDecimal");
301 }
302 }
303