1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
package rardecode
import (
"io"
"math/bits"
)
type bitReader interface {
readBits(n uint8) (int, error) // read n bits of data
unreadBits(n uint8) // revert the reading of the last n bits read
}
// rar5BitReader is a bitReader that reads bytes from a byteReader and stops with io.EOF after l bits.
type rar5BitReader struct {
r byteReader
v int // cache of bits read from r
l int // number of bits (not cached) that can be read from r
n uint8 // number of unread bits in v
}
func (r *rar5BitReader) unreadBits(n uint8) { r.n += n }
// ReadByte reads and returns a single byte. If no byte is available, returns an error.
func (r *rar5BitReader) ReadByte() (byte, error) {
if r.n == 0 {
return r.r.ReadByte()
}
b, err := r.readBits(8)
return byte(b), err
}
func (r *rar5BitReader) reset(br byteReader) {
r.r = br
}
// setLimit sets the maximum bit count that can be read.
func (r *rar5BitReader) setLimit(n int) {
r.l = n
r.n = 0
}
// readBits returns n bits from the underlying byteReader.
// n must be less than integer size - 8.
func (r *rar5BitReader) readBits(n uint8) (int, error) {
for n > r.n {
if r.l == 0 {
// reached bits limit
return 0, io.EOF
}
c, err := r.r.ReadByte()
if err != nil {
if err == io.EOF {
// io.EOF before we reached bit limit
err = ErrDecoderOutOfData
}
return 0, err
}
r.v = r.v<<8 | int(c)
r.n += 8
r.l -= 8
if r.l < 0 {
// overshot, discard the extra bits
bits := uint8(-r.l)
r.l = 0
r.v >>= bits
r.n -= bits
}
}
r.n -= n
return (r.v >> r.n) & ((1 << n) - 1), nil
}
// rarBitReader wraps an io.ByteReader to perform various bit and byte
// reading utility functions used in RAR file processing.
type rarBitReader struct {
r byteReader
v int
n uint8
}
func (r *rarBitReader) reset(br byteReader) {
r.r = br
r.n = 0
r.v = 0
}
// readBits returns n bits from the underlying byteReader.
// n must be less than integer size - 8.
func (r *rarBitReader) readBits(n uint8) (int, error) {
for n > r.n {
b, err := r.r.ReadByte()
if err != nil {
return 0, err
}
r.v = r.v<<8 | int(b)
r.n += 8
}
r.n -= n
return (r.v >> r.n) & ((1 << n) - 1), nil
}
func (r *rarBitReader) unreadBits(n uint8) {
r.n += n
}
// alignByte aligns the current bit reading input to the next byte boundary.
func (r *rarBitReader) alignByte() {
r.n -= r.n % 8
}
// readUint32 reads a RAR V3 encoded uint32
func (r *rarBitReader) readUint32() (uint32, error) {
n, err := r.readBits(2)
if err != nil {
return 0, err
}
if n != 1 {
if bits.UintSize == 32 {
if n == 3 {
// 32bit platforms may not be able to read 32 bits as r.v
// will need up to 7 extra bits for overflow from reading a byte.
// Split it into two reads.
n, err = r.readBits(16)
if err != nil {
return 0, err
}
m := uint32(n) << 16
n, err = r.readBits(16)
return m | uint32(n), err
}
}
n, err = r.readBits(4 << uint(n))
return uint32(n), err
}
n, err = r.readBits(4)
if err != nil {
return 0, err
}
if n == 0 {
n, err = r.readBits(8)
n |= -1 << 8
return uint32(n), err
}
nlow, err := r.readBits(4)
n = n<<4 | nlow
return uint32(n), err
}
func (r *rarBitReader) ReadByte() (byte, error) {
if r.n == 0 {
return r.r.ReadByte()
}
b, err := r.readBits(8)
return byte(b), err
}
func (r *rarBitReader) Read(p []byte) (int, error) {
if r.n == 0 {
return r.r.Read(p)
}
for i := range p {
b, err := r.readBits(8)
if err != nil {
return i, err
}
p[i] = byte(b)
}
return len(p), nil
}
func newRarBitReader(r byteReader) *rarBitReader {
return &rarBitReader{r: r}
}
|