forked from mirror/go-json
Fix compact/indent
This commit is contained in:
parent
bbc1c41481
commit
42368dcccb
|
@ -0,0 +1,43 @@
|
|||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
func compact(dst *bytes.Buffer, src []byte) error {
|
||||
length := len(src)
|
||||
for cursor := 0; cursor < length; cursor++ {
|
||||
c := src[cursor]
|
||||
switch c {
|
||||
case ' ', '\t', '\n', '\r':
|
||||
continue
|
||||
case '"':
|
||||
if err := dst.WriteByte(c); err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
cursor++
|
||||
if err := dst.WriteByte(src[cursor]); err != nil {
|
||||
return err
|
||||
}
|
||||
switch src[cursor] {
|
||||
case '\\':
|
||||
cursor++
|
||||
if err := dst.WriteByte(src[cursor]); err != nil {
|
||||
return err
|
||||
}
|
||||
case '"':
|
||||
goto LOOP_END
|
||||
case nul:
|
||||
return errUnexpectedEndOfJSON("string", int64(length))
|
||||
}
|
||||
}
|
||||
default:
|
||||
if err := dst.WriteByte(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
LOOP_END:
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package json
|
||||
|
||||
import "bytes"
|
||||
|
||||
func encodeWithIndent(dst *bytes.Buffer, src []byte, prefix, indentStr string) error {
|
||||
length := int64(len(src))
|
||||
indentNum := 0
|
||||
indentBytes := []byte(indentStr)
|
||||
for cursor := int64(0); cursor < length; cursor++ {
|
||||
c := src[cursor]
|
||||
switch c {
|
||||
case ' ', '\t', '\n', '\r':
|
||||
continue
|
||||
case '"':
|
||||
if err := dst.WriteByte(c); err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
cursor++
|
||||
if err := dst.WriteByte(src[cursor]); err != nil {
|
||||
return err
|
||||
}
|
||||
switch src[cursor] {
|
||||
case '\\':
|
||||
cursor++
|
||||
if err := dst.WriteByte(src[cursor]); err != nil {
|
||||
return err
|
||||
}
|
||||
case '"':
|
||||
goto LOOP_END
|
||||
case nul:
|
||||
return errUnexpectedEndOfJSON("string", int64(length))
|
||||
}
|
||||
}
|
||||
case '{':
|
||||
if cursor+1 < length && src[cursor+1] == '}' {
|
||||
if _, err := dst.Write([]byte{'{', '}'}); err != nil {
|
||||
return err
|
||||
}
|
||||
cursor++
|
||||
} else {
|
||||
indentNum++
|
||||
b := []byte{c, '\n'}
|
||||
b = append(b, prefix...)
|
||||
b = append(b, bytes.Repeat(indentBytes, indentNum)...)
|
||||
if _, err := dst.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case '}':
|
||||
indentNum--
|
||||
if indentNum < 0 {
|
||||
return errInvalidCharacter('}', "}", cursor)
|
||||
}
|
||||
b := []byte{'\n', c}
|
||||
b = append(b, prefix...)
|
||||
b = append(b, bytes.Repeat(indentBytes, indentNum)...)
|
||||
if _, err := dst.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
case '[':
|
||||
if cursor+1 < length && src[cursor+1] == ']' {
|
||||
if _, err := dst.Write([]byte{'[', ']'}); err != nil {
|
||||
return err
|
||||
}
|
||||
cursor++
|
||||
} else {
|
||||
indentNum++
|
||||
b := []byte{c, '\n'}
|
||||
b = append(b, prefix...)
|
||||
b = append(b, bytes.Repeat(indentBytes, indentNum)...)
|
||||
if _, err := dst.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case ']':
|
||||
indentNum--
|
||||
if indentNum < 0 {
|
||||
return errInvalidCharacter(']', "]", cursor)
|
||||
}
|
||||
b := []byte{'\n', c}
|
||||
b = append(b, prefix...)
|
||||
b = append(b, bytes.Repeat(indentBytes, indentNum)...)
|
||||
if _, err := dst.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
case ':':
|
||||
if _, err := dst.Write([]byte{':', ' '}); err != nil {
|
||||
return err
|
||||
}
|
||||
case ',':
|
||||
b := []byte{',', '\n'}
|
||||
b = append(b, prefix...)
|
||||
b = append(b, bytes.Repeat(indentBytes, indentNum)...)
|
||||
if _, err := dst.Write(b); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
if err := dst.WriteByte(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
LOOP_END:
|
||||
}
|
||||
return nil
|
||||
}
|
21
json.go
21
json.go
|
@ -325,15 +325,7 @@ func (m *RawMessage) UnmarshalJSON(data []byte) error {
|
|||
// Compact appends to dst the JSON-encoded src with
|
||||
// insignificant space characters elided.
|
||||
func Compact(dst *bytes.Buffer, src []byte) error {
|
||||
var v interface{}
|
||||
dec := NewDecoder(bytes.NewBuffer(src))
|
||||
dec.UseNumber()
|
||||
if err := dec.Decode(&v); err != nil {
|
||||
return err
|
||||
}
|
||||
enc := NewEncoder(dst)
|
||||
enc.SetEscapeHTML(false)
|
||||
return enc.Encode(v)
|
||||
return compact(dst, src)
|
||||
}
|
||||
|
||||
// Indent appends to dst an indented form of the JSON-encoded src.
|
||||
|
@ -348,16 +340,7 @@ func Compact(dst *bytes.Buffer, src []byte) error {
|
|||
// For example, if src has no trailing spaces, neither will dst;
|
||||
// if src ends in a trailing newline, so will dst.
|
||||
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
|
||||
var v interface{}
|
||||
dec := NewDecoder(bytes.NewBuffer(src))
|
||||
dec.UseNumber()
|
||||
if err := dec.Decode(&v); err != nil {
|
||||
return err
|
||||
}
|
||||
enc := NewEncoder(dst)
|
||||
enc.SetEscapeHTML(false)
|
||||
enc.SetIndent(prefix, indent)
|
||||
return enc.Encode(v)
|
||||
return encodeWithIndent(dst, src, prefix, indent)
|
||||
}
|
||||
|
||||
// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
|
||||
|
|
Loading…
Reference in New Issue