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  }