Title: | Read and Write Bits from Files, Connections and Raw Vectors |
---|---|
Description: | Bit-level reading and writing are necessary when dealing with many file formats e.g. compressed data and binary files. Currently, R connections are manipulated at the byte level. This package wraps existing connections and raw vectors so that it is possible to read bits, bit sequences, unaligned bytes and low-bit representations of integers. |
Authors: | Mike Cheng [aut, cre, cph] |
Maintainer: | Mike Cheng <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.1.0 |
Built: | 2025-01-14 14:56:01 UTC |
Source: | CRAN |
Test if an object is a bitstream object and fail if it is not
assert_bs(x)
assert_bs(x)
x |
object to test |
None
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') assert_bs(bs) bs_close(bs)
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') assert_bs(bs) bs_close(bs)
Convert between logical vector of bits and raw vector
bits_to_raw(bits, msb_first = TRUE) raw_to_bits(x, msb_first = TRUE)
bits_to_raw(bits, msb_first = TRUE) raw_to_bits(x, msb_first = TRUE)
bits |
Logical vector of bit values. Length must be a multiple of 8 |
msb_first |
MSB first? Default: TRUE |
x |
Byte values. Integer vectors will be truncated to 8 bits before output. Numeric vectors will be rounded to integers and then truncated to 8 bits. Raw vectors preferred. |
Logical vector of bit values or a raw vector.
bits <- raw_to_bits(c(0, 4, 21)) bits bits_to_raw(bits) |> as.integer()
bits <- raw_to_bits(c(0, 4, 21)) bits bits_to_raw(bits) |> as.integer()
Convert between bits and unsigned integers
bits_to_uint(bits, nbits = NULL) uint_to_bits(x, nbits)
bits_to_uint(bits, nbits = NULL) uint_to_bits(x, nbits)
bits |
logical vector of bit values in MSB first order |
nbits |
number of bits per integer. If NULL, then |
x |
vector of unsigned integers |
logical vector of bit values of vector of unsigned integers
bits <- uint_to_bits(c(1, 2, 3), nbits = 3) bits bits_to_uint(bits, nbits = 3)
bits <- uint_to_bits(c(1, 2, 3), nbits = 3) bits bits_to_uint(bits, nbits = 3)
Advance bitstream
bs_advance(bs, n)
bs_advance(bs, n)
bs |
Bistream connection object created with |
n |
number of bits to advance |
Bitstream
connection returned invisibly
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') bs_is_aligned(bs) bs_advance(bs, 4) bs_is_aligned(bs) bs_read_bit(bs, 8) bs_is_aligned(bs) bs_close(bs)
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') bs_is_aligned(bs) bs_advance(bs, 4) bs_is_aligned(bs) bs_read_bit(bs, 8) bs_is_aligned(bs) bs_close(bs)
Align the bitstream to the given number of bits - relative to start of bitstream
bs_align(bs, nbits = 8L, value = FALSE)
bs_align(bs, nbits = 8L, value = FALSE)
bs |
Bistream connection object created with |
nbits |
number of bits of alignment w.r.t start of bitstream. Default: 8 |
value |
bit fill value. Either TRUE or FALSE. Default FALSE |
Bitstream
connection returned invisibly
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_is_aligned(bs, 8) bs_align(bs, nbits = 8) bs_is_aligned(bs, 8) output <- bs_close(bs) output
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_is_aligned(bs, 8) bs_align(bs, nbits = 8) bs_is_aligned(bs, 8) output <- bs_close(bs) output
This is called internally to flush bitstream buffers to the underlying R connection.
bs_flush(bs)
bs_flush(bs)
bs |
Bistream connection object created with |
Bitstream
connection returned invisibly
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_align(bs, nbits = 8) bs_flush(bs) output <- bs_close(bs) output
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_align(bs, nbits = 8) bs_flush(bs) output <- bs_close(bs) output
Is the current bit connection aligned at the given number of bits for reading/writing?
bs_is_aligned(bs, nbits = 8)
bs_is_aligned(bs, nbits = 8)
bs |
Bistream connection object created with |
nbits |
number of bits of alignment w.r.t start of bitstream. Default: 8 |
logical. TRUE if stream location is currently aligned to the specified number of bits, otherwise FALSE
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_is_aligned(bs, 8) bs_align(bs, nbits = 8) bs_is_aligned(bs, 8) output <- bs_close(bs) output
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_is_aligned(bs, 8) bs_align(bs, nbits = 8) bs_is_aligned(bs, 8) output <- bs_close(bs) output
Open/close a bitstream
bs_open(con, mode, msb_first = TRUE, flush_threshold = 1024 * 8) bs_close(bs, verbosity = 0)
bs_open(con, mode, msb_first = TRUE, flush_threshold = 1024 * 8) bs_close(bs, verbosity = 0)
con |
A vector of raw values or an R connection (e.g. |
mode |
Bitstream mode set to read or write? One of 'r', 'w', 'rb', 'wb'. |
msb_first |
Should the output mode be Most Signficant Bit first? Default: TRUE |
flush_threshold |
Threshold number of bits at which the buffered data
will be automatically written to the connection.
Default: 8192 bits (1024 bytes). Note: Use |
bs |
Bistream connection object created with |
verbosity |
Verbosity level. Default: 0 |
bs_open()
returns a bitstream
connection object. When the
connection is a raw vector and mode = 'w'
, bs_close()
returns
the final state of the raw vector; in all other cases bs_close()
does not return a value.
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') assert_bs(bs) bs_close(bs)
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') assert_bs(bs) bs_close(bs)
Peek at bits from a bitstream i.e. examine bits without advancing bitstream
bs_peek(bs, n)
bs_peek(bs, n)
bs |
Bistream connection object created with |
n |
number of bits to peek. |
logical vector of bit values
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') bs_peek(bs, 4) stopifnot(bs_is_aligned(bs)) bs_close(bs)
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') bs_peek(bs, 4) stopifnot(bs_is_aligned(bs)) bs_close(bs)
Read bits from a bitstream
bs_read_bit(bs, n)
bs_read_bit(bs, n)
bs |
Bistream connection object created with |
n |
number of bits to read |
logical vector of bit values
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') bs_read_bit(bs, 4) bs_is_aligned(bs) bs_close(bs)
raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') bs_read_bit(bs, 4) bs_is_aligned(bs) bs_close(bs)
Write unaligned bits to a bitstream
bs_write_bit(bs, x)
bs_write_bit(bs, x)
bs |
Bistream connection object created with |
x |
Logical vector of bit values |
Bitstream
connection returned invisibly
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_align(bs, nbits = 8) bs_flush(bs) output <- bs_close(bs) output
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE, TRUE)) bs_align(bs, nbits = 8) bs_flush(bs) output <- bs_close(bs) output
Read/Write unaligned bytes with a bitstream
bs_write_byte(bs, x) bs_read_byte(bs, n)
bs_write_byte(bs, x) bs_read_byte(bs, n)
bs |
Bistream connection object created with |
x |
vector of bytes to write. Integer vectors will be truncated to 8 bits before output. Numeric vectors will be rounded to integers and then truncated to 8 bits. |
n |
number of bytes to read |
Reading returns a logical vector of bit values. When writing,
the bs
bitstream connection is returned invisibly
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE)) bs_write_byte(bs, c(1, 2, 3)) bs_align(bs) raw_vec <- bs_close(bs) bs <- bs_open(raw_vec, 'r') bs_read_bit(bs, 2) bs_read_byte(bs, 3) bs_close(bs)
bs <- bs_open(raw(), 'w') bs_write_bit(bs, c(TRUE, FALSE)) bs_write_byte(bs, c(1, 2, 3)) bs_align(bs) raw_vec <- bs_close(bs) bs <- bs_open(raw_vec, 'r') bs_read_bit(bs, 2) bs_read_byte(bs, 3) bs_close(bs)
Read/Write Exponential-Golomb encoded signed integers
bs_write_sint_exp_golomb(bs, x) bs_read_sint_exp_golomb(bs, n = 1L)
bs_write_sint_exp_golomb(bs, x) bs_read_sint_exp_golomb(bs, n = 1L)
bs |
Bistream connection object created with |
x |
integer vector to write |
n |
number of encoded integers to read |
Reading returns a vector of integers. Writing returns the bitstream invisibly.
bs <- bs_open(raw(), 'w') bs_write_sint_exp_golomb(bs, c(0, 4, -21)) raw_vec <- bs_close(bs) raw_vec bs <- bs_open(raw_vec, 'r') bs_read_sint_exp_golomb(bs, 3) bs_close(bs)
bs <- bs_open(raw(), 'w') bs_write_sint_exp_golomb(bs, c(0, 4, -21)) raw_vec <- bs_close(bs) raw_vec bs <- bs_open(raw_vec, 'r') bs_read_sint_exp_golomb(bs, 3) bs_close(bs)
Read/Write unsigned integers
bs_write_uint(bs, x, nbits) bs_read_uint(bs, nbits, n = 1L)
bs_write_uint(bs, x, nbits) bs_read_uint(bs, nbits, n = 1L)
bs |
Bistream connection object created with |
x |
integer vector to write |
nbits |
the number of bits used for each integer |
n |
number of integers to read |
Reading returns a vector of non-negative integers. Writing returns the bitstream invisibly.
bs <- bs_open(raw(), 'w') bs_write_uint(bs, c(0, 4, 21), nbits = 5) bs_align(bs, 8) raw_vec <- bs_close(bs) raw_vec bs <- bs_open(raw_vec, 'r') bs_read_uint(bs, n = 3, nbits = 5) bs_close(bs)
bs <- bs_open(raw(), 'w') bs_write_uint(bs, c(0, 4, 21), nbits = 5) bs_align(bs, 8) raw_vec <- bs_close(bs) raw_vec bs <- bs_open(raw_vec, 'r') bs_read_uint(bs, n = 3, nbits = 5) bs_close(bs)
Read/Write Exponential-Golomb encoded non-negative integers
bs_write_uint_exp_golomb(bs, x) bs_read_uint_exp_golomb(bs, n = 1L)
bs_write_uint_exp_golomb(bs, x) bs_read_uint_exp_golomb(bs, n = 1L)
bs |
Bistream connection object created with |
x |
integer vector to write |
n |
number of encoded integers to read |
Reading returns a vector of non-negative integers. Writing returns the bitstream invisibly.
bs <- bs_open(raw(), 'w') bs_write_uint_exp_golomb(bs, c(0, 4, 21)) bs_align(bs, 8) raw_vec <- bs_close(bs) raw_vec bs <- bs_open(raw_vec, 'r') bs_read_uint_exp_golomb(bs, 3) bs_close(bs)
bs <- bs_open(raw(), 'w') bs_write_uint_exp_golomb(bs, c(0, 4, 21)) bs_align(bs, 8) raw_vec <- bs_close(bs) raw_vec bs <- bs_open(raw_vec, 'r') bs_read_uint_exp_golomb(bs, 3) bs_close(bs)
Test if an object is a bitstream object
is_bs(x)
is_bs(x)
x |
object to test |
logical. TRUE if object is a bitstream object
# Negative case is_bs(NULL) # Positive case raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') is_bs(bs) bs_close(bs)
# Negative case is_bs(NULL) # Positive case raw_vec <- as.raw(1:3) bs <- bs_open(raw_vec, 'r') is_bs(bs) bs_close(bs)
Pad a logical vector to the given size
pad_bits(bits, nbits = 8L, side = "left", value = FALSE)
pad_bits(bits, nbits = 8L, side = "left", value = FALSE)
bits |
logical vector |
nbits |
Pad width to a multiple of this number of bits |
side |
'left' or 'right'. Only the lowercase version of the first letter is used to determine the side. all of these are valid options: 'L', 'R', 'left', 'Right' |
value |
The value to use for padding. single logical value. Default: FALSE |
Logical vector with the specified padding
pad_bits(c(TRUE, TRUE), nbits = 8, side = 'left') pad_bits(c(TRUE, TRUE), nbits = 8, side = 'R')
pad_bits(c(TRUE, TRUE), nbits = 8, side = 'left') pad_bits(c(TRUE, TRUE), nbits = 8, side = 'R')
Convert between signed integers and Exponential-Golomb bit sequences
sint_to_exp_golomb_bits(x) exp_golomb_bits_to_sint(bits, n = 1)
sint_to_exp_golomb_bits(x) exp_golomb_bits_to_sint(bits, n = 1)
x |
integer vector with all values >= 0 |
bits |
logical vector of bit values |
n |
number of values to decode. Default: 1. Set to 'Inf' to decode all bits. Will raise an error if there are extra bits at the end that are unused. |
logical vector of bit values, or vector of signed integers
bits <- sint_to_exp_golomb_bits(c(0, 4, -21)) bits exp_golomb_bits_to_sint(bits, n = 3)
bits <- sint_to_exp_golomb_bits(c(0, 4, -21)) bits exp_golomb_bits_to_sint(bits, n = 3)
Convert between non-negative integers and Exponential Golomb bit sequences
uint_to_exp_golomb_bits(x) exp_golomb_bits_to_uint(bits, n = 1)
uint_to_exp_golomb_bits(x) exp_golomb_bits_to_uint(bits, n = 1)
x |
integer vector with all values >= 0 |
bits |
logical vector of bit values |
n |
number of values to decode. Default: 1. Set to 'Inf' to decode all bits. Will raise an error if there are extra bits at the end that are not properly encoded integers |
logical vector of bit values, or vector of non-negative integers
bits <- uint_to_exp_golomb_bits(c(0, 4, 21)) bits exp_golomb_bits_to_uint(bits, n = 3)
bits <- uint_to_exp_golomb_bits(c(0, 4, 21)) bits exp_golomb_bits_to_uint(bits, n = 3)