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  }