1
0
mirror of https://github.com/json-iterator/go.git synced 2025-05-31 22:24:53 +02:00

#53 implement SetEscapeHtml

This commit is contained in:
Tao Wen 2017-06-16 00:10:05 +08:00
parent 5f22e50c89
commit a6ea770365
3 changed files with 83 additions and 76 deletions

View File

@ -14,9 +14,7 @@ package jsoniter
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"io" "io"
"reflect"
"unsafe" "unsafe"
) )
@ -25,41 +23,12 @@ import (
// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. // Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.
// Refer to https://godoc.org/encoding/json#Unmarshal for more information // Refer to https://godoc.org/encoding/json#Unmarshal for more information
func Unmarshal(data []byte, v interface{}) error { func Unmarshal(data []byte, v interface{}) error {
data = data[:lastNotSpacePos(data)] return ConfigOfDefault.Unmarshal(data, v)
iter := ParseBytes(ConfigOfDefault, data)
typ := reflect.TypeOf(v)
if typ.Kind() != reflect.Ptr {
// return non-pointer error
return errors.New("the second param must be ptr type")
}
iter.ReadVal(v)
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return nil
}
if iter.Error == nil {
iter.reportError("Unmarshal", "there are bytes left after unmarshal")
}
return iter.Error
} }
// UnmarshalAny adapts to // UnmarshalAny adapts to
func UnmarshalAny(data []byte) (Any, error) { func UnmarshalAny(data []byte) (Any, error) {
data = data[:lastNotSpacePos(data)] return ConfigOfDefault.UnmarshalAny(data)
iter := ParseBytes(ConfigOfDefault, data)
any := iter.ReadAny()
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return any, nil
}
if iter.Error == nil {
iter.reportError("UnmarshalAny", "there are bytes left after unmarshal")
}
return any, iter.Error
} }
func lastNotSpacePos(data []byte) int { func lastNotSpacePos(data []byte) int {
@ -72,37 +41,11 @@ func lastNotSpacePos(data []byte) int {
} }
func UnmarshalFromString(str string, v interface{}) error { func UnmarshalFromString(str string, v interface{}) error {
data := []byte(str) return ConfigOfDefault.UnmarshalFromString(str, v)
data = data[:lastNotSpacePos(data)]
iter := ParseBytes(ConfigOfDefault, data)
iter.ReadVal(v)
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return nil
}
if iter.Error == nil {
iter.reportError("UnmarshalFromString", "there are bytes left after unmarshal")
}
return iter.Error
} }
func UnmarshalAnyFromString(str string) (Any, error) { func UnmarshalAnyFromString(str string) (Any, error) {
data := []byte(str) return ConfigOfDefault.UnmarshalAnyFromString(str)
data = data[:lastNotSpacePos(data)]
iter := ParseBytes(ConfigOfDefault, data)
any := iter.ReadAny()
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return any, nil
}
if iter.Error == nil {
iter.reportError("UnmarshalAnyFromString", "there are bytes left after unmarshal")
}
return nil, iter.Error
} }
// Marshal adapts to json/encoding Marshal API // Marshal adapts to json/encoding Marshal API
@ -110,20 +53,11 @@ func UnmarshalAnyFromString(str string) (Any, error) {
// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API // Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API
// Refer to https://godoc.org/encoding/json#Marshal for more information // Refer to https://godoc.org/encoding/json#Marshal for more information
func Marshal(v interface{}) ([]byte, error) { func Marshal(v interface{}) ([]byte, error) {
stream := NewStream(ConfigOfDefault, nil, 256) return ConfigOfDefault.Marshal(v)
stream.WriteVal(v)
if stream.Error != nil {
return nil, stream.Error
}
return stream.Buffer(), nil
} }
func MarshalToString(v interface{}) (string, error) { func MarshalToString(v interface{}) (string, error) {
buf, err := Marshal(v) return ConfigOfDefault.MarshalToString(v)
if err != nil {
return "", err
}
return string(buf), nil
} }
// NewDecoder adapts to json/stream NewDecoder API. // NewDecoder adapts to json/stream NewDecoder API.
@ -133,8 +67,7 @@ func MarshalToString(v interface{}) (string, error) {
// Instead of a json/encoding Decoder, an AdaptedDecoder is returned // Instead of a json/encoding Decoder, an AdaptedDecoder is returned
// Refer to https://godoc.org/encoding/json#NewDecoder for more information // Refer to https://godoc.org/encoding/json#NewDecoder for more information
func NewDecoder(reader io.Reader) *AdaptedDecoder { func NewDecoder(reader io.Reader) *AdaptedDecoder {
iter := Parse(ConfigOfDefault, reader, 512) return ConfigOfDefault.NewDecoder(reader)
return &AdaptedDecoder{iter}
} }
// AdaptedDecoder reads and decodes JSON values from an input stream. // AdaptedDecoder reads and decodes JSON values from an input stream.
@ -172,8 +105,7 @@ func (decoder *AdaptedDecoder) UseNumber() {
} }
func NewEncoder(writer io.Writer) *AdaptedEncoder { func NewEncoder(writer io.Writer) *AdaptedEncoder {
stream := NewStream(Config{}.Froze(), writer, 512) return ConfigOfDefault.NewEncoder(writer)
return &AdaptedEncoder{stream}
} }
type AdaptedEncoder struct { type AdaptedEncoder struct {
@ -189,3 +121,9 @@ func (adapter *AdaptedEncoder) Encode(val interface{}) error {
func (adapter *AdaptedEncoder) SetIndent(prefix, indent string) { func (adapter *AdaptedEncoder) SetIndent(prefix, indent string) {
adapter.stream.cfg.indentionStep = len(indent) adapter.stream.cfg.indentionStep = len(indent)
} }
func (adapter *AdaptedEncoder) SetEscapeHTML(escapeHtml bool) {
config := adapter.stream.cfg.configBeforeFrozen
config.EscapeHtml = escapeHtml
adapter.stream.cfg = config.Froze()
}

View File

@ -5,6 +5,7 @@ import (
"reflect" "reflect"
"sync/atomic" "sync/atomic"
"unsafe" "unsafe"
"errors"
) )
type Config struct { type Config struct {
@ -15,6 +16,7 @@ type Config struct {
} }
type frozenConfig struct { type frozenConfig struct {
configBeforeFrozen Config
indentionStep int indentionStep int
decoderCache unsafe.Pointer decoderCache unsafe.Pointer
encoderCache unsafe.Pointer encoderCache unsafe.Pointer
@ -43,6 +45,7 @@ func (cfg Config) Froze() *frozenConfig {
if cfg.EscapeHtml { if cfg.EscapeHtml {
frozenConfig.escapeHtml() frozenConfig.escapeHtml()
} }
frozenConfig.configBeforeFrozen = cfg
return frozenConfig return frozenConfig
} }
@ -166,3 +169,67 @@ func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
} }
return iter.Error return iter.Error
} }
func (cfg *frozenConfig) NewEncoder(writer io.Writer) *AdaptedEncoder {
stream := NewStream(cfg, writer, 512)
return &AdaptedEncoder{stream}
}
func (cfg *frozenConfig) NewDecoder(reader io.Reader) *AdaptedDecoder {
iter := Parse(cfg, reader, 512)
return &AdaptedDecoder{iter}
}
func (cfg *frozenConfig) UnmarshalAnyFromString(str string) (Any, error) {
data := []byte(str)
data = data[:lastNotSpacePos(data)]
iter := ParseBytes(cfg, data)
any := iter.ReadAny()
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return any, nil
}
if iter.Error == nil {
iter.reportError("UnmarshalAnyFromString", "there are bytes left after unmarshal")
}
return nil, iter.Error
}
func (cfg *frozenConfig) UnmarshalAny(data []byte) (Any, error) {
data = data[:lastNotSpacePos(data)]
iter := ParseBytes(cfg, data)
any := iter.ReadAny()
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return any, nil
}
if iter.Error == nil {
iter.reportError("UnmarshalAny", "there are bytes left after unmarshal")
}
return any, iter.Error
}
func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
data = data[:lastNotSpacePos(data)]
iter := ParseBytes(cfg, data)
typ := reflect.TypeOf(v)
if typ.Kind() != reflect.Ptr {
// return non-pointer error
return errors.New("the second param must be ptr type")
}
iter.ReadVal(v)
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return nil
}
if iter.Error == nil {
iter.reportError("Unmarshal", "there are bytes left after unmarshal")
}
return iter.Error
}

View File

@ -37,10 +37,12 @@ func Test_new_encoder(t *testing.T) {
should := require.New(t) should := require.New(t)
buf1 := &bytes.Buffer{} buf1 := &bytes.Buffer{}
encoder1 := json.NewEncoder(buf1) encoder1 := json.NewEncoder(buf1)
encoder1.SetEscapeHTML(false)
encoder1.Encode([]int{1}) encoder1.Encode([]int{1})
should.Equal("[1]\n", buf1.String()) should.Equal("[1]\n", buf1.String())
buf2 := &bytes.Buffer{} buf2 := &bytes.Buffer{}
encoder2 := NewEncoder(buf2) encoder2 := NewEncoder(buf2)
encoder2.SetEscapeHTML(false)
encoder2.Encode([]int{1}) encoder2.Encode([]int{1})
should.Equal("[1]", buf2.String()) should.Equal("[1]", buf2.String())
} }