aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/json/decode.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-09-22 04:47:32 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-09-22 04:47:32 +0000
commit9d49f4d0aba73cd49fb2f7bb1b02a3c3e062949c (patch)
treed2bb9404c8c972b65a3a92e2f30721def7c92dc3 /libgo/go/json/decode.go
parent270aae3307efa26c11b8b219c4400e819b24247f (diff)
downloadgcc-9d49f4d0aba73cd49fb2f7bb1b02a3c3e062949c.zip
gcc-9d49f4d0aba73cd49fb2f7bb1b02a3c3e062949c.tar.gz
gcc-9d49f4d0aba73cd49fb2f7bb1b02a3c3e062949c.tar.bz2
Update Go library to release r60.1.
From-SVN: r179076
Diffstat (limited to 'libgo/go/json/decode.go')
-rw-r--r--libgo/go/json/decode.go22
1 files changed, 18 insertions, 4 deletions
diff --git a/libgo/go/json/decode.go b/libgo/go/json/decode.go
index 4f6562b..b7129f9 100644
--- a/libgo/go/json/decode.go
+++ b/libgo/go/json/decode.go
@@ -140,6 +140,7 @@ type decodeState struct {
scan scanner
nextscan scanner // for calls to nextValue
savedError os.Error
+ tempstr string // scratch space to avoid some allocations
}
// errPhase is used for errors that should not happen unless
@@ -470,6 +471,8 @@ func (d *decodeState) object(v reflect.Value) {
// Figure out field corresponding to key.
var subv reflect.Value
+ destring := false // whether the value is wrapped in a string to be decoded first
+
if mv.IsValid() {
elemType := mv.Type().Elem()
if !mapElem.IsValid() {
@@ -486,7 +489,8 @@ func (d *decodeState) object(v reflect.Value) {
if isValidTag(key) {
for i := 0; i < sv.NumField(); i++ {
f = st.Field(i)
- if f.Tag.Get("json") == key {
+ tagName, _ := parseTag(f.Tag.Get("json"))
+ if tagName == key {
ok = true
break
}
@@ -508,6 +512,8 @@ func (d *decodeState) object(v reflect.Value) {
} else {
subv = sv.FieldByIndex(f.Index)
}
+ _, opts := parseTag(f.Tag.Get("json"))
+ destring = opts.Contains("string")
}
}
@@ -520,8 +526,12 @@ func (d *decodeState) object(v reflect.Value) {
}
// Read value.
- d.value(subv)
-
+ if destring {
+ d.value(reflect.ValueOf(&d.tempstr))
+ d.literalStore([]byte(d.tempstr), subv)
+ } else {
+ d.value(subv)
+ }
// Write value back to map;
// if using struct, subv points into struct already.
if mv.IsValid() {
@@ -550,8 +560,12 @@ func (d *decodeState) literal(v reflect.Value) {
// Scan read one byte too far; back up.
d.off--
d.scan.undo(op)
- item := d.data[start:d.off]
+ d.literalStore(d.data[start:d.off], v)
+}
+
+// literalStore decodes a literal stored in item into v.
+func (d *decodeState) literalStore(item []byte, v reflect.Value) {
// Check for unmarshaler.
wantptr := item[0] == 'n' // null
unmarshaler, pv := d.indirect(v, wantptr)