github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/common/sink/zero_copy_source.go (about) 1 package sink 2 3 import ( 4 "encoding/binary" 5 "errors" 6 7 "github.com/sixexorg/magnetic-ring/common" 8 ) 9 10 var ErrIrregularData = errors.New("irregular data") 11 12 type ZeroCopySource struct { 13 s []byte 14 off uint64 // current reading index 15 } 16 17 func (self *ZeroCopySource) RestBytes() []byte { 18 return self.s[self.off:] 19 } 20 21 // Len returns the number of bytes of the unread portion of the 22 // slice. 23 func (self *ZeroCopySource) Len() uint64 { 24 length := uint64(len(self.s)) 25 if self.off >= length { 26 return 0 27 } 28 return length - self.off 29 } 30 31 func (self *ZeroCopySource) Pos() uint64 { 32 return self.off 33 } 34 35 // Size returns the original length of the underlying byte slice. 36 // Size is the number of bytes available for reading via ReadAt. 37 // The returned value is always the same and is not affected by calls 38 // to any other method. 39 func (self *ZeroCopySource) Size() uint64 { return uint64(len(self.s)) } 40 41 // Read implements the io.ZeroCopySource interface. 42 func (self *ZeroCopySource) NextBytes(n uint64) (data []byte, eof bool) { 43 m := uint64(len(self.s)) 44 end, overflow := SafeAdd(self.off, n) 45 if overflow || end > m { 46 end = m 47 eof = true 48 } 49 data = self.s[self.off:end] 50 self.off = end 51 52 return 53 } 54 55 func (self *ZeroCopySource) Skip(n uint64) (eof bool) { 56 m := uint64(len(self.s)) 57 end, overflow := SafeAdd(self.off, n) 58 if overflow || end > m { 59 end = m 60 eof = true 61 } 62 self.off = end 63 64 return 65 } 66 67 // ReadByte implements the io.ByteReader interface. 68 func (self *ZeroCopySource) NextByte() (data byte, eof bool) { 69 if self.off >= uint64(len(self.s)) { 70 return 0, true 71 } 72 73 b := self.s[self.off] 74 self.off++ 75 return b, false 76 } 77 78 func (self *ZeroCopySource) NextUint8() (data uint8, eof bool) { 79 var val byte 80 val, eof = self.NextByte() 81 return uint8(val), eof 82 } 83 84 func (self *ZeroCopySource) NextBool() (data bool, irregular bool, eof bool) { 85 val, eof := self.NextByte() 86 if val == 0 { 87 data = false 88 } else if val == 1 { 89 data = true 90 } else { 91 data = true 92 irregular = true 93 } 94 95 return 96 } 97 98 // Backs up a number of bytes, so that the next call to NextXXX() returns data again 99 // that was already returned by the last call to NextXXX(). 100 func (self *ZeroCopySource) BackUp(n uint64) { 101 self.off -= n 102 } 103 104 func (self *ZeroCopySource) NextUint16() (data uint16, eof bool) { 105 var buf []byte 106 buf, eof = self.NextBytes(2) 107 if eof { 108 return 109 } 110 111 return binary.LittleEndian.Uint16(buf), eof 112 } 113 114 func (self *ZeroCopySource) NextUint32() (data uint32, eof bool) { 115 var buf []byte 116 buf, eof = self.NextBytes(4) 117 if eof { 118 return 119 } 120 121 return binary.LittleEndian.Uint32(buf), eof 122 } 123 124 func (self *ZeroCopySource) NextUint64() (data uint64, eof bool) { 125 var buf []byte 126 buf, eof = self.NextBytes(8) 127 if eof { 128 return 129 } 130 131 return binary.LittleEndian.Uint64(buf), eof 132 } 133 134 func (self *ZeroCopySource) NextInt32() (data int32, eof bool) { 135 var val uint32 136 val, eof = self.NextUint32() 137 return int32(val), eof 138 } 139 140 func (self *ZeroCopySource) NextInt64() (data int64, eof bool) { 141 var val uint64 142 val, eof = self.NextUint64() 143 return int64(val), eof 144 } 145 146 func (self *ZeroCopySource) NextInt16() (data int16, eof bool) { 147 var val uint16 148 val, eof = self.NextUint16() 149 return int16(val), eof 150 } 151 152 func (self *ZeroCopySource) NextVarBytes() (data []byte, size uint64, irregular bool, eof bool) { 153 var count uint64 154 count, size, irregular, eof = self.NextVarUint() 155 size += count 156 157 data, eof = self.NextBytes(count) 158 159 return 160 } 161 162 func (self *ZeroCopySource) NextAddress() (data common.Address, eof bool) { 163 var buf []byte 164 buf, eof = self.NextBytes(common.AddrLength) 165 if eof { 166 return 167 } 168 copy(data[:], buf) 169 return 170 } 171 func (self *ZeroCopySource) NextSymbol() (data common.Symbol, eof bool) { 172 var buf []byte 173 buf, eof = self.NextBytes(common.SymbolLen) 174 if eof { 175 return 176 } 177 copy(data[:], buf) 178 return 179 } 180 181 func (self *ZeroCopySource) NextHash() (data common.Hash, eof bool) { 182 var buf []byte 183 buf, eof = self.NextBytes(common.HashLength) 184 if eof { 185 return 186 } 187 copy(data[:], buf) 188 189 return 190 } 191 192 func (self *ZeroCopySource) NextString() (data string, size uint64, irregular bool, eof bool) { 193 var val []byte 194 val, size, irregular, eof = self.NextVarBytes() 195 data = string(val) 196 return 197 } 198 199 func (self *ZeroCopySource) NextVarUint() (data uint64, size uint64, irregular bool, eof bool) { 200 var fb byte 201 fb, eof = self.NextByte() 202 if eof { 203 return 204 } 205 206 switch fb { 207 case 0xFD: 208 val, e := self.NextUint16() 209 if e { 210 return 211 } 212 data = uint64(val) 213 size = 3 214 case 0xFE: 215 val, e := self.NextUint32() 216 if e { 217 return 218 } 219 data = uint64(val) 220 size = 5 221 case 0xFF: 222 val, e := self.NextUint64() 223 if e { 224 return 225 } 226 data = uint64(val) 227 size = 9 228 default: 229 data = uint64(fb) 230 size = 1 231 } 232 233 irregular = size != getVarUintSize(data) 234 235 return 236 } 237 func (self *ZeroCopySource) NextComplex() (data *ComplexType, eof bool) { 238 data = &ComplexType{} 239 var ( 240 sizeBuf []byte 241 typeBuf byte 242 ) 243 sizeBuf, eof = self.NextBytes(2) 244 if eof { 245 return 246 } 247 data.Size = [2]byte{sizeBuf[0], sizeBuf[1]} 248 typeBuf, eof = self.NextByte() 249 if eof { 250 return 251 } 252 data.MType = typeBuf 253 u16 := common.BytesToUint16(sizeBuf) 254 data.Data, eof = self.NextBytes(uint64(u16)) 255 return 256 } 257 258 func getVarUintSize(value uint64) uint64 { 259 if value < 0xfd { 260 return 1 261 } else if value <= 0xffff { 262 return 3 263 } else if value <= 0xFFFFFFFF { 264 return 5 265 } else { 266 return 9 267 } 268 } 269 270 // NewReader returns a new ZeroCopySource reading from b. 271 func NewZeroCopySource(b []byte) *ZeroCopySource { return &ZeroCopySource{b, 0} }