github.com/iDigitalFlame/xmt@v0.5.4/data/chunk_writer.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 // WriteInt writes the supplied value to the Chunk payload buffer. 22 // 23 // If this function returns 'ErrLimit' this indicates that the write was NOT 24 // preformed. 25 func (c *Chunk) WriteInt(n int) error { 26 return c.WriteUint64(uint64(n)) 27 } 28 29 // WriteUint writes the supplied value to the Chunk payload buffer. 30 // 31 // If this function returns 'ErrLimit' this indicates that the write was NOT 32 // preformed. 33 func (c *Chunk) WriteUint(n uint) error { 34 return c.WriteUint64(uint64(n)) 35 } 36 37 // WriteInt8 writes the supplied value to the Chunk payload buffer. 38 // 39 // If this function returns 'ErrLimit' this indicates that the write was NOT 40 // preformed. 41 func (c *Chunk) WriteInt8(n int8) error { 42 return c.WriteUint8(uint8(n)) 43 } 44 45 // WriteBool writes the supplied value to the Chunk payload buffer. 46 // 47 // If this function returns 'ErrLimit' this indicates that the write was NOT 48 // preformed. 49 func (c *Chunk) WriteBool(b bool) error { 50 if b { 51 return c.WriteUint8(1) 52 } 53 return c.WriteUint8(0) 54 } 55 56 // WriteInt16 writes the supplied value to the Chunk payload buffer. 57 // 58 // If this function returns 'ErrLimit' this indicates that the write was NOT 59 // preformed. 60 func (c *Chunk) WriteInt16(n int16) error { 61 return c.WriteUint16(uint16(n)) 62 } 63 64 // WriteInt32 writes the supplied value to the Chunk payload buffer. 65 // 66 // If this function returns 'ErrLimit' this indicates that the write was NOT 67 // preformed. 68 func (c *Chunk) WriteInt32(n int32) error { 69 return c.WriteUint32(uint32(n)) 70 } 71 72 // WriteInt64 writes the supplied value to the Chunk payload buffer. 73 // 74 // If this function returns 'ErrLimit' this indicates that the write was NOT 75 // preformed. 76 func (c *Chunk) WriteInt64(n int64) error { 77 return c.WriteUint64(uint64(n)) 78 } 79 80 // WriteUint8 writes the supplied value to the Chunk payload buffer. 81 // 82 // If this function returns 'ErrLimit' this indicates that the write was NOT 83 // preformed. 84 func (c *Chunk) WriteUint8(n uint8) error { 85 i, err := c.checkWriteSize(1) 86 if i == -1 { 87 return err 88 } 89 _ = c.buf[i] 90 c.buf[i] = n 91 return err 92 } 93 94 // WriteBytes writes the supplied value to the Chunk payload buffer. 95 func (c *Chunk) WriteBytes(b []byte) error { 96 i, err := c.checkWriteSize(1) 97 if i == -1 { 98 return err 99 } 100 var x int 101 switch l := uint64(len(b)); { 102 case l == 0: 103 _ = c.buf[i] 104 c.buf[i] = 0 105 return err 106 case l < LimitSmall: 107 if x, err = c.checkWriteSize(1 + int(l)); x == -1 { 108 return err 109 } 110 _, x = c.buf[i+1+int(l)], x+1 111 c.buf[i], c.buf[i+1] = 1, byte(l) 112 case l < LimitMedium: 113 if x, err = c.checkWriteSize(2 + int(l)); x == -1 { 114 return err 115 } 116 _, x = c.buf[i+2+int(l)], x+2 117 c.buf[i], c.buf[i+1], c.buf[i+2] = 3, byte(l>>8), byte(l) 118 case l < LimitLarge: 119 if x, err = c.checkWriteSize(4 + int(l)); x == -1 { 120 return err 121 } 122 _, x = c.buf[i+4+int(l)], x+4 123 c.buf[i], c.buf[i+1], c.buf[i+2] = 5, byte(l>>24), byte(l>>16) 124 c.buf[i+3], c.buf[i+4] = byte(l>>8), byte(l) 125 default: 126 if x, err = c.checkWriteSize(8 + int(l)); x == -1 { 127 return err 128 } 129 _, x = c.buf[i+8+int(l)], x+8 130 c.buf[i], c.buf[i+1], c.buf[i+2] = 7, byte(l>>56), byte(l>>48) 131 c.buf[i+3], c.buf[i+4] = byte(l>>40), byte(l>>32) 132 c.buf[i+5], c.buf[i+6] = byte(l>>24), byte(l>>16) 133 c.buf[i+7], c.buf[i+8] = byte(l>>8), byte(l) 134 } 135 if n := copy(c.buf[x:], b); n != len(b) { 136 return io.ErrShortWrite 137 } 138 return err 139 } 140 141 // WriteUint16 writes the supplied value to the Chunk payload buffer. 142 // 143 // If this function returns 'ErrLimit' this indicates that the write was NOT 144 // preformed. 145 func (c *Chunk) WriteUint16(n uint16) error { 146 i, err := c.checkWriteSize(2) 147 if i == -1 { 148 return err 149 } 150 _ = c.buf[i+1] 151 c.buf[i], c.buf[i+1] = byte(n>>8), byte(n) 152 return err 153 } 154 155 // WriteUint32 writes the supplied value to the Chunk payload buffer. 156 // 157 // If this function returns 'ErrLimit' this indicates that the write was NOT 158 // preformed. 159 func (c *Chunk) WriteUint32(n uint32) error { 160 i, err := c.checkWriteSize(4) 161 if i == -1 { 162 return err 163 } 164 _ = c.buf[i+3] 165 c.buf[i], c.buf[i+1] = byte(n>>24), byte(n>>16) 166 c.buf[i+2], c.buf[i+3] = byte(n>>8), byte(n) 167 return err 168 } 169 170 // WriteUint64 writes the supplied value to the Chunk payload buffer. 171 // 172 // If this function returns 'ErrLimit' this indicates that the write was NOT 173 // preformed. 174 func (c *Chunk) WriteUint64(n uint64) error { 175 i, err := c.checkWriteSize(8) 176 if i == -1 { 177 return err 178 } 179 _ = c.buf[i+7] 180 c.buf[i], c.buf[i+1] = byte(n>>56), byte(n>>48) 181 c.buf[i+2], c.buf[i+3] = byte(n>>40), byte(n>>32) 182 c.buf[i+4], c.buf[i+5] = byte(n>>24), byte(n>>16) 183 c.buf[i+6], c.buf[i+7] = byte(n>>8), byte(n) 184 return err 185 } 186 187 // WriteString writes the supplied value to the Chunk payload buffer. 188 // 189 // If this function returns 'ErrLimit' this indicates that the write was NOT 190 // preformed. 191 func (c *Chunk) WriteString(s string) error { 192 return c.WriteBytes([]byte(s)) 193 } 194 195 // WriteFloat32 writes the supplied value to the Chunk payload buffer. 196 // 197 // If this function returns 'ErrLimit' this indicates that the write was NOT 198 // preformed. 199 func (c *Chunk) WriteFloat32(f float32) error { 200 return c.WriteUint32(float32ToInt(f)) 201 } 202 203 // WriteFloat64 writes the supplied value to the Chunk payload buffer. 204 // 205 // If this function returns 'ErrLimit' this indicates that the write was NOT 206 // preformed. 207 func (c *Chunk) WriteFloat64(f float64) error { 208 return c.WriteUint64(float64ToInt(f)) 209 } 210 211 // WriteBoolPos writes the supplied boolean value to the Chunk payload buffer at 212 // the supplied index 'p'. 213 // 214 // The error 'io.EOF' is returned if the position specified is greater than the 215 // Chunk buffer size, or 'ErrLimit' if this position is greater than the set 216 // Chunk limit. 217 func (c *Chunk) WriteBoolPos(p int, b bool) error { 218 if p >= c.Size() { 219 return io.EOF 220 } 221 if c.Limit > 0 && p >= c.Limit { 222 return ErrLimit 223 } 224 if _ = c.buf[p]; b { 225 c.buf[p] = 1 226 } else { 227 c.buf[p] = 0 228 } 229 return nil 230 } 231 func (c *Chunk) checkWriteSize(n int) (int, error) { 232 if c.Limit > 0 && !c.Available(n) { 233 return -1, ErrLimit 234 } 235 i, err := c.quickSlice(n) 236 switch { 237 case i == 0 && err != nil: 238 return -1, err 239 case c.Limit <= 0 && c.Size() < i+n: 240 return -1, io.ErrShortWrite 241 } 242 return i, err 243 } 244 245 // WriteUint8Pos writes the supplied uint8 value to the Chunk payload buffer at 246 // the supplied index 'p'. 247 // 248 // The error 'io.EOF' is returned if the position specified is greater than the 249 // Chunk buffer size, or 'ErrLimit' if this position is greater than the set 250 // Chunk limit. 251 func (c *Chunk) WriteUint8Pos(p int, n uint8) error { 252 if p >= c.Size() { 253 return io.EOF 254 } 255 if c.Limit > 0 && p >= c.Limit { 256 return ErrLimit 257 } 258 _ = c.buf[p] 259 c.buf[p] = n 260 return nil 261 } 262 263 // WriteUint16Pos writes the supplied uint16 value to the Chunk payload buffer 264 // at the supplied index 'p'. 265 // 266 // The error 'io.EOF' is returned if the position specified is greater than the 267 // Chunk buffer size, or 'ErrLimit' if this position is greater than the set 268 // Chunk limit. 269 func (c *Chunk) WriteUint16Pos(p int, n uint16) error { 270 if p >= c.Size() || p+1 >= c.Size() { 271 return io.EOF 272 } 273 if c.Limit > 0 && (p >= c.Limit || p+1 >= c.Limit) { 274 return ErrLimit 275 } 276 _ = c.buf[p+1] 277 c.buf[p], c.buf[p+1] = byte(n>>8), byte(n) 278 return nil 279 } 280 281 // WriteUint32Pos writes the supplied uint16 value to the Chunk payload buffer 282 // at the supplied index 'p'. 283 // 284 // The error 'io.EOF' is returned if the position specified is greater than the 285 // Chunk buffer size, or 'ErrLimit' if this position is greater than the set 286 // Chunk limit. 287 func (c *Chunk) WriteUint32Pos(p int, n uint32) error { 288 if p >= c.Size() || p+3 >= c.Size() { 289 return io.EOF 290 } 291 if c.Limit > 0 && (p >= c.Limit || p+3 >= c.Limit) { 292 return ErrLimit 293 } 294 _ = c.buf[p+3] 295 c.buf[p], c.buf[p+1], c.buf[p+2], c.buf[p+3] = byte(n>>24), byte(n>>16), byte(n>>8), byte(n) 296 return nil 297 } 298 299 // WriteUint64Pos writes the supplied uint16 value to the Chunk payload buffer 300 // at the supplied index 'p'. 301 // 302 // The error 'io.EOF' is returned if the position specified is greater than the 303 // Chunk buffer size, or 'ErrLimit' if this position is greater than the set 304 // Chunk limit. 305 func (c *Chunk) WriteUint64Pos(p int, n uint64) error { 306 if p >= c.Size() || p+7 >= c.Size() { 307 return io.EOF 308 } 309 if c.Limit > 0 && (p >= c.Limit || p+7 >= c.Limit) { 310 return ErrLimit 311 } 312 _ = c.buf[p+7] 313 c.buf[p], c.buf[p+1], c.buf[p+2], c.buf[p+3] = byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32) 314 c.buf[p+4], c.buf[p+5], c.buf[p+6], c.buf[p+7] = byte(n>>24), byte(n>>16), byte(n>>8), byte(n) 315 return nil 316 }