github.com/iDigitalFlame/xmt@v0.5.4/data/chunk_reader.go (about) 1 // Copyright (C) 2020 - 2023 iDigitalFlame 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 // 16 17 package data 18 19 import "io" 20 21 // Int reads the value from the Chunk payload buffer. 22 func (c *Chunk) Int() (int, error) { 23 v, err := c.Uint64() 24 if err != nil { 25 return 0, err 26 } 27 return int(v), nil 28 } 29 30 // Uint reads the value from the Chunk payload buffer. 31 func (c *Chunk) Uint() (uint, error) { 32 v, err := c.Uint64() 33 if err != nil { 34 return 0, err 35 } 36 return uint(v), nil 37 } 38 39 // Bool reads the value from the Chunk payload buffer. 40 func (c *Chunk) Bool() (bool, error) { 41 v, err := c.Uint8() 42 if err != nil { 43 return false, err 44 } 45 return v == 1, nil 46 } 47 48 // Int8 reads the value from the Chunk payload buffer. 49 func (c *Chunk) Int8() (int8, error) { 50 v, err := c.Uint8() 51 if err != nil { 52 return 0, err 53 } 54 return int8(v), nil 55 } 56 57 // ReadInt reads the value from the Chunk payload buffer into the provided pointer. 58 func (c *Chunk) ReadInt(p *int) error { 59 v, err := c.Int() 60 if err != nil { 61 return err 62 } 63 *p = v 64 return nil 65 } 66 67 // Int16 reads the value from the Chunk payload buffer. 68 func (c *Chunk) Int16() (int16, error) { 69 v, err := c.Uint16() 70 if err != nil { 71 return 0, err 72 } 73 return int16(v), nil 74 } 75 76 // Int32 reads the value from the Chunk payload buffer. 77 func (c *Chunk) Int32() (int32, error) { 78 v, err := c.Uint32() 79 if err != nil { 80 return 0, err 81 } 82 return int32(v), nil 83 } 84 85 // Int64 reads the value from the Chunk payload buffer. 86 func (c *Chunk) Int64() (int64, error) { 87 v, err := c.Uint64() 88 if err != nil { 89 return 0, err 90 } 91 return int64(v), nil 92 } 93 94 // Uint8 reads the value from the Chunk payload buffer. 95 func (c *Chunk) Uint8() (uint8, error) { 96 if c.checkBounds(1) { 97 return 0, io.EOF 98 } 99 v := c.buf[c.rpos] 100 c.rpos++ 101 return v, nil 102 } 103 104 // Bytes reads the value from the Chunk payload buffer. 105 func (c *Chunk) Bytes() ([]byte, error) { 106 t, err := c.Uint8() 107 if err != nil { 108 return nil, err 109 } 110 var l uint64 111 switch t { 112 case 0: 113 return nil, nil 114 case 1, 2: 115 n, err2 := c.Uint8() 116 if err2 != nil { 117 return nil, err2 118 } 119 l = uint64(n) 120 case 3, 4: 121 n, err2 := c.Uint16() 122 if err2 != nil { 123 return nil, err2 124 } 125 l = uint64(n) 126 case 5, 6: 127 n, err2 := c.Uint32() 128 if err2 != nil { 129 return nil, err2 130 } 131 l = uint64(n) 132 case 7, 8: 133 n, err2 := c.Uint64() 134 if err2 != nil { 135 return nil, err2 136 } 137 l = n 138 default: 139 return nil, ErrInvalidType 140 } 141 if l == 0 { 142 // NOTE(dij): Technically we should return (nil, nil) 143 // But! Our spec states that 0 size should be ID:0 144 // NOT ID:0,SIZE:0. So something made a fucky wucky here. 145 return nil, io.ErrUnexpectedEOF 146 } 147 if l > MaxSlice { 148 return nil, ErrTooLarge 149 } 150 // NOTE(dij): This looks like an awesome optimization, we reslice instead of 151 // allocating and writing a new slice. 152 if n := c.Size(); n < c.rpos+int(l) { 153 o := c.buf[c.rpos:] 154 c.rpos = n 155 return o, io.EOF 156 } 157 o := c.buf[c.rpos : uint64(c.rpos)+l] 158 c.rpos += int(l) 159 return o, nil 160 } 161 162 // ReadUint reads the value from the Chunk payload buffer into the provided pointer. 163 func (c *Chunk) ReadUint(p *uint) error { 164 v, err := c.Uint() 165 if err != nil { 166 return err 167 } 168 *p = v 169 return nil 170 } 171 172 // ReadInt8 reads the value from the Chunk payload buffer into the provided pointer. 173 func (c *Chunk) ReadInt8(p *int8) error { 174 v, err := c.Int8() 175 if err != nil { 176 return err 177 } 178 *p = v 179 return nil 180 } 181 182 // ReadBool reads the value from the Chunk payload buffer into the provided pointer. 183 func (c *Chunk) ReadBool(p *bool) error { 184 v, err := c.Bool() 185 if err != nil { 186 return err 187 } 188 *p = v 189 return nil 190 } 191 192 // Uint16 reads the value from the Chunk payload buffer. 193 func (c *Chunk) Uint16() (uint16, error) { 194 if c.checkBounds(2) { 195 return 0, io.EOF 196 } 197 _ = c.buf[c.rpos+1] 198 v := uint16(c.buf[c.rpos+1]) | uint16(c.buf[c.rpos])<<8 199 c.rpos += 2 200 return v, nil 201 } 202 203 // Uint32 reads the value from the Chunk payload buffer. 204 func (c *Chunk) Uint32() (uint32, error) { 205 if c.checkBounds(4) { 206 return 0, io.EOF 207 } 208 _ = c.buf[c.rpos+3] 209 v := uint32(c.buf[c.rpos+3]) | uint32(c.buf[c.rpos+2])<<8 | uint32(c.buf[c.rpos+1])<<16 | uint32(c.buf[c.rpos])<<24 210 c.rpos += 4 211 return v, nil 212 } 213 214 // Uint64 reads the value from the Chunk payload buffer. 215 func (c *Chunk) Uint64() (uint64, error) { 216 if c.checkBounds(8) { 217 return 0, io.EOF 218 } 219 _ = c.buf[c.rpos+7] 220 v := uint64(c.buf[c.rpos+7]) | uint64(c.buf[c.rpos+6])<<8 | uint64(c.buf[c.rpos+5])<<16 | uint64(c.buf[c.rpos+4])<<24 | 221 uint64(c.buf[c.rpos+3])<<32 | uint64(c.buf[c.rpos+2])<<40 | uint64(c.buf[c.rpos+1])<<48 | uint64(c.buf[c.rpos])<<56 222 c.rpos += 8 223 return v, nil 224 } 225 226 // ReadInt16 reads the value from the Chunk payload buffer into the provided pointer. 227 func (c *Chunk) ReadInt16(p *int16) error { 228 v, err := c.Int16() 229 if err != nil { 230 return err 231 } 232 *p = v 233 return nil 234 } 235 236 // ReadInt32 reads the value from the Chunk payload buffer into the provided pointer. 237 func (c *Chunk) ReadInt32(p *int32) error { 238 v, err := c.Int32() 239 if err != nil { 240 return err 241 } 242 *p = v 243 return nil 244 } 245 246 // ReadInt64 reads the value from the Chunk payload buffer into the provided pointer. 247 func (c *Chunk) ReadInt64(p *int64) error { 248 v, err := c.Int64() 249 if err != nil { 250 return err 251 } 252 *p = v 253 return nil 254 } 255 256 // ReadUint8 reads the value from the Chunk payload buffer into the provided pointer. 257 func (c *Chunk) ReadUint8(p *uint8) error { 258 v, err := c.Uint8() 259 if err != nil { 260 return err 261 } 262 *p = v 263 return nil 264 } 265 266 // Float32 reads the value from the Chunk payload buffer. 267 func (c *Chunk) Float32() (float32, error) { 268 v, err := c.Uint32() 269 if err != nil { 270 return 0, nil 271 } 272 return float32FromInt(v), nil 273 } 274 275 // Float64 reads the value from the Chunk payload buffer. 276 func (c *Chunk) Float64() (float64, error) { 277 v, err := c.Uint64() 278 if err != nil { 279 return 0, nil 280 } 281 return float64FromInt(v), nil 282 } 283 284 // ReadBytes reads the value from the Chunk payload buffer. 285 func (c *Chunk) ReadBytes(p *[]byte) error { 286 v, err := c.Bytes() 287 if err != nil { 288 return err 289 } 290 *p = v 291 return nil 292 } 293 294 // StringVal reads the value from the Chunk payload buffer. 295 func (c *Chunk) StringVal() (string, error) { 296 b, err := c.Bytes() 297 if err != nil { 298 return "", err 299 } 300 return string(b), nil 301 } 302 303 // ReadUint16 reads the value from the Chunk payload buffer into the provided pointer. 304 func (c *Chunk) ReadUint16(p *uint16) error { 305 v, err := c.Uint16() 306 if err != nil { 307 return err 308 } 309 *p = v 310 return nil 311 } 312 313 // ReadUint32 reads the value from the Chunk payload buffer into the provided pointer. 314 func (c *Chunk) ReadUint32(p *uint32) error { 315 v, err := c.Uint32() 316 if err != nil { 317 return err 318 } 319 *p = v 320 return nil 321 } 322 323 // ReadUint64 reads the value from the Chunk payload buffer into the provided pointer. 324 func (c *Chunk) ReadUint64(p *uint64) error { 325 v, err := c.Uint64() 326 if err != nil { 327 return err 328 } 329 *p = v 330 return nil 331 } 332 333 // ReadString reads the value from the Chunk payload buffer into the provided pointer. 334 func (c *Chunk) ReadString(p *string) error { 335 v, err := c.StringVal() 336 if err != nil { 337 return err 338 } 339 *p = v 340 return nil 341 } 342 343 // ReadFloat32 reads the value from the Chunk payload buffer into the provided pointer. 344 func (c *Chunk) ReadFloat32(p *float32) error { 345 v, err := c.Float32() 346 if err != nil { 347 return err 348 } 349 *p = v 350 return nil 351 } 352 353 // ReadFloat64 reads the value from the Chunk payload buffer into the provided pointer. 354 func (c *Chunk) ReadFloat64(p *float64) error { 355 v, err := c.Float64() 356 if err != nil { 357 return err 358 } 359 *p = v 360 return nil 361 }