blob: e5c84a77de8636e361f5fc9beb05b66ae7157362 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
// Copyright (C) 2023 Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later
package jsonutil
import (
"fmt"
"io"
"math"
)
type invalidHexRuneError rune
func (e invalidHexRuneError) Error() string {
return fmt.Sprintf("jsonutil: invalid hex digit: %q", rune(e))
}
// hexDecoder is like an encoding/hex.Decoder, but has a "push"
// interface rather than a "pull" interface.
type hexDecoder struct {
dst io.ByteWriter
buf byte
bufOK bool
}
func (d *hexDecoder) WriteRune(r rune) (int, error) {
if r > math.MaxUint8 {
return 0, invalidHexRuneError(r)
}
c := byte(r)
var v byte
//nolint:gomnd // Hex conversion.
switch {
case '0' <= c && c <= '9':
v = c - '0'
case 'a' <= c && c <= 'f':
v = c - 'a' + 10
case 'A' <= c && c <= 'F':
v = c - 'A' + 10
default:
return 0, invalidHexRuneError(r)
}
if !d.bufOK {
d.buf = v
d.bufOK = true
return 1, nil
}
d.bufOK = false
return 1, d.dst.WriteByte(d.buf<<4 | v)
}
func (d *hexDecoder) Close() error {
if d.bufOK {
return io.ErrUnexpectedEOF
}
return nil
}
|