Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(3490)

Delta Between Two Patch Sets: src/pkg/encoding/json/decode.go

Issue 6943047: code review 6943047: encoding/json: encode map key is of string kind, decode... (Closed)
Left Patch Set: diff -r ac06fe42df6d https://code.google.com/p/go/ Created 11 years, 3 months ago
Right Patch Set: diff -r a298f2d529ec https://code.google.com/p/go/ Created 11 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/encoding/json/decode_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 defer func() { 118 defer func() {
119 if r := recover(); r != nil { 119 if r := recover(); r != nil {
120 if _, ok := r.(runtime.Error); ok { 120 if _, ok := r.(runtime.Error); ok {
121 panic(r) 121 panic(r)
122 } 122 }
123 err = r.(error) 123 err = r.(error)
124 } 124 }
125 }() 125 }()
126 126
127 rv := reflect.ValueOf(v) 127 rv := reflect.ValueOf(v)
128 » pv := rv 128 » if rv.Kind() != reflect.Ptr || rv.IsNil() {
129 » if pv.Kind() != reflect.Ptr || pv.IsNil() {
130 return &InvalidUnmarshalError{reflect.TypeOf(v)} 129 return &InvalidUnmarshalError{reflect.TypeOf(v)}
131 } 130 }
132 131
133 d.scan.reset() 132 d.scan.reset()
134 » // We decode rv not pv.Elem because the Unmarshaler interface 133 » // We decode rv not rv.Elem because the Unmarshaler interface
135 // test must be applied at the top level of the value. 134 // test must be applied at the top level of the value.
136 d.value(rv) 135 d.value(rv)
137 return d.savedError 136 return d.savedError
138 } 137 }
139 138
140 // A Number represents a JSON number literal. 139 // A Number represents a JSON number literal.
141 type Number string 140 type Number string
142 141
143 // String returns the literal text of the number. 142 // String returns the literal text of the number.
144 func (n Number) String() string { return string(n) } 143 func (n Number) String() string { return string(n) }
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 d.off-- 415 d.off--
417 err := unmarshaler.UnmarshalJSON(d.next()) 416 err := unmarshaler.UnmarshalJSON(d.next())
418 if err != nil { 417 if err != nil {
419 d.error(err) 418 d.error(err)
420 } 419 }
421 return 420 return
422 } 421 }
423 v = pv 422 v = pv
424 423
425 // Decoding into nil interface? Switch to non-reflect code. 424 // Decoding into nil interface? Switch to non-reflect code.
426 » iv := v 425 » if v.Kind() == reflect.Interface {
427 » if iv.Kind() == reflect.Interface { 426 » » v.Set(reflect.ValueOf(d.objectInterface()))
428 » » iv.Set(reflect.ValueOf(d.objectInterface()))
429 return 427 return
430 } 428 }
431 429
432 // Check type of target: struct or map[string]T 430 // Check type of target: struct or map[string]T
433 var (
434 mv reflect.Value
435 sv reflect.Value
436 )
437 switch v.Kind() { 431 switch v.Kind() {
438 case reflect.Map: 432 case reflect.Map:
439 // map must have string kind 433 // map must have string kind
440 t := v.Type() 434 t := v.Type()
441 » » if t.Key().Kind() != reflect.TypeOf("").Kind() { 435 » » if t.Key().Kind() != reflect.String {
442 d.saveError(&UnmarshalTypeError{"object", v.Type()}) 436 d.saveError(&UnmarshalTypeError{"object", v.Type()})
443 break 437 break
444 } 438 }
445 » » mv = v 439 » » if v.IsNil() {
446 » » if mv.IsNil() { 440 » » » v.Set(reflect.MakeMap(t))
447 » » » mv.Set(reflect.MakeMap(t))
448 } 441 }
449 case reflect.Struct: 442 case reflect.Struct:
450 sv = v
451 default: 443 default:
452 d.saveError(&UnmarshalTypeError{"object", v.Type()}) 444 d.saveError(&UnmarshalTypeError{"object", v.Type()})
453 } 445 }
454 446
455 » if !mv.IsValid() && !sv.IsValid() { 447 » if !v.IsValid() {
456 d.off-- 448 d.off--
457 d.next() // skip over { } in input 449 d.next() // skip over { } in input
458 return 450 return
459 } 451 }
460 452
461 var mapElem reflect.Value 453 var mapElem reflect.Value
462 454
463 for { 455 for {
464 // Read opening " of string key or closing }. 456 // Read opening " of string key or closing }.
465 op := d.scanWhile(scanSkipSpace) 457 op := d.scanWhile(scanSkipSpace)
(...skipping 11 matching lines...) Expand all
477 item := d.data[start : d.off-1] 469 item := d.data[start : d.off-1]
478 key, ok := unquote(item) 470 key, ok := unquote(item)
479 if !ok { 471 if !ok {
480 d.error(errPhase) 472 d.error(errPhase)
481 } 473 }
482 474
483 // Figure out field corresponding to key. 475 // Figure out field corresponding to key.
484 var subv reflect.Value 476 var subv reflect.Value
485 destring := false // whether the value is wrapped in a string to be decoded first 477 destring := false // whether the value is wrapped in a string to be decoded first
486 478
487 » » if mv.IsValid() { 479 » » if v.Kind() == reflect.Map {
488 » » » elemType := mv.Type().Elem() 480 » » » elemType := v.Type().Elem()
489 if !mapElem.IsValid() { 481 if !mapElem.IsValid() {
490 mapElem = reflect.New(elemType).Elem() 482 mapElem = reflect.New(elemType).Elem()
491 } else { 483 } else {
492 mapElem.Set(reflect.Zero(elemType)) 484 mapElem.Set(reflect.Zero(elemType))
493 } 485 }
494 subv = mapElem 486 subv = mapElem
495 } else { 487 } else {
496 var f *field 488 var f *field
497 » » » fields := cachedTypeFields(sv.Type()) 489 » » » fields := cachedTypeFields(v.Type())
498 for i := range fields { 490 for i := range fields {
499 ff := &fields[i] 491 ff := &fields[i]
500 if ff.name == key { 492 if ff.name == key {
501 f = ff 493 f = ff
502 break 494 break
503 } 495 }
504 if f == nil && strings.EqualFold(ff.name, key) { 496 if f == nil && strings.EqualFold(ff.name, key) {
505 f = ff 497 f = ff
506 } 498 }
507 } 499 }
508 if f != nil { 500 if f != nil {
509 » » » » subv = sv 501 » » » » subv = v
510 destring = f.quoted 502 destring = f.quoted
511 for _, i := range f.index { 503 for _, i := range f.index {
512 if subv.Kind() == reflect.Ptr { 504 if subv.Kind() == reflect.Ptr {
513 if subv.IsNil() { 505 if subv.IsNil() {
514 subv.Set(reflect.New(sub v.Type().Elem())) 506 subv.Set(reflect.New(sub v.Type().Elem()))
515 } 507 }
516 subv = subv.Elem() 508 subv = subv.Elem()
517 } 509 }
518 subv = subv.Field(i) 510 subv = subv.Field(i)
519 } 511 }
520 } else { 512 } else {
521 // To give a good error, a quick scan for unexpo rted fields in top level. 513 // To give a good error, a quick scan for unexpo rted fields in top level.
522 » » » » st := sv.Type() 514 » » » » st := v.Type()
523 for i := 0; i < st.NumField(); i++ { 515 for i := 0; i < st.NumField(); i++ {
524 f := st.Field(i) 516 f := st.Field(i)
525 if f.PkgPath != "" && strings.EqualFold( f.Name, key) { 517 if f.PkgPath != "" && strings.EqualFold( f.Name, key) {
526 d.saveError(&UnmarshalFieldError {key, st, f}) 518 d.saveError(&UnmarshalFieldError {key, st, f})
527 } 519 }
528 } 520 }
529 } 521 }
530 } 522 }
531 523
532 // Read : before value. 524 // Read : before value.
533 if op == scanSkipSpace { 525 if op == scanSkipSpace {
534 op = d.scanWhile(scanSkipSpace) 526 op = d.scanWhile(scanSkipSpace)
535 } 527 }
536 if op != scanObjectKey { 528 if op != scanObjectKey {
537 d.error(errPhase) 529 d.error(errPhase)
538 } 530 }
539 531
540 // Read value. 532 // Read value.
541 if destring { 533 if destring {
542 d.value(reflect.ValueOf(&d.tempstr)) 534 d.value(reflect.ValueOf(&d.tempstr))
543 d.literalStore([]byte(d.tempstr), subv, true) 535 d.literalStore([]byte(d.tempstr), subv, true)
544 } else { 536 } else {
545 d.value(subv) 537 d.value(subv)
546 } 538 }
539
547 // Write value back to map; 540 // Write value back to map;
548 // if using struct, subv points into struct already. 541 // if using struct, subv points into struct already.
549 » » if mv.IsValid() { 542 » » if v.Kind() == reflect.Map {
550 » » » kv := reflect.New(v.Type().Key()) 543 » » » kv := reflect.ValueOf(key).Convert(v.Type().Key())
551 » » » kv.Elem().SetString(key) 544 » » » v.SetMapIndex(kv, subv)
552 » » » mv.SetMapIndex(kv.Elem(), subv)
553 } 545 }
554 546
555 // Next token must be , or }. 547 // Next token must be , or }.
556 op = d.scanWhile(scanSkipSpace) 548 op = d.scanWhile(scanSkipSpace)
557 if op == scanEndObject { 549 if op == scanEndObject {
558 break 550 break
559 } 551 }
560 if op != scanObjectValue { 552 if op != scanObjectValue {
561 d.error(errPhase) 553 d.error(errPhase)
562 } 554 }
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 973
982 // Coerce to well-formed UTF-8. 974 // Coerce to well-formed UTF-8.
983 default: 975 default:
984 rr, size := utf8.DecodeRune(s[r:]) 976 rr, size := utf8.DecodeRune(s[r:])
985 r += size 977 r += size
986 w += utf8.EncodeRune(b[w:], rr) 978 w += utf8.EncodeRune(b[w:], rr)
987 } 979 }
988 } 980 }
989 return b[0:w], true 981 return b[0:w], true
990 } 982 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b