package rlepluslazy import ( "github.com/multiformats/go-varint" "golang.org/x/xerrors" ) func DecodeRLE(buf []byte) (RunIterator, error) { bv := readBitvec(buf) ver := bv.Get(2) // Read version if ver != Version { return nil, ErrWrongVersion } it := &rleIterator{bv: bv} // next run is previous in relation to prep // so we invert the value it.nextRun.Val = bv.Get(1) != 1 if err := it.prep(); err != nil { return nil, err } return it, nil } type rleIterator struct { bv *rbitvec nextRun Run } func (it *rleIterator) HasNext() bool { return it.nextRun.Valid() } func (it *rleIterator) NextRun() (Run, error) { ret := it.nextRun return ret, it.prep() } func (it *rleIterator) prep() error { x := it.bv.Get(1) switch x { case 1: it.nextRun.Len = 1 case 0: y := it.bv.Get(1) switch y { case 1: it.nextRun.Len = uint64(it.bv.Get(4)) case 0: var buf = make([]byte, 0, 10) for { b := it.bv.Get(8) buf = append(buf, b) if b&0x80 == 0 { break } if len(buf) > 10 { return xerrors.Errorf("run too long: %w", ErrDecode) } } var err error it.nextRun.Len, _, err = varint.FromUvarint(buf) if err != nil { return err } } } it.nextRun.Val = !it.nextRun.Val return nil }