github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/api/uri.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:43</date> 10 //</624450112499748865> 11 12 13 package api 14 15 import ( 16 "fmt" 17 "net/url" 18 "regexp" 19 "strings" 20 21 "github.com/ethereum/go-ethereum/common" 22 "github.com/ethereum/go-ethereum/swarm/storage" 23 ) 24 25 //匹配十六进制群哈希 26 //托多:这很糟糕,不应该硬编码哈希值有多长 27 var hashMatcher = regexp.MustCompile("^([0-9A-Fa-f]{64})([0-9A-Fa-f]{64})?$") 28 29 //URI是对存储在Swarm中的内容的引用。 30 type URI struct { 31 //方案具有以下值之一: 32 // 33 //*BZZ-群清单中的条目 34 //*BZZ原始-原始群内容 35 //*BZZ不可变-群清单中某个条目的不可变URI 36 //(地址未解析) 37 //*BZZ列表-包含在Swarm清单中的所有文件的列表 38 // 39 Scheme string 40 41 //addr是十六进制存储地址,或者是 42 //解析为存储地址 43 Addr string 44 45 //addr存储解析的存储地址 46 addr storage.Address 47 48 //路径是群清单中内容的路径 49 Path string 50 } 51 52 func (u *URI) MarshalJSON() (out []byte, err error) { 53 return []byte(`"` + u.String() + `"`), nil 54 } 55 56 func (u *URI) UnmarshalJSON(value []byte) error { 57 uri, err := Parse(string(value)) 58 if err != nil { 59 return err 60 } 61 *u = *uri 62 return nil 63 } 64 65 //解析将rawuri解析为一个uri结构,其中rawuri应该有一个 66 //以下格式: 67 // 68 //*方案>: 69 //*<scheme>:/<addr> 70 //*<scheme>:/<addr>/<path> 71 //*方案>: 72 //*<scheme>:/<addr> 73 //*<scheme>:/<addr>/<path> 74 // 75 //使用方案一:bzz、bzz raw、bzz immutable、bzz list或bzz hash 76 func Parse(rawuri string) (*URI, error) { 77 u, err := url.Parse(rawuri) 78 if err != nil { 79 return nil, err 80 } 81 uri := &URI{Scheme: u.Scheme} 82 83 //检查方案是否有效 84 switch uri.Scheme { 85 case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzz-hash", "bzz-feed": 86 default: 87 return nil, fmt.Errorf("unknown scheme %q", u.Scheme) 88 } 89 90 //处理类似bzz://<addr>/<path>的uri,其中addr和path 91 //已按URL拆分。分析 92 if u.Host != "" { 93 uri.Addr = u.Host 94 uri.Path = strings.TrimLeft(u.Path, "/") 95 return uri, nil 96 } 97 98 //uri类似于bzz:/<addr>/<path>so split the addr and path from 99 //原始路径(将是/<addr>/<path>) 100 parts := strings.SplitN(strings.TrimLeft(u.Path, "/"), "/", 2) 101 uri.Addr = parts[0] 102 if len(parts) == 2 { 103 uri.Path = parts[1] 104 } 105 return uri, nil 106 } 107 func (u *URI) Feed() bool { 108 return u.Scheme == "bzz-feed" 109 } 110 111 func (u *URI) Raw() bool { 112 return u.Scheme == "bzz-raw" 113 } 114 115 func (u *URI) Immutable() bool { 116 return u.Scheme == "bzz-immutable" 117 } 118 119 func (u *URI) List() bool { 120 return u.Scheme == "bzz-list" 121 } 122 123 func (u *URI) Hash() bool { 124 return u.Scheme == "bzz-hash" 125 } 126 127 func (u *URI) String() string { 128 return u.Scheme + ":/" + u.Addr + "/" + u.Path 129 } 130 131 func (u *URI) Address() storage.Address { 132 if u.addr != nil { 133 return u.addr 134 } 135 if hashMatcher.MatchString(u.Addr) { 136 u.addr = common.Hex2Bytes(u.Addr) 137 return u.addr 138 } 139 return nil 140 } 141