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 }