OSDN Git Service

Wallet store test (#312)
[bytom/vapor.git] / vendor / github.com / tendermint / go-wire / data / bytes.go
1 package data
2
3 import (
4         "encoding/base64"
5         "encoding/hex"
6         "encoding/json"
7         "strings"
8
9         "github.com/pkg/errors"
10 )
11
12 // Encoder is a global setting for all byte encoding
13 // This is the default.  Please override in the main()/init()
14 // of your program to change how byte slices are presented
15 //
16 // In addition to these implementation, you can also find
17 // BTCEncoder and FlickrEncoder that use base58 variants in
18 // github.com/tendermint/go-wire/data/base58
19 var (
20         Encoder       ByteEncoder = hexEncoder{}
21         HexEncoder                = hexEncoder{}
22         B64Encoder                = base64Encoder{base64.URLEncoding}
23         RawB64Encoder             = base64Encoder{base64.RawURLEncoding}
24 )
25
26 // Bytes is a special byte slice that allows us to control the
27 // serialization format per app.
28 //
29 // Thus, basecoin could use hex, another app base64, and a third
30 // app base58...
31 type Bytes []byte
32
33 func (b Bytes) MarshalJSON() ([]byte, error) {
34         return Encoder.Marshal(b)
35 }
36
37 func (b *Bytes) UnmarshalJSON(data []byte) error {
38         ref := (*[]byte)(b)
39         return Encoder.Unmarshal(ref, data)
40 }
41
42 // Allow it to fulfill various interfaces in light-client, etc...
43 func (b Bytes) Bytes() []byte {
44         return b
45 }
46
47 // String gets a simple string for printing (the json output minus quotes)
48 func (b Bytes) String() string {
49         raw, err := Encoder.Marshal(b)
50         l := len(raw)
51         if err != nil || l < 2 {
52                 return "Bytes<?????>"
53         }
54         return string(raw[1 : l-1])
55 }
56
57 // ByteEncoder handles both the marshalling and unmarshalling of
58 // an arbitrary byte slice.
59 //
60 // All Bytes use the global Encoder set in this package.
61 // If you want to use this encoding for byte arrays, you can just
62 // implement a simple custom marshaller for your byte array
63 //
64 //   type Dings [64]byte
65 //
66 //   func (d Dings) MarshalJSON() ([]byte, error) {
67 //     return data.Encoder.Marshal(d[:])
68 //   }
69 //
70 //   func (d *Dings) UnmarshalJSON(enc []byte) error {
71 //     var ref []byte
72 //     err := data.Encoder.Unmarshal(&ref, enc)
73 //     copy(d[:], ref)
74 //     return err
75 //   }
76 type ByteEncoder interface {
77         Marshal(bytes []byte) ([]byte, error)
78         Unmarshal(dst *[]byte, src []byte) error
79 }
80
81 // hexEncoder implements ByteEncoder encoding the slice as a hexidecimal
82 // string
83 type hexEncoder struct{}
84
85 var _ ByteEncoder = hexEncoder{}
86
87 func (_ hexEncoder) Unmarshal(dst *[]byte, src []byte) (err error) {
88         var s string
89         err = json.Unmarshal(src, &s)
90         if err != nil {
91                 return errors.Wrap(err, "parse string")
92         }
93         // and interpret that string as hex
94         *dst, err = hex.DecodeString(s)
95         return err
96 }
97
98 func (_ hexEncoder) Marshal(bytes []byte) ([]byte, error) {
99         s := strings.ToUpper(hex.EncodeToString(bytes))
100         return json.Marshal(s)
101 }
102
103 // base64Encoder implements ByteEncoder encoding the slice as
104 // base64 url-safe encoding
105 type base64Encoder struct {
106         *base64.Encoding
107 }
108
109 var _ ByteEncoder = base64Encoder{}
110
111 func (e base64Encoder) Unmarshal(dst *[]byte, src []byte) (err error) {
112         var s string
113         err = json.Unmarshal(src, &s)
114         if err != nil {
115                 return errors.Wrap(err, "parse string")
116         }
117         *dst, err = e.DecodeString(s)
118         return err
119 }
120
121 func (e base64Encoder) Marshal(bytes []byte) ([]byte, error) {
122         s := e.EncodeToString(bytes)
123         return json.Marshal(s)
124 }