github.com/scottcagno/storage@v1.8.0/pkg/_junk/_binary/entryidx.go (about)

     1  package binary
     2  
     3  import (
     4  	"encoding/binary"
     5  	"io"
     6  )
     7  
     8  // EntryIndex is a binary entry index
     9  type EntryIndex struct {
    10  	Key    []byte
    11  	Offset int64
    12  }
    13  
    14  // DecodeEntryIndex reads and decodes the provided entry index from r
    15  func DecodeEntryIndex(r io.Reader) (*EntryIndex, error) {
    16  	// make buffer
    17  	buf := make([]byte, 18)
    18  	// read entry key length
    19  	_, err := r.Read(buf[0:8])
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  	// read entry data offset
    24  	_, err = r.Read(buf[8:18])
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	// decode key length
    29  	klen := binary.LittleEndian.Uint64(buf[0:8])
    30  	// decode data offset
    31  	off, _ := binary.Varint(buf[8:18])
    32  	// make entry index
    33  	e := &EntryIndex{
    34  		Key:    make([]byte, klen),
    35  		Offset: off,
    36  	}
    37  	// read key from data into entry key
    38  	_, err = r.Read(e.Key)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	// return entry
    43  	return e, nil
    44  }
    45  
    46  func DecodeEntryIndexAt(r io.ReaderAt, offset int64) (*EntryIndex, error) {
    47  	// make buffer
    48  	buf := make([]byte, 18)
    49  	// read entry key length
    50  	n, err := r.ReadAt(buf[0:8], offset)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	// update offset
    55  	offset += int64(n)
    56  	// read entry data offset
    57  	n, err = r.ReadAt(buf[8:18], offset)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	// update offset
    62  	offset += int64(n)
    63  	// decode key length
    64  	klen := binary.LittleEndian.Uint64(buf[0:8])
    65  	// decode data offset
    66  	off, _ := binary.Varint(buf[8:18])
    67  	// make entry index
    68  	e := &EntryIndex{
    69  		Key:    make([]byte, klen),
    70  		Offset: off,
    71  	}
    72  	// read key from data into entry key
    73  	n, err = r.ReadAt(e.Key, offset)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	// update offset
    78  	offset += int64(n)
    79  	// return entry
    80  	return e, nil
    81  }
    82  
    83  // EncodeEntryIndex encodes and writes the provided entry index to w
    84  func EncodeEntryIndex(w io.WriteSeeker, e *EntryIndex) (int64, error) {
    85  	// error check
    86  	if e == nil {
    87  		return -1, ErrBadEntry
    88  	}
    89  	// get the file pointer offset for the entry
    90  	offset, err := w.Seek(0, io.SeekCurrent)
    91  	if err != nil {
    92  		return -1, err
    93  	}
    94  	// make buffer
    95  	buf := make([]byte, 18)
    96  	// encode and write entry key length
    97  	binary.LittleEndian.PutUint64(buf[0:8], uint64(len(e.Key)))
    98  	_, err = w.Write(buf[0:8])
    99  	if err != nil {
   100  		return -1, err
   101  	}
   102  	// encode and write entry index data offset
   103  	binary.PutVarint(buf[8:18], e.Offset)
   104  	_, err = w.Write(buf[8:18])
   105  	if err != nil {
   106  		return -1, err
   107  	}
   108  	// write entry key
   109  	_, err = w.Write(e.Key)
   110  	if err != nil {
   111  		return -1, err
   112  	}
   113  	return offset, nil
   114  }