Reads a serialized roaringArray from a byte slice.
(stream internal.ByteInput, cookieHeader ...byte)
| 575 | |
| 576 | // Reads a serialized roaringArray from a byte slice. |
| 577 | func (ra *roaringArray) readFrom(stream internal.ByteInput, cookieHeader ...byte) (int64, error) { |
| 578 | var cookie uint32 |
| 579 | var err error |
| 580 | if len(cookieHeader) > 0 && len(cookieHeader) != 4 { |
| 581 | return int64(len(cookieHeader)), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: incorrect size of cookie header") |
| 582 | } |
| 583 | if len(cookieHeader) == 4 { |
| 584 | cookie = binary.LittleEndian.Uint32(cookieHeader) |
| 585 | } else { |
| 586 | cookie, err = stream.ReadUInt32() |
| 587 | if err != nil { |
| 588 | return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: could not read initial cookie: %s", err) |
| 589 | } |
| 590 | } |
| 591 | // If NextReturnsSafeSlice is false, then willNeedCopyOnWrite should be true |
| 592 | willNeedCopyOnWrite := !stream.NextReturnsSafeSlice() |
| 593 | |
| 594 | var size uint32 |
| 595 | var isRunBitmap []byte |
| 596 | |
| 597 | if cookie&0x0000FFFF == serialCookie { |
| 598 | size = cookie>>16 + 1 |
| 599 | // create is-run-container bitmap |
| 600 | isRunBitmapSize := (int(size) + 7) / 8 |
| 601 | isRunBitmap, err = stream.Next(isRunBitmapSize) |
| 602 | if err != nil { |
| 603 | return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read is-run bitmap, got: %s", err) |
| 604 | } |
| 605 | } else if cookie == serialCookieNoRunContainer { |
| 606 | size, err = stream.ReadUInt32() |
| 607 | if err != nil { |
| 608 | return stream.GetReadBytes(), fmt.Errorf("malformed bitmap, failed to read a bitmap size: %s", err) |
| 609 | } |
| 610 | } else { |
| 611 | return stream.GetReadBytes(), fmt.Errorf("error in roaringArray.readFrom: did not find expected serialCookie in header") |
| 612 | } |
| 613 | |
| 614 | if size > (1 << 16) { |
| 615 | return stream.GetReadBytes(), fmt.Errorf("it is logically impossible to have more than (1<<16) containers") |
| 616 | } |
| 617 | |
| 618 | // descriptive header |
| 619 | buf, err := stream.Next(2 * 2 * int(size)) |
| 620 | if err != nil { |
| 621 | return stream.GetReadBytes(), fmt.Errorf("failed to read descriptive header: %s", err) |
| 622 | } |
| 623 | |
| 624 | keycard := byteSliceAsUint16Slice(buf) |
| 625 | |
| 626 | if isRunBitmap == nil || size >= noOffsetThreshold { |
| 627 | if err := stream.SkipBytes(int(size) * 4); err != nil { |
| 628 | return stream.GetReadBytes(), fmt.Errorf("failed to skip bytes: %s", err) |
| 629 | } |
| 630 | } |
| 631 | |
| 632 | // Allocate slices upfront as number of containers is known |
| 633 | if cap(ra.containers) >= int(size) { |
| 634 | ra.containers = ra.containers[:size] |
no test coverage detected