@@ -3,9 +3,7 @@ package io.circe
3
3
import com .github .plokhotnyuk .jsoniter_scala .core ._
4
4
import io .circe .Decoder .Result
5
5
import io .circe .Json ._
6
- import io .circe .numbers .BiggerDecimal
7
-
8
- import java .math .{BigInteger , RoundingMode }
6
+ import java .math .RoundingMode
9
7
import java .nio .charset .StandardCharsets
10
8
import java .util
11
9
import scala .collection .immutable .VectorBuilder
@@ -15,7 +13,6 @@ object JsoniterScalaCodec {
15
13
/**
16
14
* Default number parser that detects integers vs floating-point values
17
15
* and chooses an appropriate JSON number representation.
18
- *
19
16
* @return a JSON number value
20
17
*/
21
18
val defaultNumberParser : JsonReader => Json = in => new JNumber ({
@@ -72,9 +69,13 @@ object JsoniterScalaCodec {
72
69
}
73
70
}
74
71
75
- private [this ] val longMin = BigInteger .valueOf(Long .MinValue )
72
+ private [this ] val intMin = java.math.BigDecimal .valueOf(Int .MinValue )
73
+
74
+ private [this ] val intMax = java.math.BigDecimal .valueOf(Int .MaxValue )
75
+
76
+ private [this ] val longMin = java.math.BigDecimal .valueOf(Long .MinValue )
76
77
77
- private [this ] val longMax = BigInteger .valueOf(Long .MaxValue )
78
+ private [this ] val longMax = java.math. BigDecimal .valueOf(Long .MaxValue )
78
79
79
80
/**
80
81
* Converts an ASCII byte array to a JSON string.
@@ -107,9 +108,9 @@ object JsoniterScalaCodec {
107
108
val b = l.toByte
108
109
if (b == l) return new Right (b)
109
110
case jbd : JsonBigDecimal =>
110
- val bi = longValueExact (jbd.value)
111
- if (bi ne null ) {
112
- val l = bi.longValue
111
+ val bd = intValueExact (jbd.value)
112
+ if (bd ne null ) {
113
+ val l = bd.intValue
113
114
val b = l.toByte
114
115
if (b == l) return new Right (b)
115
116
}
@@ -143,9 +144,9 @@ object JsoniterScalaCodec {
143
144
val s = l.toShort
144
145
if (s == l) return new Right (s)
145
146
case jbd : JsonBigDecimal =>
146
- val bi = longValueExact (jbd.value)
147
- if (bi ne null ) {
148
- val l = bi.longValue
147
+ val bd = intValueExact (jbd.value)
148
+ if (bd ne null ) {
149
+ val l = bd.intValue
149
150
val s = l.toShort
150
151
if (s == l) return new Right (s)
151
152
}
@@ -179,12 +180,8 @@ object JsoniterScalaCodec {
179
180
val i = l.toInt
180
181
if (i == l) return new Right (i)
181
182
case jbd : JsonBigDecimal =>
182
- val bi = longValueExact(jbd.value)
183
- if (bi ne null ) {
184
- val l = bi.longValue
185
- val i = l.toInt
186
- if (i == l) return new Right (i)
187
- }
183
+ val bd = intValueExact(jbd.value)
184
+ if (bd ne null ) return new Right (bd.intValue)
188
185
case y =>
189
186
val ol = y.toLong
190
187
if (ol ne None ) {
@@ -212,12 +209,8 @@ object JsoniterScalaCodec {
212
209
n.value match {
213
210
case jl : JsonLong => return new Right (jl.value)
214
211
case jbd : JsonBigDecimal =>
215
- val bi = longValueExact(jbd.value)
216
- if (bi ne null ) {
217
- val l = bi.longValue
218
- val s = l.toShort
219
- if (s == l) return new Right (s)
220
- }
212
+ val bd = longValueExact(jbd.value)
213
+ if (bd ne null ) return new Right (bd.longValue)
221
214
case x =>
222
215
val ol = x.toLong
223
216
if (ol ne None ) return new Right (ol.get)
@@ -315,16 +308,27 @@ object JsoniterScalaCodec {
315
308
private [this ] def fail (c : HCursor ): Result [BigDecimal ] = new Left (DecodingFailure (" BigDecimal" , c.history))
316
309
}
317
310
318
- private [this ] def longValueExact (bd : java.math.BigDecimal ): BigInteger =
311
+ private [this ] def intValueExact (bd : java.math.BigDecimal ): java.math.BigDecimal =
312
+ if (bd.signum != 0 ) {
313
+ var p = bd.precision
314
+ val s = bd.scale
315
+ if (p <= s || p - 10 > s) return null
316
+ val bd0 = bd.setScale(0 , RoundingMode .UNNECESSARY )
317
+ p = bd0.precision
318
+ if (p > 10 || p == 10 && (bd0.compareTo(intMin) < 0 || bd0.compareTo(intMax) > 0 )) return null
319
+ bd0
320
+ } else java.math.BigDecimal .ZERO
321
+
322
+ private [this ] def longValueExact (bd : java.math.BigDecimal ): java.math.BigDecimal =
319
323
if (bd.signum != 0 ) {
320
- val p = bd.precision
324
+ var p = bd.precision
321
325
val s = bd.scale
322
326
if (p <= s || p - 19 > s) return null
323
327
val bd0 = bd.setScale(0 , RoundingMode .UNNECESSARY )
324
- val bi = bd0.unscaledValue
325
- if (bd0.precision >= 19 || bi .compareTo(longMin) < 0 || bi .compareTo(longMax) > 0 ) return null
326
- bi
327
- } else BigInteger .ZERO
328
+ p = bd0.precision
329
+ if (p > 19 || p == 19 && (bd0 .compareTo(longMin) < 0 || bd0 .compareTo(longMax) > 0 ) ) return null
330
+ bd0
331
+ } else java.math. BigDecimal .ZERO
328
332
}
329
333
330
334
/**
0 commit comments