Tao Wen 9 gadi atpakaļ
vecāks
revīzija
90fc0b822f
5 mainītis faili ar 74 papildinājumiem un 12 dzēšanām
  1. 5 10
      feature_reflect.go
  2. 42 0
      feature_reflect_array.go
  3. 1 2
      feature_reflect_object.go
  4. 16 0
      jsoniter_array_test.go
  5. 10 0
      stream.go

+ 5 - 10
feature_reflect.go

@@ -359,7 +359,7 @@ func decoderOfType(typ reflect.Type) (Decoder, error) {
 	case reflect.Interface:
 		return &interfaceDecoder{}, nil
 	case reflect.Struct:
-		return decoderOfStruct(typ)
+		return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(typ))
 	case reflect.Slice:
 		return prefix("[slice]").addToDecoder(decoderOfSlice(typ))
 	case reflect.Map:
@@ -374,6 +374,7 @@ func decoderOfType(typ reflect.Type) (Decoder, error) {
 
 
 func encoderOfType(typ reflect.Type) (Encoder, error) {
+	typeName := typ.String()
 	switch typ.Kind() {
 	case reflect.String:
 		return &stringCodec{}, nil
@@ -404,7 +405,9 @@ func encoderOfType(typ reflect.Type) (Encoder, error) {
 	case reflect.Bool:
 		return &boolCodec{}, nil
 	case reflect.Struct:
-		return encoderOfStruct(typ)
+		return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(typ))
+	case reflect.Slice:
+		return prefix("[slice]").addToEncoder(encoderOfSlice(typ))
 	default:
 		return nil, fmt.Errorf("unsupported type: %v", typ)
 	}
@@ -418,14 +421,6 @@ func decoderOfOptional(typ reflect.Type) (Decoder, error) {
 	return &optionalDecoder{typ, decoder}, nil
 }
 
-func decoderOfSlice(typ reflect.Type) (Decoder, error) {
-	decoder, err := decoderOfType(typ.Elem())
-	if err != nil {
-		return nil, err
-	}
-	return &sliceDecoder{typ, typ.Elem(), decoder}, nil
-}
-
 func decoderOfMap(typ reflect.Type) (Decoder, error) {
 	decoder, err := decoderOfType(typ.Elem())
 	if err != nil {

+ 42 - 0
feature_reflect_array.go

@@ -7,6 +7,48 @@ import (
 	"fmt"
 )
 
+func decoderOfSlice(typ reflect.Type) (Decoder, error) {
+	decoder, err := decoderOfType(typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	return &sliceDecoder{typ, typ.Elem(), decoder}, nil
+}
+
+func encoderOfSlice(typ reflect.Type) (Encoder, error) {
+	encoder, err := encoderOfType(typ.Elem())
+	if err != nil {
+		return nil, err
+	}
+	return &sliceEncoder{typ, typ.Elem(), encoder}, nil
+}
+
+type sliceEncoder struct {
+	sliceType   reflect.Type
+	elemType    reflect.Type
+	elemEncoder Encoder
+}
+
+func (encoder *sliceEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
+	slice := (*sliceHeader)(ptr)
+	if slice.Len == 0 {
+		stream.WriteEmptyArray()
+		return
+	}
+	stream.WriteArrayStart()
+	elemPtr := uintptr(slice.Data)
+	encoder.elemEncoder.encode(unsafe.Pointer(elemPtr), stream)
+	for i := 1; i < slice.Len; i++ {
+		stream.WriteMore()
+		elemPtr += encoder.elemType.Size()
+		encoder.elemEncoder.encode(unsafe.Pointer(elemPtr), stream)
+	}
+	stream.WriteArrayEnd()
+	if stream.Error != nil && stream.Error != io.EOF {
+		stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
+	}
+}
+
 type sliceDecoder struct {
 	sliceType   reflect.Type
 	elemType    reflect.Type

+ 1 - 2
feature_reflect_object.go

@@ -415,6 +415,5 @@ type emptyStructEncoder struct {
 }
 
 func (encoder *emptyStructEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
-	stream.WriteObjectStart()
-	stream.WriteObjectEnd()
+	stream.WriteEmptyObject()
 }

+ 16 - 0
jsoniter_array_test.go

@@ -134,6 +134,22 @@ func Test_write_array(t *testing.T) {
 	should.Equal("[\n  1,\n  2\n]", buf.String())
 }
 
+func Test_write_val_array(t *testing.T) {
+	should := require.New(t)
+	val := []int{1,2,3}
+	str, err := MarshalToString(val)
+	should.Nil(err)
+	should.Equal("[1,2,3]", str)
+}
+
+func Test_write_val_empty_array(t *testing.T) {
+	should := require.New(t)
+	val := []int{}
+	str, err := MarshalToString(val)
+	should.Nil(err)
+	should.Equal("[]", str)
+}
+
 func Benchmark_jsoniter_array(b *testing.B) {
 	b.ReportAllocs()
 	input := []byte(`[1,2,3,4,5,6,7,8,9]`)

+ 10 - 0
stream.go

@@ -171,6 +171,11 @@ func (stream *Stream) WriteObjectEnd() {
 	stream.writeByte('}')
 }
 
+func (stream *Stream) WriteEmptyObject() {
+	stream.writeByte('{')
+	stream.writeByte('}')
+}
+
 func (stream *Stream) WriteMore() {
 	stream.writeByte(',')
 	stream.writeIndention(0)
@@ -182,6 +187,11 @@ func (stream *Stream) WriteArrayStart() {
 	stream.writeIndention(0)
 }
 
+func (stream *Stream) WriteEmptyArray() {
+	stream.writeByte('[')
+	stream.writeByte(']')
+}
+
 func (stream *Stream) WriteArrayEnd() {
 	stream.writeIndention(stream.IndentionStep)
 	stream.indention -= stream.IndentionStep