github.com/scottcagno/storage@v1.8.0/pkg/_se/pager.go (about) 1 package _se 2 3 import ( 4 "bufio" 5 "errors" 6 "io" 7 ) 8 9 var page [pageSize]byte 10 11 var fakeHeader = [headerSize]byte{ 12 0xff, 0xff, 0xff, 13 } 14 15 type PageWriter struct { 16 bw *bufio.Writer 17 } 18 19 func NewPageWriter(w io.Writer) *PageWriter { 20 return &PageWriter{ 21 bw: bufio.NewWriterSize(w, pageSize), 22 } 23 } 24 25 func (pw *PageWriter) Write(p []byte) (int, error) { 26 var nn int 27 // write header 28 n, err := pw.bw.Write(fakeHeader[:]) 29 if err != nil { 30 return -1, err 31 } 32 nn += n 33 // write data 34 n, err = pw.bw.Write(p) 35 if err != nil { 36 return -1, err 37 } 38 nn += n 39 padding := pageSize - nn%pageSize 40 // write padding 41 if padding != 0 { 42 n, err = pw.bw.Write(page[:padding]) 43 if err != nil { 44 return -1, err 45 } 46 nn += n 47 } 48 return nn, nil 49 } 50 51 func (pw *PageWriter) Flush() error { 52 err := pw.bw.Flush() 53 if err != nil { 54 return err 55 } 56 return nil 57 } 58 59 type PageReader struct { 60 br *bufio.Reader 61 } 62 63 func NewPageReader(r io.Reader) *PageReader { 64 return &PageReader{ 65 br: bufio.NewReaderSize(r, pageSize), 66 } 67 } 68 69 var ErrBadSize = errors.New("bad size") 70 71 func (pr *PageReader) Read(p []byte) (int, error) { 72 if len(p)%pageSize != 0 { 73 return -1, ErrBadSize 74 } 75 var nn int 76 // read header 77 n, err := pr.br.Read(p[:headerSize]) 78 if err != nil { 79 return -1, err 80 } 81 nn += n 82 // decode and err check header 83 // 84 85 // read data 86 n, err = pr.br.Read(p[nn:]) 87 if err != nil { 88 return -1, err 89 } 90 nn += n 91 return nn, nil 92 }