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.
@@ -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