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

Side by Side Diff: src/pkg/encoding/json/decode.go

Issue 6460044: code review 6460044: encoding/json: handle anonymous fields (Closed)
Patch Set: diff -r 56c7453d488f https://code.google.com/p/go/ Created 11 years, 6 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:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/pkg/encoding/json/decode_test.go » ('j') | src/pkg/encoding/json/encode.go » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 486
487 if mv.IsValid() { 487 if mv.IsValid() {
488 elemType := mv.Type().Elem() 488 elemType := mv.Type().Elem()
489 if !mapElem.IsValid() { 489 if !mapElem.IsValid() {
490 mapElem = reflect.New(elemType).Elem() 490 mapElem = reflect.New(elemType).Elem()
491 } else { 491 } else {
492 mapElem.Set(reflect.Zero(elemType)) 492 mapElem.Set(reflect.Zero(elemType))
493 } 493 }
494 subv = mapElem 494 subv = mapElem
495 } else { 495 } else {
496 » » » var f reflect.StructField 496 » » » var f *field
497 » » » var ok bool 497 » » » fields := cachedTypeFields(sv.Type())
498 » » » st := sv.Type() 498 » » » for i := range fields {
499 » » » for i := 0; i < sv.NumField(); i++ { 499 » » » » ff := &fields[i]
500 » » » » sf := st.Field(i) 500 » » » » if ff.name == key {
501 » » » » tag := sf.Tag.Get("json") 501 » » » » » f = ff
502 » » » » if tag == "-" { 502 » » » » » break
503 » » » » » // Pretend this field doesn't exist.
504 » » » » » continue
505 } 503 }
506 » » » » if sf.Anonymous { 504 » » » » if f == nil && strings.EqualFold(ff.name, key) {
507 » » » » » // Pretend this field doesn't exist, 505 » » » » » f = ff
508 » » » » » // so that we can do a good job with
509 » » » » » // these in a later version.
510 » » » » » continue
511 » » » » }
512 » » » » // First, tag match
513 » » » » tagName, _ := parseTag(tag)
514 » » » » if tagName != "" {
515 » » » » » if tagName == key {
516 » » » » » » f = sf
517 » » » » » » ok = true
518 » » » » » » break // no better match possibl e
519 » » » » » }
520 » » » » » // There was a tag, but it didn't match.
521 » » » » » // Ignore field names.
522 » » » » » continue
523 » » » » }
524 » » » » // Second, exact field name match
525 » » » » if sf.Name == key {
526 » » » » » f = sf
527 » » » » » ok = true
528 » » » » }
529 » » » » // Third, case-insensitive field name match,
530 » » » » // but only if a better match hasn't already bee n seen
531 » » » » if !ok && strings.EqualFold(sf.Name, key) {
532 » » » » » f = sf
533 » » » » » ok = true
534 } 506 }
535 } 507 }
536 508 » » » if f != nil {
537 » » » // Extract value; name must be exported. 509 » » » » subv = sv
538 » » » if ok { 510 » » » » destring = f.quoted
539 » » » » if f.PkgPath != "" { 511 » » » » for _, i := range f.index {
540 » » » » » d.saveError(&UnmarshalFieldError{key, st , f}) 512 » » » » » if subv.Kind() == reflect.Ptr {
541 » » » » } else { 513 » » » » » » if subv.IsNil() {
542 » » » » » subv = sv.FieldByIndex(f.Index) 514 » » » » » » » subv.Set(reflect.New(sub v.Type().Elem()))
515 » » » » » » }
516 » » » » » » subv = subv.Elem()
517 » » » » » }
518 » » » » » subv = subv.Field(i)
543 } 519 }
544 » » » » _, opts := parseTag(f.Tag.Get("json")) 520 » » » } else {
545 » » » » destring = opts.Contains("string") 521 » » » » // To give a good error, a quick scan for unexpo rted fields in top level.
522 » » » » st := sv.Type()
523 » » » » for i := 0; i < st.NumField(); i++ {
524 » » » » » f := st.Field(i)
525 » » » » » if f.PkgPath != "" && strings.EqualFold( f.Name, key) {
526 » » » » » » d.saveError(&UnmarshalFieldError {key, st, f})
527 » » » » » }
528 » » » » }
546 } 529 }
547 } 530 }
548 531
549 // Read : before value. 532 // Read : before value.
550 if op == scanSkipSpace { 533 if op == scanSkipSpace {
551 op = d.scanWhile(scanSkipSpace) 534 op = d.scanWhile(scanSkipSpace)
552 } 535 }
553 if op != scanObjectKey { 536 if op != scanObjectKey {
554 d.error(errPhase) 537 d.error(errPhase)
555 } 538 }
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 981
999 // Coerce to well-formed UTF-8. 982 // Coerce to well-formed UTF-8.
1000 default: 983 default:
1001 rr, size := utf8.DecodeRune(s[r:]) 984 rr, size := utf8.DecodeRune(s[r:])
1002 r += size 985 r += size
1003 w += utf8.EncodeRune(b[w:], rr) 986 w += utf8.EncodeRune(b[w:], rr)
1004 } 987 }
1005 } 988 }
1006 return b[0:w], true 989 return b[0:w], true
1007 } 990 }
1008
1009 // The following is issue 3069.
1010
1011 // BUG(rsc): This package ignores anonymous (embedded) struct fields
1012 // during encoding and decoding. A future version may assign meaning
1013 // to them. To force an anonymous field to be ignored in all future
1014 // versions of this package, use an explicit `json:"-"` tag in the struct
1015 // definition.
OLDNEW
« no previous file with comments | « no previous file | src/pkg/encoding/json/decode_test.go » ('j') | src/pkg/encoding/json/encode.go » ('J')

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