// 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 (
	
)

// 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 ( *Reader) ( block,  int) bitReader {
	return bitReader{
		r:    ,
		data: ,
		off:  uint32(),
	}
}

// moreBits is called to read more bits.
// This ensures that at least 16 bits are available.
func ( *bitReader) () error {
	for .cnt < 16 {
		if .off >= uint32(len(.data)) {
			return .r.makeEOFError(int(.off))
		}
		 := .data[.off]
		.off++
		.bits |= uint32() << .cnt
		.cnt += 8
	}
	return nil
}

// val is called to fetch a value of b bits.
func ( *bitReader) ( uint8) uint32 {
	 := .bits & ((1 << ) - 1)
	.bits >>= 
	.cnt -= uint32()
	return 
}

// backup steps back to the last byte we used.
func ( *bitReader) () {
	for .cnt >= 8 {
		.off--
		.cnt -= 8
	}
}

// makeError returns an error at the current offset wrapping a string.
func ( *bitReader) ( string) error {
	return .r.makeError(int(.off), )
}

// 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 ( *Reader) ( block, ,  int) (reverseBitReader, error) {
	 := []
	if  == 0 {
		return reverseBitReader{}, .makeError(, "zero byte at reverse bit stream start")
	}
	 := reverseBitReader{
		r:     ,
		data:  ,
		off:   uint32(),
		start: uint32(),
		bits:  uint32(),
		cnt:   uint32(7 - bits.LeadingZeros8()),
	}
	return , nil
}

// val is called to fetch a value of b bits.
func ( *reverseBitReader) ( uint8) (uint32, error) {
	if !.fetch() {
		return 0, .r.makeEOFError(int(.off))
	}

	.cnt -= uint32()
	 := (.bits >> .cnt) & ((1 << ) - 1)
	return , 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 ( *reverseBitReader) ( uint8) bool {
	for .cnt < uint32() {
		if .off <= .start {
			return false
		}
		.off--
		 := .data[.off]
		.bits <<= 8
		.bits |= uint32()
		.cnt += 8
	}
	return true
}

// makeError returns an error at the current offset wrapping a string.
func ( *reverseBitReader) ( string) error {
	return .r.makeError(int(.off), )
}