gopherjs - json/stream.go
1 package json
2
3 import (
4 "errors"
5 "io"
6
7 "github.com/gopherjs/gopherjs/js"
8 )
9
10 type JSObject struct {
11 *js.Object
12 }
13
14 type RawMessage []byte
15
16 func (r *RawMessage) MarshalJSON() ([]byte, error) {
17 return *r, nil
18 }
19
20 func (r *RawMessage) UnmarshalJSON(data []byte) error {
21 if r == nil {
22 return ErrRawNil
23 }
24 *r = append((*r)[:0], data...)
25 return nil
26 }
27
28 type Encoder struct {
29 w io.Writer
30 err error
31 }
32
33 func NewEncoder(w io.Writer) *Encoder {
34 return &Encoder{w: w}
35 }
36
37 func (e *Encoder) Encode(v interface{}) error {
38 b, err := Marshal(v)
39 if err != nil {
40 return err
41 }
42 _, err = e.w.Write(b)
43 e.err = err
44 return err
45 }
46
47 type Decoder struct {
48 p parser
49 }
50
51 type byteReader struct {
52 io.Reader
53 }
54
55 func (br byteReader) ReadByte() (byte, error) {
56 b := make([]byte, 1)
57 _, err := br.Read(b)
58 if err != nil {
59 return 0, err
60 }
61 return b[0], nil
62 }
63
64 type parser struct {
65 io.ByteReader
66 err error
67 buf byte
68 read []byte
69 }
70
71 func (p *parser) Next() byte {
72 var b byte
73 if p.buf > 0 {
74 b = p.buf
75 p.buf = 0
76 } else {
77 var err error
78 b, err = p.ByteReader.ReadByte()
79 if err != nil {
80 p.err = err
81 return 0
82 }
83 }
84 p.read = append(p.read, b)
85 return b
86 }
87
88 func (p *parser) Backup() {
89 p.buf = p.read[len(p.read)-1]
90 p.read = p.read[:len(p.read)-1]
91 }
92
93 func (p *parser) Accept(s string) bool {
94 b := p.Next()
95 for i := 0; i < len(s); i++ {
96 if s[i] == b {
97 return true
98 }
99 }
100 p.Backup()
101 return false
102 }
103
104 func (p *parser) AcceptRun(s string) {
105 Loop:
106 for {
107 b := p.Next()
108 for i := 0; i < len(s); i++ {
109 if s[i] == b {
110 continue Loop
111 }
112 }
113 p.Backup()
114 return
115 }
116 }
117
118 func (p *parser) Peek() byte {
119 b := p.Next()
120 p.Backup()
121 return b
122 }
123
124 func NewDecoder(r io.Reader) *Decoder {
125 b, ok := r.(io.ByteReader)
126 if !ok {
127 b = byteReader{r}
128 }
129 return &Decoder{p: parser{ByteReader: b}}
130 }
131
132 func (d *Decoder) Decode(v interface{}) error {
133 d.p.err = nil
134 d.p.read = d.p.read[:0]
135 if !d.readValue() {
136 return errInvalidJSON
137 }
138 if d.p.err != nil {
139 err := d.p.err
140 return err
141 }
142 if !d.readValue() {
143 if d.p.err != nil {
144 return d.p.err
145 }
146 return errInvalidJSON
147 }
148 s := string(d.p.read)
149 return UnmarshalString(s, v)
150 }
151
152 const whitespace = " \n\r"
153
154 func (d *Decoder) readValue() bool {
155 d.p.AcceptRun(whitespace)
156 var valid bool
157 switch d.p.Peek() {
158 case '"':
159 valid = d.readString()
160 case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
161 valid = d.readNumber()
162 case '{':
163 valid = d.readObject()
164 case '[':
165 valid = d.readArray()
166 case 't':
167 valid = d.readTrue()
168 case 'f':
169 valid = d.readFalse()
170 case 'n':
171 valid = d.readNull()
172 }
173 return valid
174 }
175
176 func (d *Decoder) readString() bool {
177 if !d.p.Accept("\"") {
178 return false
179 }
180 for {
181 switch c := d.p.Next(); c {
182 case '"':
183 return true
184 case '\\':
185 switch d.p.Next() {
186 case '"', '\\', '/', 'b', 'n', 'r', 't':
187 case 'u':
188 if !d.p.Accept("0123456789abcdefABCDEF") || !d.p.Accept("0123456789abcdefABCDEF") || !d.p.Accept("0123456789abcdefABCDEF") || !d.p.Accept("0123456789abcdefABCDEF") {
189 return false
190 }
191 default:
192 return false
193 }
194 case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x7f:
195 return false
196 }
197 }
198 }
199
200 func (d *Decoder) readNumber() bool {
201 d.p.Accept("-")
202 if !d.p.Accept("0") {
203 d.p.Accept("123456789")
204 d.p.AcceptRun("0123456789")
205 }
206 if d.p.Accept(".") {
207 d.p.AcceptRun("0123456789")
208 }
209 if d.p.Accept("eE") {
210 d.p.Accept("+-")
211 d.p.AcceptRun("0123456789")
212 }
213 return true
214 }
215
216 func (d *Decoder) readObject() bool {
217 d.p.Accept("{")
218 d.p.AcceptRun(whitespace)
219 if d.p.Accept("}") {
220 return true
221 }
222 for {
223 if !d.readString() {
224 return false
225 }
226 d.p.AcceptRun(whitespace)
227 if !d.p.Accept(":") {
228 return false
229 }
230 if !d.readValue() {
231 return false
232 }
233 d.p.AcceptRun(whitespace)
234 if d.p.Accept("}") {
235 return true
236 }
237 if !d.p.Accept(",") {
238 return false
239 }
240 d.p.AcceptRun(whitespace)
241 }
242 }
243
244 func (d *Decoder) readArray() bool {
245 d.p.Accept("[")
246 d.p.AcceptRun(whitespace)
247 if d.p.Accept("]") {
248 return true
249 }
250 for {
251 if !d.readValue() {
252 return false
253 }
254 d.p.AcceptRun(whitespace)
255 if d.p.Accept("]") {
256 return true
257 }
258 if !d.p.Accept(",") {
259 return false
260 }
261 }
262 }
263
264 func (d *Decoder) readTrue() bool {
265 return d.p.Accept("t") && d.p.Accept("r") && d.p.Accept("u") && d.p.Accept("e")
266 }
267
268 func (d *Decoder) readFalse() bool {
269 return d.p.Accept("f") && d.p.Accept("a") && d.p.Accept("l") && d.p.Accept("s") && d.p.Accept("e")
270 }
271
272 func (d *Decoder) readNull() bool {
273 return d.p.Accept("n") && d.p.Accept("u") && d.p.Accept("l") && d.p.Accept("l")
274 }
275
276 // Errors
277 var (
278 errInvalidJSON = errors.New("invalid JSON")
279 ErrRawNil = errors.New("RawMessage cannot be nil pointer")
280 )