|
@@ -0,0 +1,134 @@
|
|
|
|
|
+package jsoniter
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "github.com/v2pro/plz/reflect2"
|
|
|
|
|
+ "unsafe"
|
|
|
|
|
+ "encoding"
|
|
|
|
|
+ "encoding/json"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+type marshalerEncoder struct {
|
|
|
|
|
+ checkIsEmpty checkIsEmpty
|
|
|
|
|
+ valType reflect2.Type
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
|
|
|
+ obj := encoder.valType.UnsafeIndirect(ptr)
|
|
|
|
|
+ if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
|
|
|
|
|
+ stream.WriteNil()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ marshaler := obj.(json.Marshaler)
|
|
|
|
|
+ bytes, err := marshaler.MarshalJSON()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ stream.Error = err
|
|
|
|
|
+ } else {
|
|
|
|
|
+ stream.Write(bytes)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
|
|
|
+ return encoder.checkIsEmpty.IsEmpty(ptr)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type directMarshalerEncoder struct {
|
|
|
|
|
+ checkIsEmpty checkIsEmpty
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
|
|
|
+ marshaler := *(*json.Marshaler)(ptr)
|
|
|
|
|
+ if marshaler == nil {
|
|
|
|
|
+ stream.WriteNil()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ bytes, err := marshaler.MarshalJSON()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ stream.Error = err
|
|
|
|
|
+ } else {
|
|
|
|
|
+ stream.Write(bytes)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
|
|
|
+ return encoder.checkIsEmpty.IsEmpty(ptr)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type textMarshalerEncoder struct {
|
|
|
|
|
+ valType reflect2.Type
|
|
|
|
|
+ checkIsEmpty checkIsEmpty
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
|
|
|
+ obj := encoder.valType.UnsafeIndirect(ptr)
|
|
|
|
|
+ if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
|
|
|
|
|
+ stream.WriteNil()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ marshaler := (obj).(encoding.TextMarshaler)
|
|
|
|
|
+ bytes, err := marshaler.MarshalText()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ stream.Error = err
|
|
|
|
|
+ } else {
|
|
|
|
|
+ stream.WriteString(string(bytes))
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
|
|
|
+ return encoder.checkIsEmpty.IsEmpty(ptr)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type directTextMarshalerEncoder struct {
|
|
|
|
|
+ checkIsEmpty checkIsEmpty
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|
|
|
|
+ marshaler := *(*encoding.TextMarshaler)(ptr)
|
|
|
|
|
+ if marshaler == nil {
|
|
|
|
|
+ stream.WriteNil()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ bytes, err := marshaler.MarshalText()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ stream.Error = err
|
|
|
|
|
+ } else {
|
|
|
|
|
+ stream.WriteString(string(bytes))
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|
|
|
|
+ return encoder.checkIsEmpty.IsEmpty(ptr)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type unmarshalerDecoder struct {
|
|
|
|
|
+ templateInterface emptyInterface
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
|
+ templateInterface := decoder.templateInterface
|
|
|
|
|
+ templateInterface.word = ptr
|
|
|
|
|
+ realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
|
|
|
|
|
+ unmarshaler := (*realInterface).(json.Unmarshaler)
|
|
|
|
|
+ iter.nextToken()
|
|
|
|
|
+ iter.unreadByte() // skip spaces
|
|
|
|
|
+ bytes := iter.SkipAndReturnBytes()
|
|
|
|
|
+ err := unmarshaler.UnmarshalJSON(bytes)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ iter.ReportError("unmarshalerDecoder", err.Error())
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type textUnmarshalerDecoder struct {
|
|
|
|
|
+ templateInterface emptyInterface
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|
|
|
|
+ templateInterface := decoder.templateInterface
|
|
|
|
|
+ templateInterface.word = ptr
|
|
|
|
|
+ realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
|
|
|
|
|
+ unmarshaler := (*realInterface).(encoding.TextUnmarshaler)
|
|
|
|
|
+ str := iter.ReadString()
|
|
|
|
|
+ err := unmarshaler.UnmarshalText([]byte(str))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ iter.ReportError("textUnmarshalerDecoder", err.Error())
|
|
|
|
|
+ }
|
|
|
|
|
+}
|