Documentation
¶
Overview ¶
This package provides bit-manipulation and bit-field-manipulation functions that operate on byte slices. It contains functions similar to those the standard 'math/bits' package provides for unsigned integers, but operating on byte slices. Some of this functionality might really belong in the Go standard library, perhaps as a "bytes/bits" sub-package of the current "bytes" package.
This package is preliminary, unstable, and incompletely tested. Beware.
Overview ¶
The And, AndNot, Or, Xor, and Not functions perform the obvious bitwise operations on entire byte slices, either in-place, or into a destination that is allocated or grown as needed. Count counts the total number of zero or one bits in a slice.
The BigEndian and LittleEndian variables are instances of the BigEndianOrder and LittleEndianOrder types, respectively, which provide endianness-dependent bit operations on byte slices. These operations treat byte slices as bit vectors in either big-endian or little-endian bit ordering, as illustrated below.
Big Endian Bit Ordering ¶
To illustrate big-endian bit ordering, a bit-field starting at bit offset 14 and having a width of five bits will contain the least-significant two bits of the second byte and the most-significant three bits of the third byte, as follows:
offset 14 = 8+6 bits 5-bit width ------------------------------> |<------->| +-----------------+-----------------+-----------------+ | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | +-----------------+-----------------+-----------------+
The BigEndian.Uint* and BigEndian.PutUint* operations use big endian as both bit order within bytes and byte order within integers to be read or written at arbitrary positions in a slice.
Little Endian Bit Ordering ¶
To illustrate big-endian bit ordering, a bit-field starting at bit offset 14 and having a width of five bits will contain the most-significant two bits of the second byte and the least-significant three bits of the third byte, as follows:
offset 14 = 8+6 bits 5-bit width ------------------------------> |<------->| +-----------------+-----------------+-----------------+ | 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | +-----------------+-----------------+-----------------+
The BigEndian.Uint* and BigEndian.PutUint* operations use big endian as both bit order within bytes and byte order within integers to be read or written at arbitrary positions in a slice.
Limitations ¶
These functions could probably be sped up significantly via architecture-specific optimizations similarly to the math/bits primitives, but this implementation currently does not do so.
Still todo: little endian, shift operations, field Leading/Trailing, more/better testing, bit I/O, ...
Index ¶
- Variables
- func And(z, x, y []byte) []byte
- func AndNot(z, x, y []byte) []byte
- func Count(x []byte, v uint) (n int)
- func Grow(z []byte, l int) []byte
- func Not(z, x []byte) []byte
- func Or(z, x, y []byte) []byte
- func Xor(z, x, y []byte) []byte
- type BigEndianField
- func (z *BigEndianField) And(x, y Field) Field
- func (z *BigEndianField) AndNot(x, y Field) Field
- func (z *BigEndianField) Count(b uint) (n int)
- func (z *BigEndianField) Fill(b uint)
- func (z *BigEndianField) Grow(buf []byte, ofs, width int) []byte
- func (z *BigEndianField) Init(buf []byte, ofs, width int) Field
- func (z *BigEndianField) Not(x Field) Field
- func (z *BigEndianField) Or(x, y Field) Field
- func (z *BigEndianField) ReadBits(n int) (v uint64, err error)
- func (z *BigEndianField) RotateLeft(x Field, rot int) Field
- func (z *BigEndianField) Set(x Field) Field
- func (z *BigEndianField) Xor(x, y Field) Field
- type BigEndianOrder
- func (be BigEndianOrder) Bit(x []byte, xofs int) uint
- func (be BigEndianOrder) Copy(z []byte, x []byte, zofs, xofs, w int) []byte
- func (be BigEndianOrder) Field(buf []byte, ofs, width int) Field
- func (be BigEndianOrder) Leading(z []byte, b uint) (n int)
- func (be BigEndianOrder) PutBit(z []byte, zofs int, v uint) []byte
- func (be BigEndianOrder) PutBytes(z []byte, zofs int, b []byte) []byte
- func (be BigEndianOrder) PutUint16(z []byte, zofs int, v uint16) []byte
- func (be BigEndianOrder) PutUint32(z []byte, zofs int, v uint32) []byte
- func (be BigEndianOrder) PutUint64(z []byte, zofs int, v uint64) []byte
- func (be BigEndianOrder) PutUint8(z []byte, zofs int, v uint8) []byte
- func (be BigEndianOrder) RotateLeft(z, x []byte, rot int) []byte
- func (be BigEndianOrder) Trailing(z []byte, b uint) (n int)
- func (be BigEndianOrder) Uint16(x []byte, xofs int) uint16
- func (be BigEndianOrder) Uint32(x []byte, xofs int) uint32
- func (be BigEndianOrder) Uint64(x []byte, xofs int) uint64
- func (be BigEndianOrder) Uint8(x []byte, xofs int) uint8
- type BitReader
- type BitWriter
- type Field
Constants ¶
This section is empty.
Variables ¶
var BigEndian = BigEndianOrder{}
BigEndian instantiates the BitOrder interface for bit-endian bit order.
var EOF = io.EOF
EOF represents an end-of-File error, and is identical to io.EOF.
Functions ¶
func And ¶
And sets z to the bitwise AND of slices x and y, and returns z. The source slices x and y must be of the same length. Allocates and returns a new destination slice if z is not long enough.
func AndNot ¶
AndNot sets z to the bitwise AND of slices x and NOT y, and returns z. The source slices x and y must be of the same length. Allocates and returns a new destination slice if z is not long enough.
func Grow ¶
Grow grows slice z to have a length of at least l. If z is already of length l or longer, just returns z. If z is shorter but the slice has capacity at least l, returns z[:l]. Otherwise, copies the contents of z to a new slice and returns it.
func Not ¶
Not sets z to the bitwise NOT of slice x, and returns z. Allocates and returns a new destination slice if z is not long enough.
Types ¶
type BigEndianField ¶
type BigEndianField field
BigEndianField represents a bit field within a byte slice interpreted as a big-endian sequence of bits.
func (*BigEndianField) And ¶
func (z *BigEndianField) And(x, y Field) Field
And sets the contents of bit field z to the bitwise AND of fields x and y, and returns z. The source fields x and y must be at least as long as field z.
func (*BigEndianField) AndNot ¶
func (z *BigEndianField) AndNot(x, y Field) Field
AndNot sets the contents of bit field z to the bitwise AND of fields x and NOT y, and returns z. The source fields x and y must be at least as long as field z.
func (*BigEndianField) Count ¶
func (z *BigEndianField) Count(b uint) (n int)
Count returns the number of bits with value b (0 or 1) in field z.
func (*BigEndianField) Fill ¶
func (z *BigEndianField) Fill(b uint)
Fill sets all bits in field z to bit value b (0 or 1).
func (*BigEndianField) Grow ¶
func (z *BigEndianField) Grow(buf []byte, ofs, width int) []byte
Grow points the field to a big-endian bit field within slice buf, copying buf to a new larger buffer if needed to include the bit field. Returns buf or the newly-allocated buffer if it was grown.
func (*BigEndianField) Init ¶
func (z *BigEndianField) Init(buf []byte, ofs, width int) Field
Init sets the field to refer to a big-endian bit field within slice buf, starting at bit offset ofs and extending for width bits. The caller must ensure that the underlying slice is large enough to contain the complete bit field specified; otherwise accesses to the bit field may yield bounds check panics.
func (*BigEndianField) Not ¶
func (z *BigEndianField) Not(x Field) Field
Not sets the contents of bit field z to the bitwise NOT of field x, and returns z. The source field x must be at least as long as field z.
func (*BigEndianField) Or ¶
func (z *BigEndianField) Or(x, y Field) Field
Or sets the contents of bit field z to the bitwise OR of fields x and y, and returns z. The source fields x and y must be at least as long as field z.
func (*BigEndianField) ReadBits ¶
func (z *BigEndianField) ReadBits(n int) (v uint64, err error)
ReadBits implements the BitReader interface, reading up to n bits from the start of the field, or 64 bits maximum. On success, returns the bits read in the least-significant bits of the returned value b, and shrinks the field to skip the n bits read. Returns an EOF error if the bit field is less than n bits wide.
func (*BigEndianField) RotateLeft ¶
func (z *BigEndianField) RotateLeft(x Field, rot int) Field
RotateLeft sets field z to field x rotated left by rot bits. To rotate right, pass a negative value for rot. Field x must be at least as long as z. The slices underlying x and z must not overlap, except if -7 <= rot <= 7, in which case x and z may be identical for small in-place bit rotations.
func (*BigEndianField) Set ¶
func (z *BigEndianField) Set(x Field) Field
Copy sets the contents of bit field z to that of field x, and returns z. The source field x must be at least as long as field z.
func (*BigEndianField) Xor ¶
func (z *BigEndianField) Xor(x, y Field) Field
Xor sets the contents of bit field z to the bitwise XOR of fields x and y, and returns z. The source fields x and y must be at least as long as field z.
type BigEndianOrder ¶
type BigEndianOrder struct{}
BigEndianOrder provides bitwise operations that treat the bits in each byte as having big-endian bit ordering.
You normally invoke its methods via the standard BigEndian instance. For example, to extract the 5-bit field illustrated above, you can invoke:
BigEndian.Bits(dst, src, 14, 5)
BigEndianOrder implements the BitOrder interface for big endian ordering. This interface may be used to parameterize the bit ordering in other code.
func (BigEndianOrder) Bit ¶
func (be BigEndianOrder) Bit(x []byte, xofs int) uint
Bit returns the value of the bit at position xofs bits from the left of x.
func (BigEndianOrder) Copy ¶
func (be BigEndianOrder) Copy(z []byte, x []byte, zofs, xofs, w int) []byte
Copy copies a bit-field of width bits starting at offset xofs in x into a field of the same width starting at offset zofs in z, then returns z. Copies z and returns a new slice if z is null or not large enough. All other bits within z are left unmodified.
func (BigEndianOrder) Leading ¶
func (be BigEndianOrder) Leading(z []byte, b uint) (n int)
Leading counts the number of consecutive leading bits with value b in slice z starting from the most-significant bit of the first byte.
func (BigEndianOrder) PutBit ¶
func (be BigEndianOrder) PutBit(z []byte, zofs int, v uint) []byte
PutBit sets the bit at zofs in slice z to bit value v. Copies z and returns a new slice if z is null or not large enough.
func (BigEndianOrder) PutBytes ¶
func (be BigEndianOrder) PutBytes(z []byte, zofs int, b []byte) []byte
PutBytes writes the contents of byte b slice into slice z at bit offset zofs. Copies z and returns a new slice if z is nil or not large enough.
func (BigEndianOrder) PutUint16 ¶
func (be BigEndianOrder) PutUint16(z []byte, zofs int, v uint16) []byte
PutUint16 sets the uint16 starting at zofs in slice z to value v. Copies z and returns a new slice if z is null or not large enough.
func (BigEndianOrder) PutUint32 ¶
func (be BigEndianOrder) PutUint32(z []byte, zofs int, v uint32) []byte
PutUint32 sets the uint32 starting at zofs in slice z to value v. Copies z and returns a new slice if z is null or not large enough.
func (BigEndianOrder) PutUint64 ¶
func (be BigEndianOrder) PutUint64(z []byte, zofs int, v uint64) []byte
PutUint64 sets the uint64 starting at zofs in slice z to value v. Copies z and returns a new slice if z is null or not large enough.
func (BigEndianOrder) PutUint8 ¶
func (be BigEndianOrder) PutUint8(z []byte, zofs int, v uint8) []byte
PutUint8 sets the uint8 starting at zofs in slice z to value v. Copies z and returns a new slice if z is null or not large enough.
func (BigEndianOrder) RotateLeft ¶
func (be BigEndianOrder) RotateLeft(z, x []byte, rot int) []byte
RotateLeft sets slice z to the contents of x rotated left by rot bits. To rotate right, pass a negative value for rot. Copies z and returns a new slice if z is nil or not large enough. The slices x and z must not overlap, except if -8 <= rot <= 8, in which case x and z may be identical for small in-place bit rotations.
func (BigEndianOrder) Trailing ¶
func (be BigEndianOrder) Trailing(z []byte, b uint) (n int)
Trailing counts the number of consecutive trailing bits with value b in slice z starting from the least-significant bit of the last byte.
func (BigEndianOrder) Uint16 ¶
func (be BigEndianOrder) Uint16(x []byte, xofs int) uint16
Uint16 extracts a uint16 starting at bit position xofs from the left of x.
func (BigEndianOrder) Uint32 ¶
func (be BigEndianOrder) Uint32(x []byte, xofs int) uint32
Uint32 extracts a uint32 starting at bit position xofs from the left of x.
type BitReader ¶
BitReader is an interface to a stream that supports reading a few bits at a time. The ReadBits method reads up to n bits from the stream into the least-significant bits of the returned value b, or reads 64 bits if n > 64. ReadBits returns the number of bits read and any error that occurred; the err return must be non-nil if r != n. Unlike the io.Reader interface, early EOF is considered an error: the BitReader must return EOF if the stream ends before reading n bits. Whether the least- or most-significant bits of the returned value b are treated as coming "first" depends on the endianness of the bit stream.
type BitWriter ¶
BitWriter is an interface to a stream that supports writing a few bits at a time.
The WriteBits method writes n bits to the stream from the least-significant bits of b, or writes 64 bits if n > 64. WriteBits returns nil if all n bits were successfully written or an error if not all n bits could be written. Whether WriteBits interprets the least- or most-significant bits of b as coming "first" depends on the endianness of the bit stream.
type Field ¶
type Field interface { Set(x Field) Field // Set to x And(x, y Field) Field // Set to x & y AndNot(x, y Field) Field // Set to x &^ y Or(x, y Field) Field // Set to x | y Xor(x, y Field) Field // Set to x ^ y Not(x Field) Field // Set to ^x Count(b uint) int // Count bits with value b Fill(b uint) // Fill with bit value b RotateLeft(x Field, rot int) Field }
Field is an interface to a bit-field providing common bit manipulation operations.