github.com/scottcagno/storage@v1.8.0/pkg/bw/v3/writer.go (about) 1 package v3 2 3 import ( 4 "bufio" 5 "hash/crc32" 6 "io" 7 ) 8 9 type DataWriter struct { 10 bw *bufio.Writer 11 opts *Options 12 emptyPage page 13 } 14 15 func NewDataWriter(w io.Writer, opt *Options) *DataWriter { 16 checkOptions(opt) 17 return &DataWriter{ 18 bw: bufio.NewWriterSize(w, opt.pageSize), 19 opts: opt, 20 } 21 } 22 23 func (d *DataWriter) writeHeader(p []byte) (int, error) { 24 var kind uint16 25 if len(p) == 0 || p == nil { 26 kind = kindInactive 27 } 28 // create header 29 h := &header{ 30 magic: magicBytes, 31 kind: kind, 32 crc32: crc32.ChecksumIEEE(p), 33 size: uint64(len(p)), 34 } 35 // write header 36 n, err := h.WriteTo(d.bw) 37 if err != nil { 38 return int(n), err 39 } 40 return int(n), nil 41 } 42 43 func (d *DataWriter) Write(p []byte) (int, error) { 44 // write header 45 n, err := d.writeHeader(p) 46 if err != nil { 47 return n, err 48 } 49 var nn int 50 nn += n 51 // write body 52 n, err = d.bw.Write(p) 53 if err != nil { 54 return n + nn, err 55 } 56 nn += n 57 // check align rules 58 if d.opts.pageAlign { 59 off := d.bw.Size() - d.bw.Buffered() 60 n, err = d.bw.Write(d.emptyPage.data[:off]) 61 if err != nil { 62 return n + nn, err 63 } 64 nn += n 65 } 66 // check auto flush 67 if d.opts.autoFlush { 68 err = d.bw.Flush() 69 if err != nil { 70 return nn, err 71 } 72 } 73 // return bytes written 74 return nn, nil 75 } 76 77 func (d *DataWriter) Flush() error { 78 return d.bw.Flush() 79 }