OSDN Git Service

Merge pull request #31 from Bytom/dev_ipfs_transaction
[bytom/vapor.git] / vendor / github.com / multiformats / go-multiaddr / codec.go
1 package multiaddr
2
3 import (
4         "bytes"
5         "fmt"
6         "strings"
7 )
8
9 func stringToBytes(s string) ([]byte, error) {
10
11         // consume trailing slashes
12         s = strings.TrimRight(s, "/")
13
14         var b bytes.Buffer
15         sp := strings.Split(s, "/")
16
17         if sp[0] != "" {
18                 return nil, fmt.Errorf("invalid multiaddr, must begin with /")
19         }
20
21         // consume first empty elem
22         sp = sp[1:]
23
24         for len(sp) > 0 {
25                 name := sp[0]
26                 p := ProtocolWithName(name)
27                 if p.Code == 0 {
28                         return nil, fmt.Errorf("no protocol with name %s", sp[0])
29                 }
30                 _, _ = b.Write(CodeToVarint(p.Code))
31                 sp = sp[1:]
32
33                 if p.Size == 0 { // no length.
34                         continue
35                 }
36
37                 if len(sp) < 1 {
38                         return nil, fmt.Errorf("protocol requires address, none given: %s", name)
39                 }
40
41                 if p.Path {
42                         // it's a path protocol (terminal).
43                         // consume the rest of the address as the next component.
44                         sp = []string{"/" + strings.Join(sp, "/")}
45                 }
46
47                 a, err := p.Transcoder.StringToBytes(sp[0])
48                 if err != nil {
49                         return nil, fmt.Errorf("failed to parse %s: %s %s", p.Name, sp[0], err)
50                 }
51                 if p.Size < 0 { // varint size.
52                         _, _ = b.Write(CodeToVarint(len(a)))
53                 }
54                 b.Write(a)
55                 sp = sp[1:]
56         }
57
58         return b.Bytes(), nil
59 }
60
61 func validateBytes(b []byte) (err error) {
62         for len(b) > 0 {
63                 code, n, err := ReadVarintCode(b)
64                 if err != nil {
65                         return err
66                 }
67
68                 b = b[n:]
69                 p := ProtocolWithCode(code)
70                 if p.Code == 0 {
71                         return fmt.Errorf("no protocol with code %d", code)
72                 }
73
74                 if p.Size == 0 {
75                         continue
76                 }
77
78                 n, size, err := sizeForAddr(p, b)
79                 if err != nil {
80                         return err
81                 }
82
83                 b = b[n:]
84
85                 if len(b) < size || size < 0 {
86                         return fmt.Errorf("invalid value for size %d", len(b))
87                 }
88
89                 err = p.Transcoder.ValidateBytes(b[:size])
90                 if err != nil {
91                         return err
92                 }
93
94                 b = b[size:]
95         }
96
97         return nil
98 }
99
100 func readComponent(b []byte) (int, Component, error) {
101         var offset int
102         code, n, err := ReadVarintCode(b)
103         if err != nil {
104                 return 0, Component{}, err
105         }
106         offset += n
107
108         p := ProtocolWithCode(code)
109         if p.Code == 0 {
110                 return 0, Component{}, fmt.Errorf("no protocol with code %d", code)
111         }
112
113         if p.Size == 0 {
114                 return offset, Component{
115                         bytes:    b[:offset],
116                         offset:   offset,
117                         protocol: p,
118                 }, nil
119         }
120
121         n, size, err := sizeForAddr(p, b[offset:])
122         if err != nil {
123                 return 0, Component{}, err
124         }
125
126         offset += n
127
128         if len(b[offset:]) < size || size < 0 {
129                 return 0, Component{}, fmt.Errorf("invalid value for size %d", len(b[offset:]))
130         }
131
132         return offset + size, Component{
133                 bytes:    b[:offset+size],
134                 protocol: p,
135                 offset:   offset,
136         }, nil
137 }
138
139 func bytesToString(b []byte) (ret string, err error) {
140         var buf strings.Builder
141
142         for len(b) > 0 {
143                 n, c, err := readComponent(b)
144                 if err != nil {
145                         return "", err
146                 }
147                 b = b[n:]
148                 c.writeTo(&buf)
149         }
150
151         return buf.String(), nil
152 }
153
154 func sizeForAddr(p Protocol, b []byte) (skip, size int, err error) {
155         switch {
156         case p.Size > 0:
157                 return 0, (p.Size / 8), nil
158         case p.Size == 0:
159                 return 0, 0, nil
160         default:
161                 size, n, err := ReadVarintCode(b)
162                 if err != nil {
163                         return 0, 0, err
164                 }
165                 return n, size, nil
166         }
167 }
168
169 func bytesSplit(b []byte) ([][]byte, error) {
170         var ret [][]byte
171         for len(b) > 0 {
172                 code, n, err := ReadVarintCode(b)
173                 if err != nil {
174                         return nil, err
175                 }
176
177                 p := ProtocolWithCode(code)
178                 if p.Code == 0 {
179                         return nil, fmt.Errorf("no protocol with code %d", b[0])
180                 }
181
182                 n2, size, err := sizeForAddr(p, b[n:])
183                 if err != nil {
184                         return nil, err
185                 }
186
187                 length := n + n2 + size
188                 ret = append(ret, b[:length])
189                 b = b[length:]
190         }
191
192         return ret, nil
193 }