forked from go-faster/jx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dec_raw.go
81 lines (68 loc) · 1.53 KB
/
dec_raw.go
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package jx
import (
"io"
"github.com/go-faster/errors"
)
type rawReader struct {
// internal buffer, may be reference to *Decoder.buf.
buf []byte
// if true, buf is reference to *Decoder.buf.
captured bool
orig io.Reader
}
func (r *rawReader) Read(p []byte) (n int, err error) {
if r.captured {
// Make a copy.
r.buf = append([]byte(nil), r.buf...)
r.captured = false
}
n, err = r.orig.Read(p)
if n > 0 {
r.buf = append(r.buf, p[:n]...)
}
return n, err
}
// Raw is like Skip(), but saves and returns skipped value as raw json.
//
// Do not retain returned value, it references underlying buffer.
func (d *Decoder) Raw() (Raw, error) {
start := d.head
if orig := d.reader; orig != nil {
rr := &rawReader{
buf: d.buf[start:d.tail],
captured: true,
orig: orig,
}
d.reader = rr
defer func() {
d.reader = orig
}()
if err := d.Skip(); err != nil {
return nil, errors.Wrap(err, "skip")
}
unread := d.tail - d.head
raw := rr.buf
raw = raw[:len(raw)-unread]
return raw, nil
}
if err := d.Skip(); err != nil {
return nil, errors.Wrap(err, "skip")
}
return d.buf[start:d.head], nil
}
// RawAppend is Raw that appends saved raw json value to buf.
func (d *Decoder) RawAppend(buf Raw) (Raw, error) {
raw, err := d.Raw()
if err != nil {
return nil, err
}
return append(buf, raw...), err
}
// Raw json value.
type Raw []byte
// Type of Raw json value.
func (r Raw) Type() Type {
d := Decoder{buf: r, tail: len(r)}
return d.Next()
}
func (r Raw) String() string { return string(r) }