github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/feed/feed.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 //</624450118795399168> 11 12 13 package feed 14 15 import ( 16 "hash" 17 "unsafe" 18 19 "github.com/ethereum/go-ethereum/common" 20 "github.com/ethereum/go-ethereum/common/hexutil" 21 "github.com/ethereum/go-ethereum/swarm/storage" 22 ) 23 24 //源表示特定用户对主题的更新流 25 type Feed struct { 26 Topic Topic `json:"topic"` 27 User common.Address `json:"user"` 28 } 29 30 //饲料布局: 31 //TopicLength字节 32 //useraddr common.addresslength字节 33 const feedLength = TopicLength + common.AddressLength 34 35 //mapkey计算此源的唯一ID。由“handler”中的缓存映射使用 36 func (f *Feed) mapKey() uint64 { 37 serializedData := make([]byte, feedLength) 38 f.binaryPut(serializedData) 39 hasher := hashPool.Get().(hash.Hash) 40 defer hashPool.Put(hasher) 41 hasher.Reset() 42 hasher.Write(serializedData) 43 hash := hasher.Sum(nil) 44 return *(*uint64)(unsafe.Pointer(&hash[0])) 45 } 46 47 //BinaryPut将此源实例序列化到提供的切片中 48 func (f *Feed) binaryPut(serializedData []byte) error { 49 if len(serializedData) != feedLength { 50 return NewErrorf(ErrInvalidValue, "Incorrect slice size to serialize feed. Expected %d, got %d", feedLength, len(serializedData)) 51 } 52 var cursor int 53 copy(serializedData[cursor:cursor+TopicLength], f.Topic[:TopicLength]) 54 cursor += TopicLength 55 56 copy(serializedData[cursor:cursor+common.AddressLength], f.User[:]) 57 cursor += common.AddressLength 58 59 return nil 60 } 61 62 //BinaryLength返回序列化时此结构的预期大小 63 func (f *Feed) binaryLength() int { 64 return feedLength 65 } 66 67 //binaryget从传递的切片中包含的信息还原当前实例 68 func (f *Feed) binaryGet(serializedData []byte) error { 69 if len(serializedData) != feedLength { 70 return NewErrorf(ErrInvalidValue, "Incorrect slice size to read feed. Expected %d, got %d", feedLength, len(serializedData)) 71 } 72 73 var cursor int 74 copy(f.Topic[:], serializedData[cursor:cursor+TopicLength]) 75 cursor += TopicLength 76 77 copy(f.User[:], serializedData[cursor:cursor+common.AddressLength]) 78 cursor += common.AddressLength 79 80 return nil 81 } 82 83 //十六进制将提要序列化为十六进制字符串 84 func (f *Feed) Hex() string { 85 serializedData := make([]byte, feedLength) 86 f.binaryPut(serializedData) 87 return hexutil.Encode(serializedData) 88 } 89 90 //FromValues从字符串键值存储中反序列化此实例 91 //用于分析查询字符串 92 func (f *Feed) FromValues(values Values) (err error) { 93 topic := values.Get("topic") 94 if topic != "" { 95 if err := f.Topic.FromHex(values.Get("topic")); err != nil { 96 return err 97 } 98 } else { //查看用户集名称和相关内容 99 name := values.Get("name") 100 relatedContent, _ := hexutil.Decode(values.Get("relatedcontent")) 101 if len(relatedContent) > 0 { 102 if len(relatedContent) < storage.AddressLength { 103 return NewErrorf(ErrInvalidValue, "relatedcontent field must be a hex-encoded byte array exactly %d bytes long", storage.AddressLength) 104 } 105 relatedContent = relatedContent[:storage.AddressLength] 106 } 107 f.Topic, err = NewTopic(name, relatedContent) 108 if err != nil { 109 return err 110 } 111 } 112 f.User = common.HexToAddress(values.Get("user")) 113 return nil 114 } 115 116 //AppendValues将此结构序列化到提供的字符串键值存储区中 117 //用于生成查询字符串 118 func (f *Feed) AppendValues(values Values) { 119 values.Set("topic", f.Topic.Hex()) 120 values.Set("user", f.User.Hex()) 121 } 122