diff --git a/roaring/roaring.go b/roaring/roaring.go index cf6c1d5f3..600c9b8e2 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -522,19 +522,39 @@ func (b *Bitmap) Optimize() { } } -//hoping this in-lines -func WriteUint16(w io.Writer, b []byte, v uint16) (int, error) { - binary.LittleEndian.PutUint16(b, v) - return w.Write(b) -} -func WriteUint32(w io.Writer, b []byte, v uint32) (int, error) { - binary.LittleEndian.PutUint32(b, v) - return w.Write(b) +type errWriter struct { + w io.Writer + err error + n int } -func WriteUint64(w io.Writer, b []byte, v uint64) (int, error) { +func (ew *errWriter) WriteUint16(b []byte, v uint16) { + if ew.err != nil { + return + } + var n int + binary.LittleEndian.PutUint16(b, v) + n, ew.err = ew.w.Write(b) + ew.n += n +} +func (ew *errWriter) WriteUint32(b []byte, v uint32) { + if ew.err != nil { + return + } + var n int + binary.LittleEndian.PutUint32(b, v) + n, ew.err = ew.w.Write(b) + ew.n += n +} + +func (ew *errWriter) WriteUint64(b []byte, v uint64) { + if ew.err != nil { + return + } + var n int binary.LittleEndian.PutUint64(b, v) - return w.Write(b) + n, ew.err = ew.w.Write(b) + ew.n += n } // WriteTo writes b to w. @@ -552,9 +572,13 @@ func (b *Bitmap) WriteTo(w io.Writer) (n int64, err error) { // Build header before writing individual container blocks. // Metadata for each container is 8+2+2+4 = sizeof(key) + sizeof(containerType)+sizeof(cardinality) + sizeof(file offset) // Cookie header section. + ew := &errWriter{ + w: w, + n: 0, + } - WriteUint32(w, byte4, cookie) - WriteUint32(w, byte4, uint32(containerCount)) + ew.WriteUint32(byte4, cookie) + ew.WriteUint32(byte4, uint32(containerCount)) // Descriptive header section: encode keys and cardinality. // Key and cardinality are stored interleaved here, 12 bytes per container. @@ -566,9 +590,9 @@ func (b *Bitmap) WriteTo(w io.Writer) (n int64, err error) { //count := c.count() //assert(c.count() == c.n, "cannot write container count, mismatch: count=%d, n=%d", count, c.n) if c.n > 0 { - WriteUint64(w, byte8, uint64(key)) - WriteUint16(w, byte2, uint16(c.containerType)) - WriteUint16(w, byte2, uint16(c.n-1)) + ew.WriteUint64(byte8, uint64(key)) + ew.WriteUint16(byte2, uint16(c.containerType)) + ew.WriteUint16(byte2, uint16(c.n-1)) } } @@ -578,15 +602,15 @@ func (b *Bitmap) WriteTo(w io.Writer) (n int64, err error) { for _, c := range b.containers { if c.n > 0 { - WriteUint32(w, byte4, uint32(offset)) + ew.WriteUint32(byte4, uint32(offset)) offset += uint32(c.size()) } } + if ew.err != nil { + return int64(ew.n), ew.err + } n = int64(headerSize + (containerCount * (8 + 2 + 2 + 4))) - if err != nil { - return n, err - } // Container storage section: write each container block. for _, c := range b.containers { @@ -1688,8 +1712,8 @@ func (c *container) runWriteTo(w io.Writer) (n int64, err error) { return 0, nil } var byte2 [2]byte - - _, err = WriteUint16(w, byte2[:], uint16(len(c.runs))) + binary.LittleEndian.PutUint16(byte2[:], uint16(len(c.runs))) + _, err = w.Write(byte2[:]) if err != nil { return 0, err }