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