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