github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/feed/topic.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:44</date> 10 //</624450119541985280> 11 12 13 package feed 14 15 import ( 16 "bytes" 17 "encoding/json" 18 "fmt" 19 20 "github.com/ethereum/go-ethereum/common/bitutil" 21 "github.com/ethereum/go-ethereum/common/hexutil" 22 "github.com/ethereum/go-ethereum/swarm/storage" 23 ) 24 25 //topic length建立主题字符串的最大长度 26 const TopicLength = storage.AddressLength 27 28 //主题表示提要的内容 29 type Topic [TopicLength]byte 30 31 //创建名称/相关内容太长的主题时返回errtopictolong 32 var ErrTopicTooLong = fmt.Errorf("Topic is too long. Max length is %d", TopicLength) 33 34 //new topic从提供的名称和“相关内容”字节数组创建新主题, 35 //将两者合并在一起。 36 //如果RelatedContent或Name长于TopicLength,它们将被截断并返回错误 37 //名称可以是空字符串 38 //相关内容可以为零 39 func NewTopic(name string, relatedContent []byte) (topic Topic, err error) { 40 if relatedContent != nil { 41 contentLength := len(relatedContent) 42 if contentLength > TopicLength { 43 contentLength = TopicLength 44 err = ErrTopicTooLong 45 } 46 copy(topic[:], relatedContent[:contentLength]) 47 } 48 nameBytes := []byte(name) 49 nameLength := len(nameBytes) 50 if nameLength > TopicLength { 51 nameLength = TopicLength 52 err = ErrTopicTooLong 53 } 54 bitutil.XORBytes(topic[:], topic[:], nameBytes[:nameLength]) 55 return topic, err 56 } 57 58 //hex将返回编码为十六进制字符串的主题 59 func (t *Topic) Hex() string { 60 return hexutil.Encode(t[:]) 61 } 62 63 //FromHex将把十六进制字符串解析到此主题实例中 64 func (t *Topic) FromHex(hex string) error { 65 bytes, err := hexutil.Decode(hex) 66 if err != nil || len(bytes) != len(t) { 67 return NewErrorf(ErrInvalidValue, "Cannot decode topic") 68 } 69 copy(t[:], bytes) 70 return nil 71 } 72 73 //name将尝试从主题中提取主题名称 74 func (t *Topic) Name(relatedContent []byte) string { 75 nameBytes := *t 76 if relatedContent != nil { 77 contentLength := len(relatedContent) 78 if contentLength > TopicLength { 79 contentLength = TopicLength 80 } 81 bitutil.XORBytes(nameBytes[:], t[:], relatedContent[:contentLength]) 82 } 83 z := bytes.IndexByte(nameBytes[:], 0) 84 if z < 0 { 85 z = TopicLength 86 } 87 return string(nameBytes[:z]) 88 89 } 90 91 //unmashaljson实现json.unmarshaller接口 92 func (t *Topic) UnmarshalJSON(data []byte) error { 93 var hex string 94 json.Unmarshal(data, &hex) 95 return t.FromHex(hex) 96 } 97 98 //marshaljson实现json.marshaller接口 99 func (t *Topic) MarshalJSON() ([]byte, error) { 100 return json.Marshal(t.Hex()) 101 } 102