1
1
package main
2
2
3
3
import (
4
- "bytes"
5
4
"fmt"
6
5
"os"
7
6
"strings"
8
7
9
8
c "github.com/ipfs/go-cid"
10
9
11
10
mb "github.com/multiformats/go-multibase"
12
- mh "github.com/multiformats/go-multihash"
13
11
)
14
12
15
13
func usage () {
16
14
fmt .Fprintf (os .Stderr , "usage: %s [-b multibase-code] [-v cid-version] <fmt-str> <cid> ...\n \n " , os .Args [0 ])
17
- fmt .Fprintf (os .Stderr , "<fmt-str> is either 'prefix' or a printf style format string:\n %s" , fmtRef )
15
+ fmt .Fprintf (os .Stderr , "<fmt-str> is either 'prefix' or a printf style format string:\n %s" , c . FormatRef )
18
16
os .Exit (2 )
19
17
}
20
18
21
- const fmtRef = `
22
- %% literal %
23
- %b multibase name
24
- %B multibase code
25
- %v version string
26
- %V version number
27
- %c codec name
28
- %C codec code
29
- %h multihash name
30
- %H multihash code
31
- %L hash digest length
32
- %m multihash encoded in base %b (with multibase prefix)
33
- %M multihash encoded in base %b without multibase prefix
34
- %d hash digest encoded in base %b (with multibase prefix)
35
- %D hash digest encoded in base %b without multibase prefix
36
- %s cid string encoded in base %b (1)
37
- %S cid string encoded in base %b without multibase prefix
38
- %P cid prefix: %v-%c-%h-%L
39
-
40
- (1) For CID version 0 the multibase must be base58btc and no prefix is
41
- used. For Cid version 1 the multibase prefix is included.
42
- `
43
-
44
19
func main () {
45
20
if len (os .Args ) < 2 {
46
21
usage ()
94
69
}
95
70
}
96
71
for _ , cidStr := range args [1 :] {
97
- base , cid , err := decode (cidStr )
72
+ base , cid , err := c . DecodeV2 (cidStr )
98
73
if err != nil {
99
74
fmt .Fprintf (os .Stdout , "!INVALID_CID!\n " )
100
75
errorMsg ("%s: %v" , cidStr , err )
@@ -113,9 +88,9 @@ outer:
113
88
continue
114
89
}
115
90
}
116
- str , err := fmtCid (fmtStr , base , cid )
91
+ str , err := c . Format (fmtStr , base , cid )
117
92
switch err .(type ) {
118
- case FormatStringError :
93
+ case c. FormatStringError :
119
94
fmt .Fprintf (os .Stderr , "Error: %v\n " , err )
120
95
os .Exit (2 )
121
96
default :
@@ -140,146 +115,6 @@ func errorMsg(fmtStr string, a ...interface{}) {
140
115
exitCode = 1
141
116
}
142
117
143
- func decode (v string ) (mb.Encoding , * c.Cid , error ) {
144
- if len (v ) < 2 {
145
- return 0 , nil , c .ErrCidTooShort
146
- }
147
-
148
- if len (v ) == 46 && v [:2 ] == "Qm" {
149
- hash , err := mh .FromB58String (v )
150
- if err != nil {
151
- return 0 , nil , err
152
- }
153
-
154
- return mb .Base58BTC , c .NewCidV0 (hash ), nil
155
- }
156
-
157
- base , data , err := mb .Decode (v )
158
- if err != nil {
159
- return 0 , nil , err
160
- }
161
-
162
- cid , err := c .Cast (data )
163
-
164
- return base , cid , err
165
- }
166
-
167
- const ERR_STR = "!ERROR!"
168
-
169
- type FormatStringError struct {
170
- Message string
171
- Specifier string
172
- }
173
-
174
- func (e FormatStringError ) Error () string {
175
- if e .Specifier == "" {
176
- return e .Message
177
- } else {
178
- return fmt .Sprintf ("%s: %s" , e .Message , e .Specifier )
179
- }
180
- }
181
-
182
- func fmtCid (fmtStr string , base mb.Encoding , cid * c.Cid ) (string , error ) {
183
- p := cid .Prefix ()
184
- out := new (bytes.Buffer )
185
- var err error
186
- encoder , err := mb .NewEncoder (base )
187
- if err != nil {
188
- return "" , err
189
- }
190
- for i := 0 ; i < len (fmtStr ); i ++ {
191
- if fmtStr [i ] != '%' {
192
- out .WriteByte (fmtStr [i ])
193
- continue
194
- }
195
- i ++
196
- if i >= len (fmtStr ) {
197
- return "" , FormatStringError {"premature end of format string" , "" }
198
- }
199
- switch fmtStr [i ] {
200
- case '%' :
201
- out .WriteByte ('%' )
202
- case 'b' : // base name
203
- out .WriteString (baseToString (base ))
204
- case 'B' : // base code
205
- out .WriteByte (byte (base ))
206
- case 'v' : // version string
207
- fmt .Fprintf (out , "cidv%d" , p .Version )
208
- case 'V' : // version num
209
- fmt .Fprintf (out , "%d" , p .Version )
210
- case 'c' : // codec name
211
- out .WriteString (codecToString (p .Codec ))
212
- case 'C' : // codec code
213
- fmt .Fprintf (out , "%d" , p .Codec )
214
- case 'h' : // hash fun name
215
- out .WriteString (hashToString (p .MhType ))
216
- case 'H' : // hash fun code
217
- fmt .Fprintf (out , "%d" , p .MhType )
218
- case 'L' : // hash length
219
- fmt .Fprintf (out , "%d" , p .MhLength )
220
- case 'm' , 'M' : // multihash encoded in base %b
221
- out .WriteString (encode (encoder , cid .Hash (), fmtStr [i ] == 'M' ))
222
- case 'd' , 'D' : // hash digest encoded in base %b
223
- dec , err := mh .Decode (cid .Hash ())
224
- if err != nil {
225
- return "" , err
226
- }
227
- out .WriteString (encode (encoder , dec .Digest , fmtStr [i ] == 'D' ))
228
- case 's' : // cid string encoded in base %b
229
- str , err := cid .StringOfBase (base )
230
- if err != nil {
231
- return "" , err
232
- }
233
- out .WriteString (str )
234
- case 'S' : // cid string without base prefix
235
- out .WriteString (encode (encoder , cid .Bytes (), true ))
236
- case 'P' : // prefix
237
- fmt .Fprintf (out , "cidv%d-%s-%s-%d" ,
238
- p .Version ,
239
- codecToString (p .Codec ),
240
- hashToString (p .MhType ),
241
- p .MhLength ,
242
- )
243
- default :
244
- return "" , FormatStringError {"unrecognized specifier in format string" , fmtStr [i - 1 : i + 1 ]}
245
- }
246
-
247
- }
248
- return out .String (), err
249
- }
250
-
251
- func baseToString (base mb.Encoding ) string {
252
- baseStr , ok := mb .EncodingToStr [base ]
253
- if ! ok {
254
- return fmt .Sprintf ("base?%c" , base )
255
- }
256
- return baseStr
257
- }
258
-
259
- func codecToString (num uint64 ) string {
260
- name , ok := c .CodecToStr [num ]
261
- if ! ok {
262
- return fmt .Sprintf ("codec?%d" , num )
263
- }
264
- return name
265
- }
266
-
267
- func hashToString (num uint64 ) string {
268
- name , ok := mh .Codes [num ]
269
- if ! ok {
270
- return fmt .Sprintf ("hash?%d" , num )
271
- }
272
- return name
273
- }
274
-
275
- func encode (base mb.Encoder , data []byte , strip bool ) string {
276
- str := base .Encode (data )
277
- if strip {
278
- return str [1 :]
279
- }
280
- return str
281
- }
282
-
283
118
func toCidV0 (cid * c.Cid ) (* c.Cid , error ) {
284
119
if cid .Type () != c .DagProtobuf {
285
120
return nil , fmt .Errorf ("can't convert non-protobuf nodes to cidv0" )
0 commit comments