@@ -43,13 +43,15 @@ defmodule Jason.Decoder do
43
43
@ key 2
44
44
@ object 3
45
45
46
- defrecordp :decode , [ keys: nil , strings: nil ]
46
+ defrecordp :decode , [ keys: nil , strings: nil , floats: nil ]
47
47
48
48
def parse ( data , opts ) when is_binary ( data ) do
49
49
key_decode = key_decode_function ( opts )
50
50
string_decode = string_decode_function ( opts )
51
+ float_decode = float_decode_function ( opts )
52
+ decode = decode ( keys: key_decode , strings: string_decode , floats: float_decode )
51
53
try do
52
- value ( data , data , 0 , [ @ terminate ] , decode ( keys: key_decode , strings: string_decode ) )
54
+ value ( data , data , 0 , [ @ terminate ] , decode )
53
55
catch
54
56
{ :position , position } ->
55
57
{ :error , % DecodeError { position: position , data: data } }
@@ -69,6 +71,30 @@ defmodule Jason.Decoder do
69
71
defp string_decode_function ( % { strings: :copy } ) , do: & :binary . copy / 1
70
72
defp string_decode_function ( % { strings: :reference } ) , do: & ( & 1 )
71
73
74
+ defp float_decode_function ( % { floats: :native } ) do
75
+ fn string , token , skip ->
76
+ try do
77
+ :erlang . binary_to_float ( string )
78
+ catch
79
+ :error , :badarg ->
80
+ token_error ( token , skip )
81
+ end
82
+ end
83
+ end
84
+
85
+ defp float_decode_function ( % { floats: :decimals } ) do
86
+ fn string , token , skip ->
87
+ # silence xref warning
88
+ decimal = Decimal
89
+ try do
90
+ decimal . new ( string )
91
+ rescue
92
+ Decimal.Error ->
93
+ token_error ( token , skip )
94
+ end
95
+ end
96
+ end
97
+
72
98
defp value ( data , original , skip , stack , decode ) do
73
99
bytecase data do
74
100
_ in '\s \n \t \r ' , rest ->
@@ -160,7 +186,8 @@ defmodule Jason.Decoder do
160
186
end
161
187
defp number_frac_cont ( << rest :: bits >> , original , skip , stack , decode , len ) do
162
188
token = binary_part ( original , skip , len )
163
- float = try_parse_float ( token , token , skip )
189
+ decode ( floats: float_decode ) = decode
190
+ float = float_decode . ( token , token , skip )
164
191
continue ( rest , original , skip + len , stack , decode , float )
165
192
end
166
193
@@ -190,7 +217,8 @@ defmodule Jason.Decoder do
190
217
end
191
218
defp number_exp_cont ( << rest :: bits >> , original , skip , stack , decode , len ) do
192
219
token = binary_part ( original , skip , len )
193
- float = try_parse_float ( token , token , skip )
220
+ decode ( floats: float_decode ) = decode
221
+ float = float_decode . ( token , token , skip )
194
222
continue ( rest , original , skip + len , stack , decode , float )
195
223
end
196
224
@@ -225,7 +253,8 @@ defmodule Jason.Decoder do
225
253
initial_skip = skip - prefix_size - 1
226
254
final_skip = skip + len
227
255
token = binary_part ( original , initial_skip , prefix_size + len + 1 )
228
- float = try_parse_float ( string , token , initial_skip )
256
+ decode ( floats: float_decode ) = decode
257
+ float = float_decode . ( string , token , initial_skip )
229
258
continue ( rest , original , final_skip , stack , decode , float )
230
259
end
231
260
@@ -610,13 +639,6 @@ defmodule Jason.Decoder do
610
639
error ( original , skip + 6 )
611
640
end
612
641
613
- defp try_parse_float ( string , token , skip ) do
614
- :erlang . binary_to_float ( string )
615
- catch
616
- :error , :badarg ->
617
- token_error ( token , skip )
618
- end
619
-
620
642
defp error ( << _rest :: bits >> , _original , skip , _stack , _decode ) do
621
643
throw { :position , skip - 1 }
622
644
end
0 commit comments