dependabot-hex 0.107.13 → 0.107.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/helpers/deps/jason/.fetch +0 -0
- data/helpers/deps/jason/.hex +2 -0
- data/helpers/deps/jason/CHANGELOG.md +60 -0
- data/helpers/deps/jason/LICENSE +13 -0
- data/helpers/deps/jason/README.md +179 -0
- data/helpers/deps/jason/hex_metadata.config +20 -0
- data/helpers/deps/jason/lib/codegen.ex +158 -0
- data/helpers/deps/jason/lib/decoder.ex +657 -0
- data/helpers/deps/jason/lib/encode.ex +630 -0
- data/helpers/deps/jason/lib/encoder.ex +216 -0
- data/helpers/deps/jason/lib/formatter.ex +253 -0
- data/helpers/deps/jason/lib/fragment.ex +11 -0
- data/helpers/deps/jason/lib/helpers.ex +90 -0
- data/helpers/deps/jason/lib/jason.ex +228 -0
- data/helpers/deps/jason/mix.exs +92 -0
- metadata +18 -3
@@ -0,0 +1,657 @@
|
|
1
|
+
defmodule Jason.DecodeError do
|
2
|
+
@type t :: %__MODULE__{position: integer, data: String.t}
|
3
|
+
|
4
|
+
defexception [:position, :token, :data]
|
5
|
+
|
6
|
+
def message(%{position: position, token: token}) when is_binary(token) do
|
7
|
+
"unexpected sequence at position #{position}: #{inspect token}"
|
8
|
+
end
|
9
|
+
def message(%{position: position, data: data}) when position == byte_size(data) do
|
10
|
+
"unexpected end of input at position #{position}"
|
11
|
+
end
|
12
|
+
def message(%{position: position, data: data}) do
|
13
|
+
byte = :binary.at(data, position)
|
14
|
+
str = <<byte>>
|
15
|
+
if String.printable?(str) do
|
16
|
+
"unexpected byte at position #{position}: " <>
|
17
|
+
"#{inspect byte, base: :hex} ('#{str}')"
|
18
|
+
else
|
19
|
+
"unexpected byte at position #{position}: " <>
|
20
|
+
"#{inspect byte, base: :hex}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
defmodule Jason.Decoder do
|
26
|
+
@moduledoc false
|
27
|
+
|
28
|
+
import Bitwise
|
29
|
+
|
30
|
+
alias Jason.{DecodeError, Codegen}
|
31
|
+
|
32
|
+
import Codegen, only: [bytecase: 2, bytecase: 3]
|
33
|
+
|
34
|
+
# @compile :native
|
35
|
+
|
36
|
+
# We use integers instead of atoms to take advantage of the jump table
|
37
|
+
# optimization
|
38
|
+
@terminate 0
|
39
|
+
@array 1
|
40
|
+
@key 2
|
41
|
+
@object 3
|
42
|
+
|
43
|
+
def parse(data, opts) when is_binary(data) do
|
44
|
+
key_decode = key_decode_function(opts)
|
45
|
+
string_decode = string_decode_function(opts)
|
46
|
+
try do
|
47
|
+
value(data, data, 0, [@terminate], key_decode, string_decode)
|
48
|
+
catch
|
49
|
+
{:position, position} ->
|
50
|
+
{:error, %DecodeError{position: position, data: data}}
|
51
|
+
{:token, token, position} ->
|
52
|
+
{:error, %DecodeError{token: token, position: position, data: data}}
|
53
|
+
else
|
54
|
+
value ->
|
55
|
+
{:ok, value}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
defp key_decode_function(%{keys: :atoms}), do: &String.to_atom/1
|
60
|
+
defp key_decode_function(%{keys: :atoms!}), do: &String.to_existing_atom/1
|
61
|
+
defp key_decode_function(%{keys: :strings}), do: &(&1)
|
62
|
+
defp key_decode_function(%{keys: fun}) when is_function(fun, 1), do: fun
|
63
|
+
|
64
|
+
defp string_decode_function(%{strings: :copy}), do: &:binary.copy/1
|
65
|
+
defp string_decode_function(%{strings: :reference}), do: &(&1)
|
66
|
+
|
67
|
+
defp value(data, original, skip, stack, key_decode, string_decode) do
|
68
|
+
bytecase data do
|
69
|
+
_ in '\s\n\t\r', rest ->
|
70
|
+
value(rest, original, skip + 1, stack, key_decode, string_decode)
|
71
|
+
_ in '0', rest ->
|
72
|
+
number_zero(rest, original, skip, stack, key_decode, string_decode, 1)
|
73
|
+
_ in '123456789', rest ->
|
74
|
+
number(rest, original, skip, stack, key_decode, string_decode, 1)
|
75
|
+
_ in '-', rest ->
|
76
|
+
number_minus(rest, original, skip, stack, key_decode, string_decode)
|
77
|
+
_ in '"', rest ->
|
78
|
+
string(rest, original, skip + 1, stack, key_decode, string_decode, 0)
|
79
|
+
_ in '[', rest ->
|
80
|
+
array(rest, original, skip + 1, stack, key_decode, string_decode)
|
81
|
+
_ in '{', rest ->
|
82
|
+
object(rest, original, skip + 1, stack, key_decode, string_decode)
|
83
|
+
_ in ']', rest ->
|
84
|
+
empty_array(rest, original, skip + 1, stack, key_decode, string_decode)
|
85
|
+
_ in 't', rest ->
|
86
|
+
case rest do
|
87
|
+
<<"rue", rest::bits>> ->
|
88
|
+
continue(rest, original, skip + 4, stack, key_decode, string_decode, true)
|
89
|
+
<<_::bits>> ->
|
90
|
+
error(original, skip)
|
91
|
+
end
|
92
|
+
_ in 'f', rest ->
|
93
|
+
case rest do
|
94
|
+
<<"alse", rest::bits>> ->
|
95
|
+
continue(rest, original, skip + 5, stack, key_decode, string_decode, false)
|
96
|
+
<<_::bits>> ->
|
97
|
+
error(original, skip)
|
98
|
+
end
|
99
|
+
_ in 'n', rest ->
|
100
|
+
case rest do
|
101
|
+
<<"ull", rest::bits>> ->
|
102
|
+
continue(rest, original, skip + 4, stack, key_decode, string_decode, nil)
|
103
|
+
<<_::bits>> ->
|
104
|
+
error(original, skip)
|
105
|
+
end
|
106
|
+
_, rest ->
|
107
|
+
error(rest, original, skip + 1, stack, key_decode, string_decode)
|
108
|
+
<<_::bits>> ->
|
109
|
+
error(original, skip)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
defp number_minus(<<?0, rest::bits>>, original, skip, stack, key_decode, string_decode) do
|
114
|
+
number_zero(rest, original, skip, stack, key_decode, string_decode, 2)
|
115
|
+
end
|
116
|
+
defp number_minus(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode)
|
117
|
+
when byte in '123456789' do
|
118
|
+
number(rest, original, skip, stack, key_decode, string_decode, 2)
|
119
|
+
end
|
120
|
+
defp number_minus(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode) do
|
121
|
+
error(original, skip + 1)
|
122
|
+
end
|
123
|
+
|
124
|
+
defp number(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
125
|
+
when byte in '0123456789' do
|
126
|
+
number(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
127
|
+
end
|
128
|
+
defp number(<<?., rest::bits>>, original, skip, stack, key_decode, string_decode, len) do
|
129
|
+
number_frac(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
130
|
+
end
|
131
|
+
defp number(<<e, rest::bits>>, original, skip, stack, key_decode, string_decode, len) when e in 'eE' do
|
132
|
+
prefix = binary_part(original, skip, len)
|
133
|
+
number_exp_copy(rest, original, skip + len + 1, stack, key_decode, string_decode, prefix)
|
134
|
+
end
|
135
|
+
defp number(<<rest::bits>>, original, skip, stack, key_decode, string_decode, len) do
|
136
|
+
int = String.to_integer(binary_part(original, skip, len))
|
137
|
+
continue(rest, original, skip + len, stack, key_decode, string_decode, int)
|
138
|
+
end
|
139
|
+
|
140
|
+
defp number_frac(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
141
|
+
when byte in '0123456789' do
|
142
|
+
number_frac_cont(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
143
|
+
end
|
144
|
+
defp number_frac(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, len) do
|
145
|
+
error(original, skip + len)
|
146
|
+
end
|
147
|
+
|
148
|
+
defp number_frac_cont(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
149
|
+
when byte in '0123456789' do
|
150
|
+
number_frac_cont(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
151
|
+
end
|
152
|
+
defp number_frac_cont(<<e, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
153
|
+
when e in 'eE' do
|
154
|
+
number_exp(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
155
|
+
end
|
156
|
+
defp number_frac_cont(<<rest::bits>>, original, skip, stack, key_decode, string_decode, len) do
|
157
|
+
token = binary_part(original, skip, len)
|
158
|
+
float = try_parse_float(token, token, skip)
|
159
|
+
continue(rest, original, skip + len, stack, key_decode, string_decode, float)
|
160
|
+
end
|
161
|
+
|
162
|
+
defp number_exp(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
163
|
+
when byte in '0123456789' do
|
164
|
+
number_exp_cont(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
165
|
+
end
|
166
|
+
defp number_exp(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
167
|
+
when byte in '+-' do
|
168
|
+
number_exp_sign(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
169
|
+
end
|
170
|
+
defp number_exp(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, len) do
|
171
|
+
error(original, skip + len)
|
172
|
+
end
|
173
|
+
|
174
|
+
defp number_exp_sign(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
175
|
+
when byte in '0123456789' do
|
176
|
+
number_exp_cont(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
177
|
+
end
|
178
|
+
defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, len) do
|
179
|
+
error(original, skip + len)
|
180
|
+
end
|
181
|
+
|
182
|
+
defp number_exp_cont(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, len)
|
183
|
+
when byte in '0123456789' do
|
184
|
+
number_exp_cont(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
185
|
+
end
|
186
|
+
defp number_exp_cont(<<rest::bits>>, original, skip, stack, key_decode, string_decode, len) do
|
187
|
+
token = binary_part(original, skip, len)
|
188
|
+
float = try_parse_float(token, token, skip)
|
189
|
+
continue(rest, original, skip + len, stack, key_decode, string_decode, float)
|
190
|
+
end
|
191
|
+
|
192
|
+
defp number_exp_copy(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, prefix)
|
193
|
+
when byte in '0123456789' do
|
194
|
+
number_exp_cont(rest, original, skip, stack, key_decode, string_decode, prefix, 1)
|
195
|
+
end
|
196
|
+
defp number_exp_copy(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, prefix)
|
197
|
+
when byte in '+-' do
|
198
|
+
number_exp_sign(rest, original, skip, stack, key_decode, string_decode, prefix, 1)
|
199
|
+
end
|
200
|
+
defp number_exp_copy(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _prefix) do
|
201
|
+
error(original, skip)
|
202
|
+
end
|
203
|
+
|
204
|
+
defp number_exp_sign(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, prefix, len)
|
205
|
+
when byte in '0123456789' do
|
206
|
+
number_exp_cont(rest, original, skip, stack, key_decode, string_decode, prefix, len + 1)
|
207
|
+
end
|
208
|
+
defp number_exp_sign(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _prefix, len) do
|
209
|
+
error(original, skip + len)
|
210
|
+
end
|
211
|
+
|
212
|
+
defp number_exp_cont(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, prefix, len)
|
213
|
+
when byte in '0123456789' do
|
214
|
+
number_exp_cont(rest, original, skip, stack, key_decode, string_decode, prefix, len + 1)
|
215
|
+
end
|
216
|
+
defp number_exp_cont(<<rest::bits>>, original, skip, stack, key_decode, string_decode, prefix, len) do
|
217
|
+
suffix = binary_part(original, skip, len)
|
218
|
+
string = prefix <> ".0e" <> suffix
|
219
|
+
prefix_size = byte_size(prefix)
|
220
|
+
initial_skip = skip - prefix_size - 1
|
221
|
+
final_skip = skip + len
|
222
|
+
token = binary_part(original, initial_skip, prefix_size + len + 1)
|
223
|
+
float = try_parse_float(string, token, initial_skip)
|
224
|
+
continue(rest, original, final_skip, stack, key_decode, string_decode, float)
|
225
|
+
end
|
226
|
+
|
227
|
+
defp number_zero(<<?., rest::bits>>, original, skip, stack, key_decode, string_decode, len) do
|
228
|
+
number_frac(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
229
|
+
end
|
230
|
+
defp number_zero(<<e, rest::bits>>, original, skip, stack, key_decode, string_decode, len) when e in 'eE' do
|
231
|
+
number_exp_copy(rest, original, skip + len + 1, stack, key_decode, string_decode, "0")
|
232
|
+
end
|
233
|
+
defp number_zero(<<rest::bits>>, original, skip, stack, key_decode, string_decode, len) do
|
234
|
+
continue(rest, original, skip + len, stack, key_decode, string_decode, 0)
|
235
|
+
end
|
236
|
+
|
237
|
+
@compile {:inline, array: 6}
|
238
|
+
|
239
|
+
defp array(rest, original, skip, stack, key_decode, string_decode) do
|
240
|
+
value(rest, original, skip, [@array, [] | stack], key_decode, string_decode)
|
241
|
+
end
|
242
|
+
|
243
|
+
defp empty_array(<<rest::bits>>, original, skip, stack, key_decode, string_decode) do
|
244
|
+
case stack do
|
245
|
+
[@array, [] | stack] ->
|
246
|
+
continue(rest, original, skip, stack, key_decode, string_decode, [])
|
247
|
+
_ ->
|
248
|
+
error(original, skip - 1)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
defp array(data, original, skip, stack, key_decode, string_decode, value) do
|
253
|
+
bytecase data do
|
254
|
+
_ in '\s\n\t\r', rest ->
|
255
|
+
array(rest, original, skip + 1, stack, key_decode, string_decode, value)
|
256
|
+
_ in ']', rest ->
|
257
|
+
[acc | stack] = stack
|
258
|
+
value = :lists.reverse(acc, [value])
|
259
|
+
continue(rest, original, skip + 1, stack, key_decode, string_decode, value)
|
260
|
+
_ in ',', rest ->
|
261
|
+
[acc | stack] = stack
|
262
|
+
value(rest, original, skip + 1, [@array, [value | acc] | stack], key_decode, string_decode)
|
263
|
+
_, _rest ->
|
264
|
+
error(original, skip)
|
265
|
+
<<_::bits>> ->
|
266
|
+
empty_error(original, skip)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
@compile {:inline, object: 6}
|
271
|
+
|
272
|
+
defp object(rest, original, skip, stack, key_decode, string_decode) do
|
273
|
+
key(rest, original, skip, [[] | stack], key_decode, string_decode)
|
274
|
+
end
|
275
|
+
|
276
|
+
defp object(data, original, skip, stack, key_decode, string_decode, value) do
|
277
|
+
bytecase data do
|
278
|
+
_ in '\s\n\t\r', rest ->
|
279
|
+
object(rest, original, skip + 1, stack, key_decode, string_decode, value)
|
280
|
+
_ in '}', rest ->
|
281
|
+
skip = skip + 1
|
282
|
+
[key, acc | stack] = stack
|
283
|
+
final = [{key_decode.(key), value} | acc]
|
284
|
+
continue(rest, original, skip, stack, key_decode, string_decode, :maps.from_list(final))
|
285
|
+
_ in ',', rest ->
|
286
|
+
skip = skip + 1
|
287
|
+
[key, acc | stack] = stack
|
288
|
+
acc = [{key_decode.(key), value} | acc]
|
289
|
+
key(rest, original, skip, [acc | stack], key_decode, string_decode)
|
290
|
+
_, _rest ->
|
291
|
+
error(original, skip)
|
292
|
+
<<_::bits>> ->
|
293
|
+
empty_error(original, skip)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
defp key(data, original, skip, stack, key_decode, string_decode) do
|
298
|
+
bytecase data do
|
299
|
+
_ in '\s\n\t\r', rest ->
|
300
|
+
key(rest, original, skip + 1, stack, key_decode, string_decode)
|
301
|
+
_ in '}', rest ->
|
302
|
+
case stack do
|
303
|
+
[[] | stack] ->
|
304
|
+
continue(rest, original, skip + 1, stack, key_decode, string_decode, %{})
|
305
|
+
_ ->
|
306
|
+
error(original, skip)
|
307
|
+
end
|
308
|
+
_ in '"', rest ->
|
309
|
+
string(rest, original, skip + 1, [@key | stack], key_decode, string_decode, 0)
|
310
|
+
_, _rest ->
|
311
|
+
error(original, skip)
|
312
|
+
<<_::bits>> ->
|
313
|
+
empty_error(original, skip)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
defp key(data, original, skip, stack, key_decode, string_decode, value) do
|
318
|
+
bytecase data do
|
319
|
+
_ in '\s\n\t\r', rest ->
|
320
|
+
key(rest, original, skip + 1, stack, key_decode, string_decode, value)
|
321
|
+
_ in ':', rest ->
|
322
|
+
value(rest, original, skip + 1, [@object, value | stack], key_decode, string_decode)
|
323
|
+
_, _rest ->
|
324
|
+
error(original, skip)
|
325
|
+
<<_::bits>> ->
|
326
|
+
empty_error(original, skip)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
# TODO: check if this approach would be faster:
|
331
|
+
# https://git.ninenines.eu/cowlib.git/tree/src/cow_ws.erl#n469
|
332
|
+
# http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
333
|
+
defp string(data, original, skip, stack, key_decode, string_decode, len) do
|
334
|
+
bytecase data, 128 do
|
335
|
+
_ in '"', rest ->
|
336
|
+
string = string_decode.(binary_part(original, skip, len))
|
337
|
+
continue(rest, original, skip + len + 1, stack, key_decode, string_decode, string)
|
338
|
+
_ in '\\', rest ->
|
339
|
+
part = binary_part(original, skip, len)
|
340
|
+
escape(rest, original, skip + len, stack, key_decode, string_decode, part)
|
341
|
+
_ in unquote(0x00..0x1F), _rest ->
|
342
|
+
error(original, skip)
|
343
|
+
_, rest ->
|
344
|
+
string(rest, original, skip, stack, key_decode, string_decode, len + 1)
|
345
|
+
<<char::utf8, rest::bits>> when char <= 0x7FF ->
|
346
|
+
string(rest, original, skip, stack, key_decode, string_decode, len + 2)
|
347
|
+
<<char::utf8, rest::bits>> when char <= 0xFFFF ->
|
348
|
+
string(rest, original, skip, stack, key_decode, string_decode, len + 3)
|
349
|
+
<<_char::utf8, rest::bits>> ->
|
350
|
+
string(rest, original, skip, stack, key_decode, string_decode, len + 4)
|
351
|
+
<<_::bits>> ->
|
352
|
+
empty_error(original, skip + len)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
defp string(data, original, skip, stack, key_decode, string_decode, acc, len) do
|
357
|
+
bytecase data, 128 do
|
358
|
+
_ in '"', rest ->
|
359
|
+
last = binary_part(original, skip, len)
|
360
|
+
string = IO.iodata_to_binary([acc | last])
|
361
|
+
continue(rest, original, skip + len + 1, stack, key_decode, string_decode, string)
|
362
|
+
_ in '\\', rest ->
|
363
|
+
part = binary_part(original, skip, len)
|
364
|
+
escape(rest, original, skip + len, stack, key_decode, string_decode, [acc | part])
|
365
|
+
_ in unquote(0x00..0x1F), _rest ->
|
366
|
+
error(original, skip)
|
367
|
+
_, rest ->
|
368
|
+
string(rest, original, skip, stack, key_decode, string_decode, acc, len + 1)
|
369
|
+
<<char::utf8, rest::bits>> when char <= 0x7FF ->
|
370
|
+
string(rest, original, skip, stack, key_decode, string_decode, acc, len + 2)
|
371
|
+
<<char::utf8, rest::bits>> when char <= 0xFFFF ->
|
372
|
+
string(rest, original, skip, stack, key_decode, string_decode, acc, len + 3)
|
373
|
+
<<_char::utf8, rest::bits>> ->
|
374
|
+
string(rest, original, skip, stack, key_decode, string_decode, acc, len + 4)
|
375
|
+
<<_::bits>> ->
|
376
|
+
empty_error(original, skip + len)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
defp escape(data, original, skip, stack, key_decode, string_decode, acc) do
|
381
|
+
bytecase data do
|
382
|
+
_ in 'b', rest ->
|
383
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\b'], 0)
|
384
|
+
_ in 't', rest ->
|
385
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\t'], 0)
|
386
|
+
_ in 'n', rest ->
|
387
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\n'], 0)
|
388
|
+
_ in 'f', rest ->
|
389
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\f'], 0)
|
390
|
+
_ in 'r', rest ->
|
391
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\r'], 0)
|
392
|
+
_ in '"', rest ->
|
393
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\"'], 0)
|
394
|
+
_ in '/', rest ->
|
395
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '/'], 0)
|
396
|
+
_ in '\\', rest ->
|
397
|
+
string(rest, original, skip + 2, stack, key_decode, string_decode, [acc | '\\'], 0)
|
398
|
+
_ in 'u', rest ->
|
399
|
+
escapeu(rest, original, skip, stack, key_decode, string_decode, acc)
|
400
|
+
_, _rest ->
|
401
|
+
error(original, skip + 1)
|
402
|
+
<<_::bits>> ->
|
403
|
+
empty_error(original, skip)
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
defmodule Unescape do
|
408
|
+
@moduledoc false
|
409
|
+
|
410
|
+
import Bitwise
|
411
|
+
|
412
|
+
@digits Enum.concat([?0..?9, ?A..?F, ?a..?f])
|
413
|
+
|
414
|
+
def unicode_escapes(chars1 \\ @digits, chars2 \\ @digits) do
|
415
|
+
for char1 <- chars1, char2 <- chars2 do
|
416
|
+
{(char1 <<< 8) + char2, integer8(char1, char2)}
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
defp integer8(char1, char2) do
|
421
|
+
(integer4(char1) <<< 4) + integer4(char2)
|
422
|
+
end
|
423
|
+
|
424
|
+
defp integer4(char) when char in ?0..?9, do: char - ?0
|
425
|
+
defp integer4(char) when char in ?A..?F, do: char - ?A + 10
|
426
|
+
defp integer4(char) when char in ?a..?f, do: char - ?a + 10
|
427
|
+
|
428
|
+
defp token_error_clause(original, skip, len) do
|
429
|
+
quote do
|
430
|
+
_ ->
|
431
|
+
token_error(unquote_splicing([original, skip, len]))
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
defmacro escapeu_first(int, last, rest, original, skip, stack, key_decode, string_decode, acc) do
|
436
|
+
clauses = escapeu_first_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc)
|
437
|
+
quote location: :keep do
|
438
|
+
case unquote(int) do
|
439
|
+
unquote(clauses ++ token_error_clause(original, skip, 6))
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
defp escapeu_first_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc) do
|
445
|
+
for {int, first} <- unicode_escapes(),
|
446
|
+
not (first in 0xDC..0xDF) do
|
447
|
+
escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc)
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc)
|
452
|
+
when first in 0xD8..0xDB do
|
453
|
+
hi =
|
454
|
+
quote bind_quoted: [first: first, last: last] do
|
455
|
+
0x10000 + ((((first &&& 0x03) <<< 8) + last) <<< 10)
|
456
|
+
end
|
457
|
+
args = [rest, original, skip, stack, key_decode, string_decode, acc, hi]
|
458
|
+
[clause] =
|
459
|
+
quote location: :keep do
|
460
|
+
unquote(int) -> escape_surrogate(unquote_splicing(args))
|
461
|
+
end
|
462
|
+
clause
|
463
|
+
end
|
464
|
+
|
465
|
+
defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc)
|
466
|
+
when first <= 0x00 do
|
467
|
+
skip = quote do: (unquote(skip) + 6)
|
468
|
+
acc =
|
469
|
+
quote bind_quoted: [acc: acc, first: first, last: last] do
|
470
|
+
if last <= 0x7F do
|
471
|
+
# 0?????
|
472
|
+
[acc, last]
|
473
|
+
else
|
474
|
+
# 110xxxx?? 10?????
|
475
|
+
byte1 = ((0b110 <<< 5) + (first <<< 2)) + (last >>> 6)
|
476
|
+
byte2 = (0b10 <<< 6) + (last &&& 0b111111)
|
477
|
+
[acc, byte1, byte2]
|
478
|
+
end
|
479
|
+
end
|
480
|
+
args = [rest, original, skip, stack, key_decode, string_decode, acc, 0]
|
481
|
+
[clause] =
|
482
|
+
quote location: :keep do
|
483
|
+
unquote(int) -> string(unquote_splicing(args))
|
484
|
+
end
|
485
|
+
clause
|
486
|
+
end
|
487
|
+
|
488
|
+
defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc)
|
489
|
+
when first <= 0x07 do
|
490
|
+
skip = quote do: (unquote(skip) + 6)
|
491
|
+
acc =
|
492
|
+
quote bind_quoted: [acc: acc, first: first, last: last] do
|
493
|
+
# 110xxx?? 10??????
|
494
|
+
byte1 = ((0b110 <<< 5) + (first <<< 2)) + (last >>> 6)
|
495
|
+
byte2 = (0b10 <<< 6) + (last &&& 0b111111)
|
496
|
+
[acc, byte1, byte2]
|
497
|
+
end
|
498
|
+
args = [rest, original, skip, stack, key_decode, string_decode, acc, 0]
|
499
|
+
[clause] =
|
500
|
+
quote location: :keep do
|
501
|
+
unquote(int) -> string(unquote_splicing(args))
|
502
|
+
end
|
503
|
+
clause
|
504
|
+
end
|
505
|
+
|
506
|
+
defp escapeu_first_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc)
|
507
|
+
when first <= 0xFF do
|
508
|
+
skip = quote do: (unquote(skip) + 6)
|
509
|
+
acc =
|
510
|
+
quote bind_quoted: [acc: acc, first: first, last: last] do
|
511
|
+
# 1110xxxx 10xxxx?? 10??????
|
512
|
+
byte1 = (0b1110 <<< 4) + (first >>> 4)
|
513
|
+
byte2 = ((0b10 <<< 6) + ((first &&& 0b1111) <<< 2)) + (last >>> 6)
|
514
|
+
byte3 = (0b10 <<< 6) + (last &&& 0b111111)
|
515
|
+
[acc, byte1, byte2, byte3]
|
516
|
+
end
|
517
|
+
args = [rest, original, skip, stack, key_decode, string_decode, acc, 0]
|
518
|
+
[clause] =
|
519
|
+
quote location: :keep do
|
520
|
+
unquote(int) -> string(unquote_splicing(args))
|
521
|
+
end
|
522
|
+
clause
|
523
|
+
end
|
524
|
+
|
525
|
+
defmacro escapeu_last(int, original, skip) do
|
526
|
+
clauses = escapeu_last_clauses()
|
527
|
+
quote location: :keep do
|
528
|
+
case unquote(int) do
|
529
|
+
unquote(clauses ++ token_error_clause(original, skip, 6))
|
530
|
+
end
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
defp escapeu_last_clauses() do
|
535
|
+
for {int, last} <- unicode_escapes() do
|
536
|
+
[clause] =
|
537
|
+
quote do
|
538
|
+
unquote(int) -> unquote(last)
|
539
|
+
end
|
540
|
+
clause
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
defmacro escapeu_surrogate(int, last, rest, original, skip, stack, key_decode, string_decode, acc,
|
545
|
+
hi) do
|
546
|
+
clauses = escapeu_surrogate_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc, hi)
|
547
|
+
quote location: :keep do
|
548
|
+
case unquote(int) do
|
549
|
+
unquote(clauses ++ token_error_clause(original, skip, 12))
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
defp escapeu_surrogate_clauses(last, rest, original, skip, stack, key_decode, string_decode, acc, hi) do
|
555
|
+
digits1 = 'Dd'
|
556
|
+
digits2 = Stream.concat([?C..?F, ?c..?f])
|
557
|
+
for {int, first} <- unicode_escapes(digits1, digits2) do
|
558
|
+
escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc, hi)
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
defp escapeu_surrogate_clause(int, first, last, rest, original, skip, stack, key_decode, string_decode, acc, hi) do
|
563
|
+
skip = quote do: unquote(skip) + 12
|
564
|
+
acc =
|
565
|
+
quote bind_quoted: [acc: acc, first: first, last: last, hi: hi] do
|
566
|
+
lo = ((first &&& 0x03) <<< 8) + last
|
567
|
+
[acc | <<(hi + lo)::utf8>>]
|
568
|
+
end
|
569
|
+
args = [rest, original, skip, stack, key_decode, string_decode, acc, 0]
|
570
|
+
[clause] =
|
571
|
+
quote do
|
572
|
+
unquote(int) ->
|
573
|
+
string(unquote_splicing(args))
|
574
|
+
end
|
575
|
+
clause
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
defp escapeu(<<int1::16, int2::16, rest::bits>>, original, skip, stack, key_decode, string_decode, acc) do
|
580
|
+
require Unescape
|
581
|
+
last = escapeu_last(int2, original, skip)
|
582
|
+
Unescape.escapeu_first(int1, last, rest, original, skip, stack, key_decode, string_decode, acc)
|
583
|
+
end
|
584
|
+
defp escapeu(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _acc) do
|
585
|
+
empty_error(original, skip)
|
586
|
+
end
|
587
|
+
|
588
|
+
# @compile {:inline, escapeu_last: 3}
|
589
|
+
|
590
|
+
defp escapeu_last(int, original, skip) do
|
591
|
+
require Unescape
|
592
|
+
Unescape.escapeu_last(int, original, skip)
|
593
|
+
end
|
594
|
+
|
595
|
+
defp escape_surrogate(<<?\\, ?u, int1::16, int2::16, rest::bits>>, original,
|
596
|
+
skip, stack, key_decode, string_decode, acc, hi) do
|
597
|
+
require Unescape
|
598
|
+
last = escapeu_last(int2, original, skip + 6)
|
599
|
+
Unescape.escapeu_surrogate(int1, last, rest, original, skip, stack, key_decode, string_decode, acc, hi)
|
600
|
+
end
|
601
|
+
defp escape_surrogate(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _acc, _hi) do
|
602
|
+
error(original, skip + 6)
|
603
|
+
end
|
604
|
+
|
605
|
+
defp try_parse_float(string, token, skip) do
|
606
|
+
:erlang.binary_to_float(string)
|
607
|
+
catch
|
608
|
+
:error, :badarg ->
|
609
|
+
token_error(token, skip)
|
610
|
+
end
|
611
|
+
|
612
|
+
defp error(<<_rest::bits>>, _original, skip, _stack, _key_decode, _string_decode) do
|
613
|
+
throw {:position, skip - 1}
|
614
|
+
end
|
615
|
+
|
616
|
+
defp empty_error(_original, skip) do
|
617
|
+
throw {:position, skip}
|
618
|
+
end
|
619
|
+
|
620
|
+
@compile {:inline, error: 2, token_error: 2, token_error: 3}
|
621
|
+
defp error(_original, skip) do
|
622
|
+
throw {:position, skip}
|
623
|
+
end
|
624
|
+
|
625
|
+
defp token_error(token, position) do
|
626
|
+
throw {:token, token, position}
|
627
|
+
end
|
628
|
+
|
629
|
+
defp token_error(token, position, len) do
|
630
|
+
throw {:token, binary_part(token, position, len), position}
|
631
|
+
end
|
632
|
+
|
633
|
+
@compile {:inline, continue: 7}
|
634
|
+
defp continue(rest, original, skip, stack, key_decode, string_decode, value) do
|
635
|
+
case stack do
|
636
|
+
[@terminate | stack] ->
|
637
|
+
terminate(rest, original, skip, stack, key_decode, string_decode, value)
|
638
|
+
[@array | stack] ->
|
639
|
+
array(rest, original, skip, stack, key_decode, string_decode, value)
|
640
|
+
[@key | stack] ->
|
641
|
+
key(rest, original, skip, stack, key_decode, string_decode, value)
|
642
|
+
[@object | stack] ->
|
643
|
+
object(rest, original, skip, stack, key_decode, string_decode, value)
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
defp terminate(<<byte, rest::bits>>, original, skip, stack, key_decode, string_decode, value)
|
648
|
+
when byte in '\s\n\r\t' do
|
649
|
+
terminate(rest, original, skip + 1, stack, key_decode, string_decode, value)
|
650
|
+
end
|
651
|
+
defp terminate(<<>>, _original, _skip, _stack, _key_decode, _string_decode, value) do
|
652
|
+
value
|
653
|
+
end
|
654
|
+
defp terminate(<<_rest::bits>>, original, skip, _stack, _key_decode, _string_decode, _value) do
|
655
|
+
error(original, skip)
|
656
|
+
end
|
657
|
+
end
|