github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/storage/feed/update.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 //</624450119634259968> 11 12 13 package feed 14 15 import ( 16 "fmt" 17 "strconv" 18 19 "github.com/ethereum/go-ethereum/swarm/chunk" 20 ) 21 22 //ProtocolVersion定义将包含在每个更新消息中的协议的当前版本 23 const ProtocolVersion uint8 = 0 24 25 const headerLength = 8 26 27 //header定义包含协议版本字节的更新消息头 28 type Header struct { 29 Version uint8 //协议版本 30 Padding [headerLength - 1]uint8 //留作将来使用 31 } 32 33 //更新将作为源更新的一部分发送的信息封装起来。 34 type Update struct { 35 Header Header // 36 ID //源更新识别信息 37 data []byte //实际数据负载 38 } 39 40 const minimumUpdateDataLength = idLength + headerLength + 1 41 42 //maxupdatedatalength指示源更新的最大负载大小 43 const MaxUpdateDataLength = chunk.DefaultSize - signatureLength - idLength - headerLength 44 45 //BinaryPut将源更新信息序列化到给定切片中 46 func (r *Update) binaryPut(serializedData []byte) error { 47 datalength := len(r.data) 48 if datalength == 0 { 49 return NewError(ErrInvalidValue, "a feed update must contain data") 50 } 51 52 if datalength > MaxUpdateDataLength { 53 return NewErrorf(ErrInvalidValue, "feed update data is too big (length=%d). Max length=%d", datalength, MaxUpdateDataLength) 54 } 55 56 if len(serializedData) != r.binaryLength() { 57 return NewErrorf(ErrInvalidValue, "slice passed to putBinary must be of exact size. Expected %d bytes", r.binaryLength()) 58 } 59 60 var cursor int 61 //序列化头 62 serializedData[cursor] = r.Header.Version 63 copy(serializedData[cursor+1:headerLength], r.Header.Padding[:headerLength-1]) 64 cursor += headerLength 65 66 //序列化ID 67 if err := r.ID.binaryPut(serializedData[cursor : cursor+idLength]); err != nil { 68 return err 69 } 70 cursor += idLength 71 72 //添加数据 73 copy(serializedData[cursor:], r.data) 74 cursor += datalength 75 76 return nil 77 } 78 79 //BinaryLength返回此结构编码所需的字节数。 80 func (r *Update) binaryLength() int { 81 return idLength + headerLength + len(r.data) 82 } 83 84 //binaryget从传递的字节片中包含的信息填充此实例 85 func (r *Update) binaryGet(serializedData []byte) error { 86 if len(serializedData) < minimumUpdateDataLength { 87 return NewErrorf(ErrNothingToReturn, "chunk less than %d bytes cannot be a feed update chunk", minimumUpdateDataLength) 88 } 89 dataLength := len(serializedData) - idLength - headerLength 90 //此时,我们可以确信我们有正确的数据长度来读取 91 92 var cursor int 93 94 //反序列化头 95 r.Header.Version = serializedData[cursor] //提取协议版本 96 copy(r.Header.Padding[:headerLength-1], serializedData[cursor+1:headerLength]) //提取填充物 97 cursor += headerLength 98 99 if err := r.ID.binaryGet(serializedData[cursor : cursor+idLength]); err != nil { 100 return err 101 } 102 cursor += idLength 103 104 data := serializedData[cursor : cursor+dataLength] 105 cursor += dataLength 106 107 //既然所有检查都通过了,那么就将数据复制到结构中。 108 r.data = make([]byte, dataLength) 109 copy(r.data, data) 110 111 return nil 112 113 } 114 115 //FromValues从字符串键值存储中反序列化此实例 116 //用于分析查询字符串 117 func (r *Update) FromValues(values Values, data []byte) error { 118 r.data = data 119 version, _ := strconv.ParseUint(values.Get("protocolVersion"), 10, 32) 120 r.Header.Version = uint8(version) 121 return r.ID.FromValues(values) 122 } 123 124 //AppendValues将此结构序列化到提供的字符串键值存储区中 125 //用于生成查询字符串 126 func (r *Update) AppendValues(values Values) []byte { 127 r.ID.AppendValues(values) 128 values.Set("protocolVersion", fmt.Sprintf("%d", r.Header.Version)) 129 return r.data 130 } 131