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
|
// Compact appends to dst the JSON-encoded src with
|
||||||
// insignificant space characters elided.
|
// insignificant space characters elided.
|
||||||
func Compact(dst *bytes.Buffer, src []byte) error {
|
func Compact(dst *bytes.Buffer, src []byte) error {
|
||||||
var v interface{}
|
return compact(dst, src)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indent appends to dst an indented form of the JSON-encoded 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;
|
// For example, if src has no trailing spaces, neither will dst;
|
||||||
// if src ends in a trailing newline, so will dst.
|
// if src ends in a trailing newline, so will dst.
|
||||||
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
|
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
|
||||||
var v interface{}
|
return encodeWithIndent(dst, src, prefix, indent)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
|
// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
|
||||||
|
|
Loading…
Reference in New Issue