Ver Fonte

#53 implement SetEscapeHtml

Tao Wen há 8 anos atrás
pai
commit
a6ea770365
3 ficheiros alterados com 83 adições e 76 exclusões
  1. 14 76
      feature_adapter.go
  2. 67 0
      feature_config.go
  3. 2 0
      jsoniter_adapter_test.go

+ 14 - 76
feature_adapter.go

@@ -14,9 +14,7 @@ package jsoniter
 import (
 	"bytes"
 	"encoding/json"
-	"errors"
 	"io"
-	"reflect"
 	"unsafe"
 )
 
@@ -25,41 +23,12 @@ import (
 // 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
 func Unmarshal(data []byte, v interface{}) error {
-	data = data[:lastNotSpacePos(data)]
-	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
+	return ConfigOfDefault.Unmarshal(data, v)
 }
 
 // UnmarshalAny adapts to
 func UnmarshalAny(data []byte) (Any, error) {
-	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("UnmarshalAny", "there are bytes left after unmarshal")
-	}
-	return any, iter.Error
+	return ConfigOfDefault.UnmarshalAny(data)
 }
 
 func lastNotSpacePos(data []byte) int {
@@ -72,37 +41,11 @@ func lastNotSpacePos(data []byte) int {
 }
 
 func UnmarshalFromString(str string, v interface{}) error {
-	data := []byte(str)
-	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
+	return ConfigOfDefault.UnmarshalFromString(str, v)
 }
 
 func UnmarshalAnyFromString(str string) (Any, error) {
-	data := []byte(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
+	return ConfigOfDefault.UnmarshalAnyFromString(str)
 }
 
 // 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
 // Refer to https://godoc.org/encoding/json#Marshal for more information
 func Marshal(v interface{}) ([]byte, error) {
-	stream := NewStream(ConfigOfDefault, nil, 256)
-	stream.WriteVal(v)
-	if stream.Error != nil {
-		return nil, stream.Error
-	}
-	return stream.Buffer(), nil
+	return ConfigOfDefault.Marshal(v)
 }
 
 func MarshalToString(v interface{}) (string, error) {
-	buf, err := Marshal(v)
-	if err != nil {
-		return "", err
-	}
-	return string(buf), nil
+	return ConfigOfDefault.MarshalToString(v)
 }
 
 // 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
 // Refer to https://godoc.org/encoding/json#NewDecoder for more information
 func NewDecoder(reader io.Reader) *AdaptedDecoder {
-	iter := Parse(ConfigOfDefault, reader, 512)
-	return &AdaptedDecoder{iter}
+	return ConfigOfDefault.NewDecoder(reader)
 }
 
 // AdaptedDecoder reads and decodes JSON values from an input stream.
@@ -172,8 +105,7 @@ func (decoder *AdaptedDecoder) UseNumber() {
 }
 
 func NewEncoder(writer io.Writer) *AdaptedEncoder {
-	stream := NewStream(Config{}.Froze(), writer, 512)
-	return &AdaptedEncoder{stream}
+	return ConfigOfDefault.NewEncoder(writer)
 }
 
 type AdaptedEncoder struct {
@@ -189,3 +121,9 @@ func (adapter *AdaptedEncoder) Encode(val interface{}) error {
 func (adapter *AdaptedEncoder) SetIndent(prefix, indent string) {
 	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()
+}

+ 67 - 0
feature_config.go

@@ -5,6 +5,7 @@ import (
 	"reflect"
 	"sync/atomic"
 	"unsafe"
+	"errors"
 )
 
 type Config struct {
@@ -15,6 +16,7 @@ type Config struct {
 }
 
 type frozenConfig struct {
+	configBeforeFrozen	      Config
 	indentionStep                 int
 	decoderCache                  unsafe.Pointer
 	encoderCache                  unsafe.Pointer
@@ -43,6 +45,7 @@ func (cfg Config) Froze() *frozenConfig {
 	if cfg.EscapeHtml {
 		frozenConfig.escapeHtml()
 	}
+	frozenConfig.configBeforeFrozen = cfg
 	return frozenConfig
 }
 
@@ -166,3 +169,67 @@ func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) 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
+}

+ 2 - 0
jsoniter_adapter_test.go

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