github.com/scottcagno/storage@v1.8.0/pkg/bio/header.go (about)

     1  package bio
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"sync"
     7  )
     8  
     9  const (
    10  	statusEmpty   = 0
    11  	statusActive  = 1
    12  	statusDeleted = 2
    13  	statusOther   = 3
    14  )
    15  
    16  const (
    17  	kindFull    = 1
    18  	kindBeg     = 2
    19  	kindMid     = 3
    20  	kindEnd     = 4
    21  	kindUnknown = 5
    22  )
    23  
    24  type headerBuff struct {
    25  	hdr *header
    26  	buf []byte
    27  }
    28  
    29  func (hb *headerBuff) clear() {
    30  	hb.hdr.status = 0
    31  	hb.hdr.kind = 0
    32  	hb.hdr.part = 0
    33  	hb.hdr.parts = 0
    34  	hb.hdr.length = 0
    35  	hb.buf[0] = 0
    36  	hb.buf[1] = 0
    37  	hb.buf[2] = 0
    38  	hb.buf[3] = 0
    39  	hb.buf[4] = 0
    40  	hb.buf[5] = 0
    41  }
    42  
    43  var headerPool = sync.Pool{
    44  	New: func() interface{} {
    45  		return &headerBuff{
    46  			hdr: new(header),
    47  			buf: make([]byte, headerSize),
    48  		}
    49  	},
    50  }
    51  
    52  func getHdr() *headerBuff {
    53  	hb := headerPool.Get().(*headerBuff)
    54  	hb.clear()
    55  	return hb
    56  }
    57  
    58  func putHdr(hb *headerBuff) {
    59  	headerPool.Put(hb)
    60  }
    61  
    62  // header represents a block header
    63  type header struct {
    64  	status uint8
    65  	kind   uint8
    66  	part   uint8
    67  	parts  uint8
    68  	length uint16
    69  }
    70  
    71  // ReadFrom implements the ReaderFrom interface for header
    72  func (h *header) ReadFrom(r io.Reader) (int64, error) {
    73  	p := make([]byte, headerSize)
    74  	n, err := r.Read(p)
    75  	h.status = p[0]
    76  	h.kind = p[1]
    77  	h.part = p[2]
    78  	h.parts = p[3]
    79  	h.length = uint16(p[4]) | uint16(p[5])<<8
    80  	if err != nil {
    81  		return -1, err
    82  	}
    83  	fmt.Printf(">>> header >> ReadFrom > (%d) %s\n", n, h)
    84  	return int64(n), err
    85  }
    86  
    87  // WriteTo implements the WriterTo interface for header
    88  func (h *header) WriteTo(w io.Writer) (int64, error) {
    89  	n, err := w.Write([]byte{
    90  		h.status,
    91  		h.kind,
    92  		h.part,
    93  		h.parts,
    94  		byte(h.length),
    95  		byte(h.length >> 8),
    96  	})
    97  	if err != nil {
    98  		return -1, err
    99  	}
   100  	return int64(n), nil
   101  }
   102  
   103  // String is header's stringer method
   104  func (h *header) String() string {
   105  	return fmt.Sprintf("status=%d, kind=%d, part=%d, parts=%d, length=%d",
   106  		h.status, h.kind, h.part, h.parts, h.length)
   107  }
   108  
   109  // getKind is a helper function that will
   110  // return a kind type based on the configuration
   111  // of the part and parts provided
   112  func getKind(part, parts int) uint8 {
   113  	if parts == 1 {
   114  		return kindFull
   115  	}
   116  	if part == 1 {
   117  		return kindBeg
   118  	}
   119  	if part > 1 && part < parts {
   120  		return kindMid
   121  	}
   122  	if part == parts {
   123  		return kindEnd
   124  	}
   125  	return kindUnknown
   126  }