github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/m3ninx/index/segment/fst/encoding/encoding.go (about) 1 // Copyright (c) 2018 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package encoding 22 23 import ( 24 "encoding/binary" 25 "errors" 26 "io" 27 ) 28 29 const maxInt = int(^uint(0) >> 1) 30 31 var byteOrder = binary.LittleEndian 32 33 var errUvarintOverflow = errors.New("uvarint overflows 64 bits") 34 var errIntOverflow = errors.New("decoded integer overflows an int") 35 36 // Encoder is a low-level encoder that can be used for encoding basic types. 37 type Encoder struct { 38 buf []byte 39 tmp [binary.MaxVarintLen64]byte 40 } 41 42 // NewEncoder returns a new encoder. 43 func NewEncoder(n int) *Encoder { 44 return &Encoder{buf: make([]byte, 0, n)} 45 } 46 47 // Bytes returns the encoded bytes. 48 func (e *Encoder) Bytes() []byte { return e.buf } 49 50 // Len returns the length of the encoder. 51 func (e *Encoder) Len() int { return len(e.buf) } 52 53 // Reset resets the encoder. 54 func (e *Encoder) Reset() { e.buf = e.buf[:0] } 55 56 // PutUint32 encodes a uint32 and returns the number of bytes written which is always 4. 57 func (e *Encoder) PutUint32(x uint32) int { 58 byteOrder.PutUint32(e.tmp[:], x) 59 e.buf = append(e.buf, e.tmp[:4]...) 60 return 4 61 } 62 63 // PutUint64 encodes a uint64 and returns the number of bytes written which is always 8. 64 func (e *Encoder) PutUint64(x uint64) int { 65 byteOrder.PutUint64(e.tmp[:], x) 66 e.buf = append(e.buf, e.tmp[:8]...) 67 return 8 68 } 69 70 // PutUvarint encodes a variable-sized unsigned integer and returns the number of 71 // bytes written. 72 func (e *Encoder) PutUvarint(x uint64) int { 73 n := binary.PutUvarint(e.tmp[:], x) 74 e.buf = append(e.buf, e.tmp[:n]...) 75 return n 76 } 77 78 // PutBytes encodes a byte slice and returns the number of bytes written. 79 func (e *Encoder) PutBytes(b []byte) int { 80 n := e.PutUvarint(uint64(len(b))) 81 e.buf = append(e.buf, b...) 82 return n + len(b) 83 } 84 85 // Decoder is a low-level decoder for decoding basic types. 86 type Decoder struct { 87 buf []byte 88 } 89 90 // NewDecoder returns a new Decoder. 91 func NewDecoder(buf []byte) *Decoder { 92 return &Decoder{buf: buf} 93 } 94 95 // Reset resets the decoder. 96 func (d *Decoder) Reset(buf []byte) { d.buf = buf } 97 98 // Uint32 reads a uint32 from the decoder. 99 func (d *Decoder) Uint32() (uint32, error) { 100 if len(d.buf) < 4 { 101 return 0, io.ErrShortBuffer 102 } 103 x := byteOrder.Uint32(d.buf) 104 d.buf = d.buf[4:] 105 return x, nil 106 } 107 108 // Uint64 reads a uint64 from the decoder. 109 func (d *Decoder) Uint64() (uint64, error) { 110 if len(d.buf) < 8 { 111 return 0, io.ErrShortBuffer 112 } 113 x := byteOrder.Uint64(d.buf) 114 d.buf = d.buf[8:] 115 return x, nil 116 } 117 118 // Uvarint reads a variable-sized unsigned integer. 119 func (d *Decoder) Uvarint() (uint64, error) { 120 x, buf, err := ReadUvarint(d.buf) 121 if err != nil { 122 return 0, err 123 } 124 d.buf = buf 125 return x, nil 126 } 127 128 // Bytes reads a byte slice from the decoder. 129 func (d *Decoder) Bytes() ([]byte, error) { 130 b, buf, err := ReadBytes(d.buf) 131 if err != nil { 132 return nil, err 133 } 134 d.buf = buf 135 return b, nil 136 } 137 138 // ReadUvarint reads a variable-size unsigned integer from a byte slice 139 // and returns a new slice positioned after the integer that was just read. 140 func ReadUvarint(buf []byte) (uint64, []byte, error) { 141 x, n := binary.Uvarint(buf) 142 if n == 0 { 143 return 0, nil, io.ErrShortBuffer 144 } 145 if n < 0 { 146 return 0, nil, errUvarintOverflow 147 } 148 buf = buf[n:] 149 return x, buf, nil 150 } 151 152 // ReadBytes reads an unsigned integer from a byte slice and 153 // returns that amount of bytes along with a new slice positioned after 154 // the last byte just read. 155 func ReadBytes(buf []byte) ([]byte, []byte, error) { 156 x, buf, err := ReadUvarint(buf) 157 if err != nil { 158 return nil, nil, err 159 } 160 161 // Verify the length of the slice won't overflow an int. 162 if x > uint64(maxInt) { 163 return nil, nil, errIntOverflow 164 } 165 166 n := int(x) 167 if len(buf) < n { 168 return nil, nil, io.ErrShortBuffer 169 } 170 b := buf[:n] 171 buf = buf[n:] 172 return b, buf, nil 173 }