diff --git a/extension_tests/decoder_test.go b/extension_tests/decoder_test.go index 0f1dd30a..eaf256b1 100644 --- a/extension_tests/decoder_test.go +++ b/extension_tests/decoder_test.go @@ -38,7 +38,7 @@ func Test_customize_byte_array_encoder(t *testing.T) { should := require.New(t) jsoniter.RegisterTypeEncoderFunc("[]uint8", func(ptr unsafe.Pointer, stream *jsoniter.Stream) { t := *((*[]byte)(ptr)) - stream.WriteString(string(t)) + stream.WriteBytesAsString(t) }, nil) //defer jsoniter.ConfigDefault.(*frozenConfig).cleanEncoders() val := []byte("abc") diff --git a/reflect_struct_encoder.go b/reflect_struct_encoder.go index d0759cf6..f84359ca 100644 --- a/reflect_struct_encoder.go +++ b/reflect_struct_encoder.go @@ -202,7 +202,7 @@ func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Strea tempStream := encoder.cfg.BorrowStream(nil) defer encoder.cfg.ReturnStream(tempStream) encoder.elemEncoder.Encode(ptr, tempStream) - stream.WriteString(string(tempStream.Buffer())) + stream.WriteBytesAsString(tempStream.Buffer()) } func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { diff --git a/stream_str.go b/stream_str.go index 54c2ba0b..6ebe8a9e 100644 --- a/stream_str.go +++ b/stream_str.go @@ -2,6 +2,7 @@ package jsoniter import ( "unicode/utf8" + "unsafe" ) // htmlSafeSet holds the value true if the ASCII character with the given @@ -307,6 +308,13 @@ func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen stream.writeByte('"') } +// WriteBytesAsString writes b to the stream (without html escapes) as if it +// were a string. (If you start out with a []byte, calling this instead of +// WriteString avoids an allocation.) +func (stream *Stream) WriteBytesAsString(b []byte) { + stream.WriteString(*(*string)(unsafe.Pointer(&b))) +} + // WriteString write string to stream without html escape func (stream *Stream) WriteString(s string) { valLen := len(s)