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  }