You've already forked postgres_exporter
mirror of
https://github.com/prometheus-community/postgres_exporter.git
synced 2025-08-09 15:42:47 +03:00
This commit implements a massive refactor of the repository, and moves the build system over to use Mage (magefile.org) which should allow seamless building across multiple platforms.
120 lines
2.4 KiB
Go
120 lines
2.4 KiB
Go
package rardecode
|
|
|
|
import "io"
|
|
|
|
type bitReader interface {
|
|
readBits(n uint) (int, error) // read n bits of data
|
|
unreadBits(n uint) // revert the reading of the last n bits read
|
|
}
|
|
|
|
type limitedBitReader struct {
|
|
br bitReader
|
|
n int
|
|
err error // error to return if br returns EOF before all n bits have been read
|
|
}
|
|
|
|
// limitBitReader returns a bitReader that reads from br and stops with io.EOF after n bits.
|
|
// If br returns an io.EOF before reading n bits, err is returned.
|
|
func limitBitReader(br bitReader, n int, err error) bitReader {
|
|
return &limitedBitReader{br, n, err}
|
|
}
|
|
|
|
func (l *limitedBitReader) readBits(n uint) (int, error) {
|
|
if int(n) > l.n {
|
|
return 0, io.EOF
|
|
}
|
|
v, err := l.br.readBits(n)
|
|
if err == nil {
|
|
l.n -= int(n)
|
|
} else if err == io.EOF {
|
|
err = l.err
|
|
}
|
|
return v, err
|
|
}
|
|
|
|
func (l *limitedBitReader) unreadBits(n uint) {
|
|
l.n += int(n)
|
|
l.br.unreadBits(n)
|
|
}
|
|
|
|
// rarBitReader wraps an io.ByteReader to perform various bit and byte
|
|
// reading utility functions used in RAR file processing.
|
|
type rarBitReader struct {
|
|
r io.ByteReader
|
|
v int
|
|
n uint
|
|
}
|
|
|
|
func (r *rarBitReader) reset(br io.ByteReader) {
|
|
r.r = br
|
|
r.n = 0
|
|
r.v = 0
|
|
}
|
|
|
|
func (r *rarBitReader) readBits(n uint) (int, error) {
|
|
for n > r.n {
|
|
c, err := r.r.ReadByte()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
r.v = r.v<<8 | int(c)
|
|
r.n += 8
|
|
}
|
|
r.n -= n
|
|
return (r.v >> r.n) & ((1 << n) - 1), nil
|
|
}
|
|
|
|
func (r *rarBitReader) unreadBits(n uint) {
|
|
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 {
|
|
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) {
|
|
n, err := r.readBits(8)
|
|
return byte(n), err
|
|
}
|
|
|
|
// readFull reads len(p) bytes into p. If fewer bytes are read an error is returned.
|
|
func (r *rarBitReader) readFull(p []byte) error {
|
|
for i := range p {
|
|
c, err := r.ReadByte()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
p[i] = c
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func newRarBitReader(r io.ByteReader) *rarBitReader {
|
|
return &rarBitReader{r: r}
|
|
}
|