From ccd992355df7192993c666236047820244914598 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 16 Apr 2024 21:19:13 +0200 Subject: Adding upstream version 1.21.8. Signed-off-by: Daniel Baumann --- src/internal/zstd/bits.go | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/internal/zstd/bits.go (limited to 'src/internal/zstd/bits.go') diff --git a/src/internal/zstd/bits.go b/src/internal/zstd/bits.go new file mode 100644 index 0000000..c9a2f70 --- /dev/null +++ b/src/internal/zstd/bits.go @@ -0,0 +1,130 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package zstd + +import ( + "math/bits" +) + +// block is the data for a single compressed block. +// The data starts immediately after the 3 byte block header, +// and is Block_Size bytes long. +type block []byte + +// bitReader reads a bit stream going forward. +type bitReader struct { + r *Reader // for error reporting + data block // the bits to read + off uint32 // current offset into data + bits uint32 // bits ready to be returned + cnt uint32 // number of valid bits in the bits field +} + +// makeBitReader makes a bit reader starting at off. +func (r *Reader) makeBitReader(data block, off int) bitReader { + return bitReader{ + r: r, + data: data, + off: uint32(off), + } +} + +// moreBits is called to read more bits. +// This ensures that at least 16 bits are available. +func (br *bitReader) moreBits() error { + for br.cnt < 16 { + if br.off >= uint32(len(br.data)) { + return br.r.makeEOFError(int(br.off)) + } + c := br.data[br.off] + br.off++ + br.bits |= uint32(c) << br.cnt + br.cnt += 8 + } + return nil +} + +// val is called to fetch a value of b bits. +func (br *bitReader) val(b uint8) uint32 { + r := br.bits & ((1 << b) - 1) + br.bits >>= b + br.cnt -= uint32(b) + return r +} + +// backup steps back to the last byte we used. +func (br *bitReader) backup() { + for br.cnt >= 8 { + br.off-- + br.cnt -= 8 + } +} + +// makeError returns an error at the current offset wrapping a string. +func (br *bitReader) makeError(msg string) error { + return br.r.makeError(int(br.off), msg) +} + +// reverseBitReader reads a bit stream in reverse. +type reverseBitReader struct { + r *Reader // for error reporting + data block // the bits to read + off uint32 // current offset into data + start uint32 // start in data; we read backward to start + bits uint32 // bits ready to be returned + cnt uint32 // number of valid bits in bits field +} + +// makeReverseBitReader makes a reverseBitReader reading backward +// from off to start. The bitstream starts with a 1 bit in the last +// byte, at off. +func (r *Reader) makeReverseBitReader(data block, off, start int) (reverseBitReader, error) { + streamStart := data[off] + if streamStart == 0 { + return reverseBitReader{}, r.makeError(off, "zero byte at reverse bit stream start") + } + rbr := reverseBitReader{ + r: r, + data: data, + off: uint32(off), + start: uint32(start), + bits: uint32(streamStart), + cnt: uint32(7 - bits.LeadingZeros8(streamStart)), + } + return rbr, nil +} + +// val is called to fetch a value of b bits. +func (rbr *reverseBitReader) val(b uint8) (uint32, error) { + if !rbr.fetch(b) { + return 0, rbr.r.makeEOFError(int(rbr.off)) + } + + rbr.cnt -= uint32(b) + v := (rbr.bits >> rbr.cnt) & ((1 << b) - 1) + return v, nil +} + +// fetch is called to ensure that at least b bits are available. +// It reports false if this can't be done, +// in which case only rbr.cnt bits are available. +func (rbr *reverseBitReader) fetch(b uint8) bool { + for rbr.cnt < uint32(b) { + if rbr.off <= rbr.start { + return false + } + rbr.off-- + c := rbr.data[rbr.off] + rbr.bits <<= 8 + rbr.bits |= uint32(c) + rbr.cnt += 8 + } + return true +} + +// makeError returns an error at the current offset wrapping a string. +func (rbr *reverseBitReader) makeError(msg string) error { + return rbr.r.makeError(int(rbr.off), msg) +} -- cgit v1.2.3