#bit #buffers #buffer #io #bits

bin+lib bit_buffers

A library for reading and writing individual bits to and from files

3 releases

Uses new Rust 2021

0.1.2 Aug 2, 2022
0.1.1 Jul 27, 2022
0.1.0 Jul 27, 2022
Download history 37/week @ 2022-07-24 37/week @ 2022-07-31 11/week @ 2022-08-07

85 downloads per month

MIT/Apache

16KB
125 lines

bit_buffers

The bit_buffers library allows for the reading and writing of individual bits to and from files.

doc tests

This library offers prototype versions of a bit reading entity and a bit writing entity that both keep track of how many bits are contained within them, and at which bit they are currently using.

Example Usage (writing bits to a file)

If you want to save a sequence of bits to a file, use a BitWriter.

// main.rs
use bit_buffers::BitWriter;

fn main() {

    // Create the writer
    let mut bit_writer = BitWriter::new();

    // Write out the desired bits
    bit_writer.write_bit(1);
    bit_writer.write_bit(0);
    bit_writer.write_bit(1);
    bit_writer.write_bit(1);
    bit_writer.write_bit(1);
    bit_writer.write_bit(1);
    bit_writer.write_bit(0);
    bit_writer.write_bit(1);

    // Save the bits to a file and clear out this writer
    bit_writer.flush_to_file("bit_sequence.bit");

}

Example Usage (reading bits from a file)

Later, if you want to read those same bits back in the order in which they were written, use a BitReader. A BitReader returns each bit in an Option, allowing the reader to return None after the last bit was read.

// main.rs
use bit_buffers::BitReader;

fn main() {

    // Load bits in from the file
    let mut bit_reader = BitReader::new();
    bit_reader.load_from_file("bit_sequence.bit");

    // Read those bits in from the file
    let bit_1_option = bit_reader.read_bit();
    let bit_2_option = bit_reader.read_bit();
    let bit_3_option = bit_reader.read_bit();
    let bit_4_option = bit_reader.read_bit();
    let bit_5_option = bit_reader.read_bit();
    let bit_6_option = bit_reader.read_bit();
    let bit_7_option = bit_reader.read_bit();
    let bit_8_option = bit_reader.read_bit();


    // After the last bit, None is returned
    let bit_9_option = bit_reader.read_bit();

    // Try and print the 9th bit
    if let Some(_) = bit_9_option {
        println!("There might still be more!");
    } else {
        println!("All bits were read in from the file!");
    }
}

Binary File Format

A simple format is used to write out bits to a file:

  • number of bits
  • bit data

Under the hood, a u128 type variable is used to count the number of bits in the file. As far as byte ordering is concerned, endianness is determined by the user's system.

When writing out the actual bit data, there may be atmost 7 extra bits of padding that are not included in the count.

When using a BitReader, it is best to use a file generated by a BitWriter, unless you are comfortable writing a file with the correct format describing the information you want.

Example Bit File

Consider the example program above demonstrating the use of a BitWriter. After a call to bit_writer.flush_to_file("bit_sequence.bit"), the following binary file is produced.

08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 BD

When viewed in a hex editor, that binary file may appear like this.

00000000    08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000010    BD

Future Goals

- Thread Safety

As of now, this library has not been tested in a multi-threaded application. Neither BitReader nor BitWriter are guaranteed to be thread safe at this time.

- Sharability

When reading and writing bits from and to files, the user's system determines the endianness. This may lead to problems when trying to share bit files across a network. A future goal is to standardize how the number of bits are written to and read from such files.

- Optimization

When bits are written to a BitWriter, they are written directly to an internal vector of bytes. The code as of now is messy and error-prone. Adding an additional buffer may simplify the underlying logic.

Additionally, for every 8 bits of data written, a re-allocation may need to take place. Adding features to allow users to reserve an expected amount of space may amortize the cost of reading and writing bits over time.

- Additional Features

Currently, there is no way for a user to index into the buffer to read specific bits or overwrite bits.

No runtime deps