Struct bitstream_io::write::BitWriter
source · pub struct BitWriter<W: Write, E: Endianness> { /* private fields */ }
Expand description
For writing bit values to an underlying stream in a given endianness.
Because this only writes whole bytes to the underlying stream, it is important that output is byte-aligned before the bitstream writer’s lifetime ends. Partial bytes will be lost if the writer is disposed of before they can be written.
Implementations
sourceimpl<W: Write, E: Endianness> BitWriter<W, E>
impl<W: Write, E: Endianness> BitWriter<W, E>
sourcepub fn new(writer: W) -> BitWriter<W, E>
pub fn new(writer: W) -> BitWriter<W, E>
Wraps a BitWriter around something that implements Write
sourcepub fn endian(writer: W, _endian: E) -> BitWriter<W, E>
pub fn endian(writer: W, _endian: E) -> BitWriter<W, E>
Wraps a BitWriter around something that implements Write
with the given endianness.
sourcepub fn into_writer(self) -> W
pub fn into_writer(self) -> W
Unwraps internal writer and disposes of BitWriter. Any unwritten partial bits are discarded.
sourcepub fn write_bit(&mut self, bit: bool) -> Result<()>
pub fn write_bit(&mut self, bit: bool) -> Result<()>
Writes a single bit to the stream.
true
indicates 1, false
indicates 0
Errors
Passes along any I/O error from the underlying stream.
Examples
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_bit(true).unwrap();
writer.write_bit(false).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(false).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(true).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write_bit(true).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(false).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(true).unwrap();
writer.write_bit(false).unwrap();
writer.write_bit(true).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
sourcepub fn write<U>(&mut self, bits: u32, value: U) -> Result<()>where
U: Numeric,
pub fn write<U>(&mut self, bits: u32, value: U) -> Result<()>where
U: Numeric,
Writes an unsigned value to the stream using the given number of bits.
Errors
Passes along any I/O error from the underlying stream. Returns an error if the input type is too small to hold the given number of bits. Returns an error if the value is too large to fit the given number of bits.
Examples
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write(1, 0b1).unwrap();
writer.write(2, 0b01).unwrap();
writer.write(5, 0b10111).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write(1, 0b1).unwrap();
writer.write(2, 0b11).unwrap();
writer.write(5, 0b10110).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use std::io::{Write, sink};
use bitstream_io::{BigEndian, BitWriter};
let mut w = BitWriter::endian(sink(), BigEndian);
assert!(w.write(9, 0u8).is_err()); // can't write u8 in 9 bits
assert!(w.write(17, 0u16).is_err()); // can't write u16 in 17 bits
assert!(w.write(33, 0u32).is_err()); // can't write u32 in 33 bits
assert!(w.write(65, 0u64).is_err()); // can't write u64 in 65 bits
assert!(w.write(1, 2).is_err()); // can't write 2 in 1 bit
assert!(w.write(2, 4).is_err()); // can't write 4 in 2 bits
assert!(w.write(3, 8).is_err()); // can't write 8 in 3 bits
assert!(w.write(4, 16).is_err()); // can't write 16 in 4 bits
sourcepub fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<()>where
S: SignedNumeric,
pub fn write_signed<S>(&mut self, bits: u32, value: S) -> Result<()>where
S: SignedNumeric,
Writes a twos-complement signed value to the stream with the given number of bits.
Errors
Passes along any I/O error from the underlying stream. Returns an error if the input type is too small to hold the given number of bits. Returns an error if the value is too large to fit the given number of bits.
Examples
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_signed(4, -5).unwrap();
writer.write_signed(4, 7).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write_signed(4, 7).unwrap();
writer.write_signed(4, -5).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
sourcepub fn write_bytes(&mut self, buf: &[u8]) -> Result<()>
pub fn write_bytes(&mut self, buf: &[u8]) -> Result<()>
Writes the entirety of a byte buffer to the stream.
If the stream is already byte-aligned, it will
map to a faster write_all
call. Otherwise it will
write bytes individually in 8-bit increments.
Errors
Passes along any I/O error from the underlying stream.
Example
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write(8, 0x66).unwrap();
writer.write(8, 0x6F).unwrap();
writer.write(8, 0x6F).unwrap();
writer.write_bytes(b"bar").unwrap();
assert_eq!(writer.into_writer(), b"foobar");
sourcepub fn write_huffman<T>(
&mut self,
tree: &WriteHuffmanTree<E, T>,
symbol: T
) -> Result<()>where
T: Ord + Copy,
pub fn write_huffman<T>(
&mut self,
tree: &WriteHuffmanTree<E, T>,
symbol: T
) -> Result<()>where
T: Ord + Copy,
Writes Huffman code for the given symbol to the stream.
Errors
Passes along any I/O error from the underlying stream.
Example
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
use bitstream_io::huffman::compile_write_tree;
let tree = compile_write_tree(
vec![('a', vec![0]),
('b', vec![1, 0]),
('c', vec![1, 1, 0]),
('d', vec![1, 1, 1])]).unwrap();
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_huffman(&tree, 'b').unwrap();
writer.write_huffman(&tree, 'c').unwrap();
writer.write_huffman(&tree, 'd').unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
sourcepub fn write_unary0(&mut self, value: u32) -> Result<()>
pub fn write_unary0(&mut self, value: u32) -> Result<()>
Writes value
number of 1 bits to the stream
and then writes a 0 bit. This field is variably-sized.
Errors
Passes along any I/O error from the underyling stream.
Examples
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_unary0(0).unwrap();
writer.write_unary0(3).unwrap();
writer.write_unary0(10).unwrap();
assert_eq!(writer.into_writer(), [0b01110111, 0b11111110]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write_unary0(0).unwrap();
writer.write_unary0(3).unwrap();
writer.write_unary0(10).unwrap();
assert_eq!(writer.into_writer(), [0b11101110, 0b01111111]);
sourcepub fn write_unary1(&mut self, value: u32) -> Result<()>
pub fn write_unary1(&mut self, value: u32) -> Result<()>
Writes value
number of 0 bits to the stream
and then writes a 1 bit. This field is variably-sized.
Errors
Passes along any I/O error from the underyling stream.
Example
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_unary1(0).unwrap();
writer.write_unary1(3).unwrap();
writer.write_unary1(10).unwrap();
assert_eq!(writer.into_writer(), [0b10001000, 0b00000001]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write_unary1(0).unwrap();
writer.write_unary1(3).unwrap();
writer.write_unary1(10).unwrap();
assert_eq!(writer.into_writer(), [0b00010001, 0b10000000]);
sourcepub fn byte_aligned(&self) -> bool
pub fn byte_aligned(&self) -> bool
Returns true if the stream is aligned at a whole byte.
Example
use std::io::{Write, sink};
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(sink(), BigEndian);
assert_eq!(writer.byte_aligned(), true);
writer.write(1, 0).unwrap();
assert_eq!(writer.byte_aligned(), false);
writer.write(7, 0).unwrap();
assert_eq!(writer.byte_aligned(), true);
sourcepub fn byte_align(&mut self) -> Result<()>
pub fn byte_align(&mut self) -> Result<()>
Pads the stream with 0 bits until it is aligned at a whole byte. Does nothing if the stream is already aligned.
Errors
Passes along any I/O error from the underyling stream.
Example
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write(1, 0).unwrap();
writer.byte_align().unwrap();
writer.write(8, 0xFF).unwrap();
assert_eq!(writer.into_writer(), [0x00, 0xFF]);
sourcepub fn into_unwritten(self) -> (u32, u8)
pub fn into_unwritten(self) -> (u32, u8)
Consumes writer and returns any un-written partial byte
as a (bits, value)
tuple.
Examples
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut data = Vec::new();
let (bits, value) = {
let mut writer = BitWriter::endian(&mut data, BigEndian);
writer.write(15, 0b1010_0101_0101_101).unwrap();
writer.into_unwritten()
};
assert_eq!(data, [0b1010_0101]);
assert_eq!(bits, 7);
assert_eq!(value, 0b0101_101);
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter};
let mut data = Vec::new();
let (bits, value) = {
let mut writer = BitWriter::endian(&mut data, BigEndian);
writer.write(8, 0b1010_0101).unwrap();
writer.into_unwritten()
};
assert_eq!(data, [0b1010_0101]);
assert_eq!(bits, 0);
assert_eq!(value, 0);