3
3
import ch .randelshofer .fastdoubleparser .JavaBigDecimalParser ;
4
4
5
5
import java .math .BigDecimal ;
6
- import java .util .Arrays ;
7
-
8
- // Based on a great idea of Eric Obermühlner to use a tree of smaller BigDecimals for parsing
9
- // really big numbers with O(n^1.5) complexity instead of O(n^2) when using the constructor
10
- // for a decimal representation from JDK 8/11:
11
- //
12
- // https://github.com/eobermuhlner/big-math/commit/7a5419aac8b2adba2aa700ccf00197f97b2ad89f
13
6
14
7
/**
15
8
* Internal Jackson Helper class used to implement more optimized parsing of {@link BigDecimal} for REALLY
@@ -37,6 +30,10 @@ private BigDecimalParser() {}
37
30
38
31
/**
39
32
* Internal Jackson method. Please do not use.
33
+ *<p>
34
+ * Note: Caller MUST pre-validate that given String represents a valid representation
35
+ * of {@link BigDecimal} value: parsers in {@code jackson-core} do that; other
36
+ * code must do the same.
40
37
*
41
38
* @param valueStr
42
39
* @return BigDecimal value
@@ -48,6 +45,10 @@ public static BigDecimal parse(String valueStr) {
48
45
49
46
/**
50
47
* Internal Jackson method. Please do not use.
48
+ *<p>
49
+ * Note: Caller MUST pre-validate that given String represents a valid representation
50
+ * of {@link BigDecimal} value: parsers in {@code jackson-core} do that; other
51
+ * code must do the same.
51
52
*
52
53
* @return BigDecimal value
53
54
* @throws NumberFormatException
@@ -62,25 +63,16 @@ public static BigDecimal parse(final char[] chars, final int off, final int len)
62
63
// 20-Aug-2022, tatu: Although "new BigDecimal(...)" only throws NumberFormatException
63
64
// operations by "parseBigDecimal()" can throw "ArithmeticException", so handle both:
64
65
} catch (ArithmeticException | NumberFormatException e ) {
65
- String desc = e .getMessage ();
66
- // 05-Feb-2021, tatu: Alas, JDK mostly has null message so:
67
- if (desc == null ) {
68
- desc = "Not a valid number representation" ;
69
- }
70
- String stringToReport ;
71
- if (len <= MAX_CHARS_TO_REPORT ) {
72
- stringToReport = new String (chars , off , len );
73
- } else {
74
- stringToReport = new String (Arrays .copyOfRange (chars , off , MAX_CHARS_TO_REPORT ))
75
- + "(truncated, full length is " + chars .length + " chars)" ;
76
- }
77
- throw new NumberFormatException ("Value \" " + stringToReport
78
- + "\" can not be represented as `java.math.BigDecimal`, reason: " + desc );
66
+ throw _parseFailure (e , new String (chars , off , len ));
79
67
}
80
68
}
81
-
69
+
82
70
/**
83
71
* Internal Jackson method. Please do not use.
72
+ *<p>
73
+ * Note: Caller MUST pre-validate that given String represents a valid representation
74
+ * of {@link BigDecimal} value: parsers in {@code jackson-core} do that; other
75
+ * code must do the same.
84
76
*
85
77
* @param chars
86
78
* @return BigDecimal value
@@ -90,25 +82,62 @@ public static BigDecimal parse(char[] chars) {
90
82
return parse (chars , 0 , chars .length );
91
83
}
92
84
85
+ /**
86
+ * Internal Jackson method. Please do not use.
87
+ *<p>
88
+ * Note: Caller MUST pre-validate that given String represents a valid representation
89
+ * of {@link BigDecimal} value: parsers in {@code jackson-core} do that; other
90
+ * code must do the same.
91
+ *
92
+ * @param valueStr
93
+ * @return BigDecimal value
94
+ * @throws NumberFormatException
95
+ */
93
96
public static BigDecimal parseWithFastParser (final String valueStr ) {
94
97
try {
95
98
return JavaBigDecimalParser .parseBigDecimal (valueStr );
96
- } catch (NumberFormatException nfe ) {
97
- final String reportNum = valueStr .length () <= MAX_CHARS_TO_REPORT ?
98
- valueStr : valueStr .substring (0 , MAX_CHARS_TO_REPORT ) + " [truncated]" ;
99
- throw new NumberFormatException ("Value \" " + reportNum
100
- + "\" can not be represented as `java.math.BigDecimal`, reason: " + nfe .getMessage ());
99
+ } catch (ArithmeticException | NumberFormatException e ) {
100
+ throw _parseFailure (e , valueStr );
101
101
}
102
102
}
103
103
104
+ /**
105
+ * Internal Jackson method. Please do not use.
106
+ *<p>
107
+ * Note: Caller MUST pre-validate that given String represents a valid representation
108
+ * of {@link BigDecimal} value: parsers in {@code jackson-core} do that; other
109
+ * code must do the same.
110
+ *
111
+ * @return BigDecimal value
112
+ * @throws NumberFormatException
113
+ */
104
114
public static BigDecimal parseWithFastParser (final char [] ch , final int off , final int len ) {
105
115
try {
106
116
return JavaBigDecimalParser .parseBigDecimal (ch , off , len );
107
- } catch (NumberFormatException nfe ) {
108
- final String reportNum = len <= MAX_CHARS_TO_REPORT ?
109
- new String (ch , off , len ) : new String (ch , off , MAX_CHARS_TO_REPORT ) + " [truncated]" ;
110
- throw new NumberFormatException ("Value \" " + reportNum
111
- + "\" can not be represented as `java.math.BigDecimal`, reason: " + nfe .getMessage ());
117
+ } catch (ArithmeticException | NumberFormatException e ) {
118
+ throw _parseFailure (e , new String (ch , off , len ));
112
119
}
113
120
}
121
+
122
+ private static NumberFormatException _parseFailure (Exception e , String fullValue ) {
123
+ String desc = e .getMessage ();
124
+ // 05-Feb-2021, tatu: Alas, JDK mostly has null message so:
125
+ if (desc == null ) {
126
+ desc = "Not a valid number representation" ;
127
+ }
128
+ String valueToReport = _getValueDesc (fullValue );
129
+ return new NumberFormatException ("Value " + valueToReport
130
+ + " can not be deserialized as `java.math.BigDecimal`, reason: " + desc );
131
+ }
132
+
133
+ private static String _getValueDesc (String fullValue ) {
134
+ final int len = fullValue .length ();
135
+ if (len <= MAX_CHARS_TO_REPORT ) {
136
+ return String .format ("\" %s\" " , fullValue );
137
+ }
138
+ return String .format ("\" %s\" (truncated to %d chars (from %d)" ,
139
+ fullValue .substring (0 , MAX_CHARS_TO_REPORT ),
140
+ MAX_CHARS_TO_REPORT , len );
141
+ }
142
+
114
143
}
0 commit comments