Permalink
Browse files

array encoder

  • Loading branch information...
1 parent 552afb3 commit 90fc0b822fa49cb2db163f017f3dcd00919a0038 @taowen taowen committed Jan 9, 2017
Showing with 74 additions and 12 deletions.
  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
View
@@ -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 {
@@ -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
@@ -415,6 +415,5 @@ type emptyStructEncoder struct {
}
func (encoder *emptyStructEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
- stream.WriteObjectStart()
- stream.WriteObjectEnd()
+ stream.WriteEmptyObject()
}
@@ -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]`)
View
@@ -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

0 comments on commit 90fc0b8

Please sign in to comment.