github.com/chain5j/chain5j-pkg@v1.0.7/codec/json/json.go (about) 1 package json 2 3 import ( 4 "io" 5 "math/big" 6 "strings" 7 "unsafe" 8 9 "github.com/chain5j/chain5j-pkg/util/hexutil" 10 "github.com/json-iterator/go" 11 ) 12 13 func init() { 14 jsoniter.RegisterTypeEncoder("[]uint8", &byteCodec{}) 15 jsoniter.RegisterTypeDecoder("[]uint8", &byteCodec{}) 16 jsoniter.RegisterTypeEncoder("big.Int", &bigIntCodec{}) 17 jsoniter.RegisterTypeDecoder("big.Int", &bigIntCodec{}) 18 } 19 20 func Marshal(v interface{}) ([]byte, error) { 21 return jsoniter.Marshal(v) 22 } 23 24 func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { 25 return jsoniter.MarshalIndent(v, prefix, indent) 26 } 27 28 func Unmarshal(data []byte, v interface{}) error { 29 return jsoniter.Unmarshal(data, v) 30 } 31 32 func NewDecoder(r io.Reader) *jsoniter.Decoder { 33 return jsoniter.NewDecoder(r) 34 } 35 36 type byteCodec struct{} 37 38 func (codec *byteCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) { 39 b := *((*[]byte)(ptr)) 40 41 stream.WriteString(hexutil.Encode(b)) 42 } 43 44 func (codec *byteCodec) IsEmpty(ptr unsafe.Pointer) bool { 45 b := *((*[]byte)(ptr)) 46 47 return len(b) == 0 48 } 49 50 func (codec *byteCodec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 51 hex := iter.ReadString() 52 53 b, err := hexutil.Decode(hex) 54 if err != nil { 55 return 56 } 57 *((*[]byte)(ptr)) = b 58 } 59 60 type bigIntCodec struct{} 61 62 func (codec *bigIntCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) { 63 i := *((*big.Int)(ptr)) 64 65 stream.WriteString(hexutil.EncodeBig(&i)) 66 } 67 68 func (codec *bigIntCodec) IsEmpty(ptr unsafe.Pointer) bool { 69 70 return false 71 } 72 73 func (codec *bigIntCodec) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { 74 result := new(big.Int) 75 76 any := iter.ReadAny() 77 valueType := any.ValueType() 78 switch valueType { 79 case jsoniter.StringValue: 80 str := any.ToString() 81 if !strings.HasPrefix(str, "0x") { 82 result.UnmarshalText([]byte(str)) 83 *((*big.Int)(ptr)) = *result 84 return 85 } 86 result, err := hexutil.DecodeBig(str) 87 if err != nil { 88 return 89 } 90 91 *((*big.Int)(ptr)) = *result 92 break 93 case jsoniter.NumberValue: 94 num := any.ToInt64() 95 result = big.NewInt(num) 96 *((*big.Int)(ptr)) = *result 97 break 98 } 99 }