summaryrefslogtreecommitdiff
path: root/encode.go
diff options
context:
space:
mode:
Diffstat (limited to 'encode.go')
-rw-r--r--encode.go45
1 files changed, 31 insertions, 14 deletions
diff --git a/encode.go b/encode.go
index 684cc75..f8c6915 100644
--- a/encode.go
+++ b/encode.go
@@ -385,34 +385,51 @@ func encode(w *ReEncoder, val reflect.Value, escaper BackslashEscaper, utf Inval
return err
}
+ var kBuf strings.Builder
+ kEnc := NewReEncoder(&kBuf, ReEncoderConfig{
+ AllowMultipleValues: true,
+
+ Compact: true,
+
+ BackslashEscape: escaper,
+ InvalidUTF8: utf,
+ })
+
type kv struct {
- K string
- V reflect.Value
+ KStr string
+ K reflect.Value
+ V reflect.Value
}
kvs := make([]kv, val.Len())
iter := val.MapRange()
for i := 0; iter.Next(); i++ {
- // TODO: Avoid buffering the map key
- var k strings.Builder
- if err := encode(NewReEncoder(&k, ReEncoderConfig{BackslashEscape: escaper, InvalidUTF8: utf}), iter.Key(), escaper, utf, false, cycleDepth, cycleSeen); err != nil {
+ if err := encode(kEnc, iter.Key(), escaper, utf, false, cycleDepth, cycleSeen); err != nil {
return err
}
- kStr := k.String()
+ if err := kEnc.Close(); err != nil {
+ return err
+ }
+ kStr := strings.Trim(kBuf.String(), "\n")
+ kBuf.Reset()
if kStr == "null" {
- kStr = `""`
+ kStr = ""
}
- if !strings.HasPrefix(kStr, `"`) {
- k.Reset()
- if err := jsonstring.EncodeStringFromString(&k, escaper, utf, iter.Key(), kStr); err != nil {
+
+ // TODO(lukeshu): Have kEnc look at the first byte, and feed directly to a decoder,
+ // instead of needing to buffer the whole thing twice.
+ if strings.HasPrefix(kStr, `"`) {
+ if err := DecodeString(strings.NewReader(kStr), &kBuf); err != nil {
return err
}
- kStr = k.String()
+ kStr = kBuf.String()
+ kBuf.Reset()
}
- kvs[i].K = kStr
+ kvs[i].KStr = kStr
+ kvs[i].K = iter.Key()
kvs[i].V = iter.Value()
}
sort.Slice(kvs, func(i, j int) bool {
- return kvs[i].K < kvs[j].K
+ return kvs[i].KStr < kvs[j].KStr
})
for i, kv := range kvs {
@@ -421,7 +438,7 @@ func encode(w *ReEncoder, val reflect.Value, escaper BackslashEscaper, utf Inval
return err
}
}
- if _, err := w.WriteString(kv.K); err != nil {
+ if err := jsonstring.EncodeStringFromString(w, escaper, utf, kv.K, kv.KStr); err != nil {
return err
}
if err := w.WriteByte(':'); err != nil {