OLD | NEW |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Represents JSON data structure using native Go types: booleans, floats, | 5 // Represents JSON data structure using native Go types: booleans, floats, |
6 // strings, arrays, and maps. | 6 // strings, arrays, and maps. |
7 | 7 |
8 package json | 8 package json |
9 | 9 |
10 import ( | 10 import ( |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 return strconv.ParseInt(string(n), 10, 64) | 166 return strconv.ParseInt(string(n), 10, 64) |
167 } | 167 } |
168 | 168 |
169 // decodeState represents the state while decoding a JSON value. | 169 // decodeState represents the state while decoding a JSON value. |
170 type decodeState struct { | 170 type decodeState struct { |
171 data []byte | 171 data []byte |
172 off int // read offset in data | 172 off int // read offset in data |
173 scan scanner | 173 scan scanner |
174 nextscan scanner // for calls to nextValue | 174 nextscan scanner // for calls to nextValue |
175 savedError error | 175 savedError error |
176 tempstr string // scratch space to avoid some allocations | |
177 useNumber bool | 176 useNumber bool |
178 } | 177 } |
179 | 178 |
180 // errPhase is used for errors that should not happen unless | 179 // errPhase is used for errors that should not happen unless |
181 // there is a bug in the JSON decoder or something is editing | 180 // there is a bug in the JSON decoder or something is editing |
182 // the data slice while the decoder executes. | 181 // the data slice while the decoder executes. |
183 var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?") | 182 var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?") |
184 | 183 |
185 func (d *decodeState) init(data []byte) *decodeState { | 184 func (d *decodeState) init(data []byte) *decodeState { |
186 d.data = data | 185 d.data = data |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 d.array(v) | 285 d.array(v) |
287 | 286 |
288 case scanBeginObject: | 287 case scanBeginObject: |
289 d.object(v) | 288 d.object(v) |
290 | 289 |
291 case scanBeginLiteral: | 290 case scanBeginLiteral: |
292 d.literal(v) | 291 d.literal(v) |
293 } | 292 } |
294 } | 293 } |
295 | 294 |
| 295 type unquotedValue struct{} |
| 296 |
| 297 // valueQuoted is like value but decodes a |
| 298 // quoted string literal or literal null into an interface value. |
| 299 // If it finds anything other than a quoted string literal or null, |
| 300 // valueQuoted returns unquotedValue{}. |
| 301 func (d *decodeState) valueQuoted() interface{} { |
| 302 switch op := d.scanWhile(scanSkipSpace); op { |
| 303 default: |
| 304 d.error(errPhase) |
| 305 |
| 306 case scanBeginArray: |
| 307 d.array(reflect.Value{}) |
| 308 |
| 309 case scanBeginObject: |
| 310 d.object(reflect.Value{}) |
| 311 |
| 312 case scanBeginLiteral: |
| 313 switch v := d.literalInterface().(type) { |
| 314 case nil, string: |
| 315 return v |
| 316 } |
| 317 } |
| 318 return unquotedValue{} |
| 319 } |
| 320 |
296 // indirect walks down v allocating pointers as needed, | 321 // indirect walks down v allocating pointers as needed, |
297 // until it gets to a non-pointer. | 322 // until it gets to a non-pointer. |
298 // if it encounters an Unmarshaler, indirect stops and returns that. | 323 // if it encounters an Unmarshaler, indirect stops and returns that. |
299 // if decodingNull is true, indirect stops at the last pointer so it can be set
to nil. | 324 // if decodingNull is true, indirect stops at the last pointer so it can be set
to nil. |
300 func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler,
encoding.TextUnmarshaler, reflect.Value) { | 325 func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler,
encoding.TextUnmarshaler, reflect.Value) { |
301 // If v is a named type and is addressable, | 326 // If v is a named type and is addressable, |
302 // start with its address, so that if the type has pointer methods, | 327 // start with its address, so that if the type has pointer methods, |
303 // we find them. | 328 // we find them. |
304 if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { | 329 if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { |
305 v = v.Addr() | 330 v = v.Addr() |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 } | 462 } |
438 } else { | 463 } else { |
439 v.SetLen(i) | 464 v.SetLen(i) |
440 } | 465 } |
441 } | 466 } |
442 if i == 0 && v.Kind() == reflect.Slice { | 467 if i == 0 && v.Kind() == reflect.Slice { |
443 v.Set(reflect.MakeSlice(v.Type(), 0, 0)) | 468 v.Set(reflect.MakeSlice(v.Type(), 0, 0)) |
444 } | 469 } |
445 } | 470 } |
446 | 471 |
| 472 var nullLiteral = []byte("null") |
| 473 |
447 // object consumes an object from d.data[d.off-1:], decoding into the value v. | 474 // object consumes an object from d.data[d.off-1:], decoding into the value v. |
448 // the first byte of the object ('{') has been read already. | 475 // the first byte ('{') of the object has been read already. |
449 func (d *decodeState) object(v reflect.Value) { | 476 func (d *decodeState) object(v reflect.Value) { |
450 // Check for unmarshaler. | 477 // Check for unmarshaler. |
451 u, ut, pv := d.indirect(v, false) | 478 u, ut, pv := d.indirect(v, false) |
452 if u != nil { | 479 if u != nil { |
453 d.off-- | 480 d.off-- |
454 err := u.UnmarshalJSON(d.next()) | 481 err := u.UnmarshalJSON(d.next()) |
455 if err != nil { | 482 if err != nil { |
456 d.error(err) | 483 d.error(err) |
457 } | 484 } |
458 return | 485 return |
(...skipping 12 matching lines...) Expand all Loading... |
471 return | 498 return |
472 } | 499 } |
473 | 500 |
474 // Check type of target: struct or map[string]T | 501 // Check type of target: struct or map[string]T |
475 switch v.Kind() { | 502 switch v.Kind() { |
476 case reflect.Map: | 503 case reflect.Map: |
477 // map must have string kind | 504 // map must have string kind |
478 t := v.Type() | 505 t := v.Type() |
479 if t.Key().Kind() != reflect.String { | 506 if t.Key().Kind() != reflect.String { |
480 d.saveError(&UnmarshalTypeError{"object", v.Type()}) | 507 d.saveError(&UnmarshalTypeError{"object", v.Type()}) |
481 » » » break | 508 » » » d.off-- |
| 509 » » » d.next() // skip over { } in input |
| 510 » » » return |
482 } | 511 } |
483 if v.IsNil() { | 512 if v.IsNil() { |
484 v.Set(reflect.MakeMap(t)) | 513 v.Set(reflect.MakeMap(t)) |
485 } | 514 } |
486 case reflect.Struct: | 515 case reflect.Struct: |
487 | 516 |
488 default: | 517 default: |
489 d.saveError(&UnmarshalTypeError{"object", v.Type()}) | 518 d.saveError(&UnmarshalTypeError{"object", v.Type()}) |
490 d.off-- | 519 d.off-- |
491 d.next() // skip over { } in input | 520 d.next() // skip over { } in input |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 // Read : before value. | 586 // Read : before value. |
558 if op == scanSkipSpace { | 587 if op == scanSkipSpace { |
559 op = d.scanWhile(scanSkipSpace) | 588 op = d.scanWhile(scanSkipSpace) |
560 } | 589 } |
561 if op != scanObjectKey { | 590 if op != scanObjectKey { |
562 d.error(errPhase) | 591 d.error(errPhase) |
563 } | 592 } |
564 | 593 |
565 // Read value. | 594 // Read value. |
566 if destring { | 595 if destring { |
567 » » » d.value(reflect.ValueOf(&d.tempstr)) | 596 » » » switch qv := d.valueQuoted().(type) { |
568 » » » d.literalStore([]byte(d.tempstr), subv, true) | 597 » » » case nil: |
569 » » » d.tempstr = "" // Zero scratch space for successive valu
es. | 598 » » » » d.literalStore(nullLiteral, subv, false) |
| 599 » » » case string: |
| 600 » » » » d.literalStore([]byte(qv), subv, true) |
| 601 » » » default: |
| 602 » » » » d.saveError(fmt.Errorf("json: invalid use of ,st
ring struct tag, trying to unmarshal unquoted value into %v", item, v.Type())) |
| 603 » » » } |
570 } else { | 604 } else { |
571 d.value(subv) | 605 d.value(subv) |
572 } | 606 } |
573 | 607 |
574 // Write value back to map; | 608 // Write value back to map; |
575 // if using struct, subv points into struct already. | 609 // if using struct, subv points into struct already. |
576 if v.Kind() == reflect.Map { | 610 if v.Kind() == reflect.Map { |
577 kv := reflect.ValueOf(key).Convert(v.Type().Key()) | 611 kv := reflect.ValueOf(key).Convert(v.Type().Key()) |
578 v.SetMapIndex(kv, subv) | 612 v.SetMapIndex(kv, subv) |
579 } | 613 } |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 | 1075 |
1042 // Coerce to well-formed UTF-8. | 1076 // Coerce to well-formed UTF-8. |
1043 default: | 1077 default: |
1044 rr, size := utf8.DecodeRune(s[r:]) | 1078 rr, size := utf8.DecodeRune(s[r:]) |
1045 r += size | 1079 r += size |
1046 w += utf8.EncodeRune(b[w:], rr) | 1080 w += utf8.EncodeRune(b[w:], rr) |
1047 } | 1081 } |
1048 } | 1082 } |
1049 return b[0:w], true | 1083 return b[0:w], true |
1050 } | 1084 } |
OLD | NEW |