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