github.com/alexdevranger/node-1.8.27@v0.0.0-20221128213301-aa5841e41d2d/swarm/storage/feed/update.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-dubxcoin library. 3 // 4 // The go-dubxcoin library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-dubxcoin library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-dubxcoin library. If not, see <http://www.gnu.org/licenses/>. 16 17 package feed 18 19 import ( 20 "fmt" 21 "strconv" 22 23 "github.com/alexdevranger/node-1.8.27/swarm/chunk" 24 ) 25 26 // ProtocolVersion defines the current version of the protocol that will be included in each update message 27 const ProtocolVersion uint8 = 0 28 29 const headerLength = 8 30 31 // Header defines a update message header including a protocol version byte 32 type Header struct { 33 Version uint8 // Protocol version 34 Padding [headerLength - 1]uint8 // reserved for future use 35 } 36 37 // Update encapsulates the information sent as part of a feed update 38 type Update struct { 39 Header Header // 40 ID // Feed Update identifying information 41 data []byte // actual data payload 42 } 43 44 const minimumUpdateDataLength = idLength + headerLength + 1 45 46 //MaxUpdateDataLength indicates the maximum payload size for a feed update 47 const MaxUpdateDataLength = chunk.DefaultSize - signatureLength - idLength - headerLength 48 49 // binaryPut serializes the feed update information into the given slice 50 func (r *Update) binaryPut(serializedData []byte) error { 51 datalength := len(r.data) 52 if datalength == 0 { 53 return NewError(ErrInvalidValue, "a feed update must contain data") 54 } 55 56 if datalength > MaxUpdateDataLength { 57 return NewErrorf(ErrInvalidValue, "feed update data is too big (length=%d). Max length=%d", datalength, MaxUpdateDataLength) 58 } 59 60 if len(serializedData) != r.binaryLength() { 61 return NewErrorf(ErrInvalidValue, "slice passed to putBinary must be of exact size. Expected %d bytes", r.binaryLength()) 62 } 63 64 var cursor int 65 // serialize Header 66 serializedData[cursor] = r.Header.Version 67 copy(serializedData[cursor+1:headerLength], r.Header.Padding[:headerLength-1]) 68 cursor += headerLength 69 70 // serialize ID 71 if err := r.ID.binaryPut(serializedData[cursor : cursor+idLength]); err != nil { 72 return err 73 } 74 cursor += idLength 75 76 // add the data 77 copy(serializedData[cursor:], r.data) 78 cursor += datalength 79 80 return nil 81 } 82 83 // binaryLength returns the expected number of bytes this structure will take to encode 84 func (r *Update) binaryLength() int { 85 return idLength + headerLength + len(r.data) 86 } 87 88 // binaryGet populates this instance from the information contained in the passed byte slice 89 func (r *Update) binaryGet(serializedData []byte) error { 90 if len(serializedData) < minimumUpdateDataLength { 91 return NewErrorf(ErrNothingToReturn, "chunk less than %d bytes cannot be a feed update chunk", minimumUpdateDataLength) 92 } 93 dataLength := len(serializedData) - idLength - headerLength 94 // at this point we can be satisfied that we have the correct data length to read 95 96 var cursor int 97 98 // deserialize Header 99 r.Header.Version = serializedData[cursor] // extract the protocol version 100 copy(r.Header.Padding[:headerLength-1], serializedData[cursor+1:headerLength]) // extract the padding 101 cursor += headerLength 102 103 if err := r.ID.binaryGet(serializedData[cursor : cursor+idLength]); err != nil { 104 return err 105 } 106 cursor += idLength 107 108 data := serializedData[cursor : cursor+dataLength] 109 cursor += dataLength 110 111 // now that all checks have passed, copy data into structure 112 r.data = make([]byte, dataLength) 113 copy(r.data, data) 114 115 return nil 116 117 } 118 119 // FromValues deserializes this instance from a string key-value store 120 // useful to parse query strings 121 func (r *Update) FromValues(values Values, data []byte) error { 122 r.data = data 123 version, _ := strconv.ParseUint(values.Get("protocolVersion"), 10, 32) 124 r.Header.Version = uint8(version) 125 return r.ID.FromValues(values) 126 } 127 128 // AppendValues serializes this structure into the provided string key-value store 129 // useful to build query strings 130 func (r *Update) AppendValues(values Values) []byte { 131 r.ID.AppendValues(values) 132 values.Set("protocolVersion", fmt.Sprintf("%d", r.Header.Version)) 133 return r.data 134 }