Trait BitWrite

Source
pub trait BitWrite {
Show 23 methods // Required methods fn write_unsigned_counted<const BITS: u32, U>( &mut self, bits: BitCount<BITS>, value: U, ) -> Result<()> where U: UnsignedInteger; fn write_signed_counted<const MAX: u32, S>( &mut self, bits: impl TryInto<SignedBitCount<MAX>>, value: S, ) -> Result<()> where S: SignedInteger; fn write_from<V>(&mut self, value: V) -> Result<()> where V: Primitive; fn write_as_from<F, V>(&mut self, value: V) -> Result<()> where F: Endianness, V: Primitive; fn byte_aligned(&self) -> bool; // Provided methods fn write_bit(&mut self, bit: bool) -> Result<()> { ... } fn write<const BITS: u32, I>(&mut self, value: I) -> Result<()> where I: Integer { ... } fn write_var<I>(&mut self, bits: u32, value: I) -> Result<()> where I: Integer { ... } fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> Result<()> where U: UnsignedInteger { ... } fn write_unsigned_var<U>(&mut self, bits: u32, value: U) -> Result<()> where U: UnsignedInteger { ... } fn write_signed<const BITS: u32, S>(&mut self, value: S) -> Result<()> where S: SignedInteger { ... } fn write_signed_var<S>(&mut self, bits: u32, value: S) -> Result<()> where S: SignedInteger { ... } fn write_count<const MAX: u32>(&mut self, _: BitCount<MAX>) -> Result<()> { ... } fn write_counted<const MAX: u32, I>( &mut self, bits: BitCount<MAX>, value: I, ) -> Result<()> where I: Integer + Sized { ... } fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> Result<()> { ... } fn pad(&mut self, bits: u32) -> Result<()> { ... } fn write_bytes(&mut self, buf: &[u8]) -> Result<()> { ... } fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> Result<()> { ... } fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> { ... } fn build_with<'a, T: ToBitStreamWith<'a>>( &mut self, build: &T, context: &T::Context, ) -> Result<(), T::Error> { ... } fn byte_align(&mut self) -> Result<()> { ... } fn write_huffman<T>(&mut self, value: T::Symbol) -> Result<()> where T: ToBits { ... } fn by_ref(&mut self) -> &mut Self { ... }
}
Expand description

A trait for anything that can write a variable number of potentially un-aligned values to an output stream

Required Methods§

Source

fn write_unsigned_counted<const BITS: u32, U>( &mut self, bits: BitCount<BITS>, value: U, ) -> Result<()>
where U: UnsignedInteger,

Writes a 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 value is too large to fit the given number of bits.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian, BitCount};

let mut w = BitWriter::endian(vec![], BigEndian);
// writing 4 bits with a maximum of 8 will fit into a u8
// so we only need check the value fits into 4 bits
assert!(w.write_unsigned_counted::<4, u8>(BitCount::new::<4>(), 0b1111).is_ok());
assert!(w.write_unsigned_counted::<4, u8>(BitCount::new::<4>(), 0b1111 + 1).is_err());
// writing 4 bits with a maximum of 64 might not fit into a u8
// so need to verify this at runtime
assert!(w.write_unsigned_counted::<64, u8>(BitCount::new::<4>(), 0b0000).is_ok());
assert_eq!(w.into_writer(), &[0b1111_0000]);
Source

fn write_signed_counted<const MAX: u32, S>( &mut self, bits: impl TryInto<SignedBitCount<MAX>>, value: S, ) -> Result<()>
where S: SignedInteger,

Writes an unsigned 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 value is too large to fit the given number of bits.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian, BitCount};

let mut w = BitWriter::endian(vec![], BigEndian);
// writing 4 bits with a maximum of 8 will fit into an i8
// so we only need check the value fits into 4 bits
assert!(w.write_signed_counted::<4, i8>(BitCount::new::<4>(), 0b0111).is_ok());
assert!(w.write_signed_counted::<4, i8>(BitCount::new::<4>(), 0b0111 + 1).is_err());
// writing 4 bits with a maximum of 64 might not fit into a i8
// so need to verify this at runtime
assert!(w.write_signed_counted::<64, i8>(BitCount::new::<4>(), 0b0000).is_ok());
assert_eq!(w.into_writer(), &[0b0111_0000]);
Source

fn write_from<V>(&mut self, value: V) -> Result<()>
where V: Primitive,

Writes whole value to the stream whose size in bits is equal to its type’s size.

§Errors

Passes along any I/O error from the underlying stream.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
assert!(w.write_from::<u32>(0x12_34_56_78).is_ok());
assert_eq!(w.into_writer(), &[0x12, 0x34, 0x56, 0x78]);
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
assert!(w.write_from::<[u8; 4]>([0x12, 0x34, 0x56, 0x78]).is_ok());
assert_eq!(w.into_writer(), &[0x12, 0x34, 0x56, 0x78]);
Source

fn write_as_from<F, V>(&mut self, value: V) -> Result<()>
where F: Endianness, V: Primitive,

Writes whole value to the stream whose size in bits is equal to its type’s size in an endianness that may be different from the stream’s endianness.

§Errors

Passes along any I/O error from the underlying stream.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian, LittleEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
assert!(w.write_as_from::<LittleEndian, u32>(0x12_34_56_78).is_ok());
assert_eq!(w.into_writer(), &[0x78, 0x56, 0x34, 0x12]);
Source

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, BitWrite};
let mut writer = BitWriter::endian(sink(), BigEndian);
assert_eq!(writer.byte_aligned(), true);
writer.write_var(1, 0u8).unwrap();
assert_eq!(writer.byte_aligned(), false);
writer.write_var(7, 0u8).unwrap();
assert_eq!(writer.byte_aligned(), true);

Provided Methods§

Source

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 bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w  = BitWriter::endian(vec![], BigEndian);
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(false).is_ok());
assert_eq!(w.into_writer(), &[0b1000_1110]);
use bitstream_io::{BitWriter, BitWrite, LittleEndian};

let mut w  = BitWriter::endian(vec![], LittleEndian);
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(true).is_ok());
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(false).is_ok());
assert!(w.write_bit(true).is_ok());
assert_eq!(w.into_writer(), &[0b1000_1110]);
Examples found in repository?
examples/flac-metadata-write.rs (line 24)
23    fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
24        w.write_bit(self.last_block)?;
25        w.write::<7, _>(self.block_type)?;
26        w.write::<24, _>(self.block_size)
27    }
Source

fn write<const BITS: u32, I>(&mut self, value: I) -> Result<()>
where I: Integer,

Writes a signed or unsigned value to the stream using the given const number of bits.

§Errors

Passes along any I/O error from the underlying stream. Returns an error if the value is too large to fit the given number of bits. A compile-time error occurs if the given number of bits is larger than the output type.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
// writing unsigned value is ok
assert!(w.write::<4, u8>(1).is_ok());
// writing signed value is ok
assert!(w.write::<4, i8>(-1).is_ok());
// writing an array of bits is ok too
assert!(w.write::<1, [bool; 4]>([true, false, true, true]).is_ok());
// writing an array of any Integer type is ok
assert!(w.write::<2, [u8; 2]>([0b11, 0b00]).is_ok());
// trying to write a value larger than 4 bits in 4 bits is an error
assert!(w.write::<4, u8>(u8::MAX).is_err());

assert_eq!(w.into_writer(), &[0b0001_1111, 0b1011_11_00]);
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
// trying to write 9 bits from a u8 is a compile-time error
w.write::<9, u8>(1);
Examples found in repository?
examples/flac-metadata-write.rs (line 25)
23    fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
24        w.write_bit(self.last_block)?;
25        w.write::<7, _>(self.block_type)?;
26        w.write::<24, _>(self.block_size)
27    }
28}
29
30#[derive(Debug, PartialEq, Eq)]
31struct Streaminfo {
32    minimum_block_size: u16,      // 16 bits
33    maximum_block_size: u16,      // 16 bits
34    minimum_frame_size: u32,      // 24 bits
35    maximum_frame_size: u32,      // 24 bits
36    sample_rate: u32,             // 20 bits
37    channels: NonZero<u8>,        // 3 bits
38    bits_per_sample: NonZero<u8>, // 5 bits
39    total_samples: u64,           // 36 bits
40    md5: [u8; 16],                // 16 bytes
41}
42
43impl ToBitStream for Streaminfo {
44    type Error = std::io::Error;
45
46    fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
47        w.write_from(self.minimum_block_size)?;
48        w.write_from(self.maximum_block_size)?;
49        w.write::<24, _>(self.minimum_frame_size)?;
50        w.write::<24, _>(self.maximum_frame_size)?;
51        w.write::<20, _>(self.sample_rate)?;
52        w.write::<3, _>(self.channels)?;
53        w.write::<5, _>(self.bits_per_sample)?;
54        w.write::<36, _>(self.total_samples)?;
55        w.write_bytes(&self.md5)
56    }
Source

fn write_var<I>(&mut self, bits: u32, value: I) -> Result<()>
where I: Integer,

Writes a signed or 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 bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
// writing unsigned value is ok
assert!(w.write_var::<u8>(4, 1).is_ok());
// writing signed value is also ok
assert!(w.write_var::<i8>(4, -1).is_ok());
assert_eq!(w.into_writer(), &[0b0001_1111]);
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
// writing a value larger than 4 bits in 4 bits is a runtime error
assert!(w.write_var::<u8>(4, u8::MAX).is_err());
// writing 9 bits from a u8 is also a runtime error
assert!(w.write_var::<u8>(9, 0).is_err());
Source

fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> Result<()>
where U: UnsignedInteger,

Writes an unsigned value to the stream using the given const number of bits.

§Errors

Passes along any I/O error from the underlying stream. Returns an error if the value is too large to fit the given number of bits. A compile-time error occurs if the given number of bits is larger than the output type.

§Examples
use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], BigEndian);
writer.write_unsigned::<1, u8>(0b1).unwrap();
writer.write_unsigned::<2, u8>(0b01).unwrap();
writer.write_unsigned::<5, u8>(0b10111).unwrap();
assert_eq!(writer.into_writer(), [0b1_01_10111]);
use bitstream_io::{LittleEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], LittleEndian);
writer.write_unsigned::<1, u8>(0b1).unwrap();
writer.write_unsigned::<2, u8>(0b11).unwrap();
writer.write_unsigned::<5, u8>(0b10110).unwrap();
assert_eq!(writer.into_writer(), [0b10110_11_1]);
use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], BigEndian);
// trying to write 9 bits from a u8 is a compile-time error
writer.write_unsigned::<9, u8>(1);
use std::io::{Write, sink};
use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut w = BitWriter::endian(sink(), BigEndian);
assert!(w.write_unsigned::<1, u8>(2).is_err());    // can't write   2 in 1 bit
assert!(w.write_unsigned::<2, u8>(4).is_err());    // can't write   4 in 2 bits
assert!(w.write_unsigned::<3, u8>(8).is_err());    // can't write   8 in 3 bits
assert!(w.write_unsigned::<4, u8>(16).is_err());   // can't write  16 in 4 bits
Source

fn write_unsigned_var<U>(&mut self, bits: u32, value: U) -> Result<()>
where U: UnsignedInteger,

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 bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], BigEndian);
writer.write_unsigned_var::<u8>(1, 0b1).unwrap();
writer.write_unsigned_var::<u8>(2, 0b01).unwrap();
writer.write_unsigned_var::<u8>(5, 0b10111).unwrap();
assert_eq!(writer.into_writer(), [0b1_01_10111]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], LittleEndian);
writer.write_unsigned_var::<u8>(1, 0b1).unwrap();
writer.write_unsigned_var::<u8>(2, 0b11).unwrap();
writer.write_unsigned_var::<u8>(5, 0b10110).unwrap();
assert_eq!(writer.into_writer(), [0b10110_11_1]);
use std::io::{Write, sink};
use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut w = BitWriter::endian(sink(), BigEndian);
assert!(w.write_unsigned_var::<u8>(9, 0).is_err());    // can't write  u8 in 9 bits
assert!(w.write_unsigned_var::<u16>(17, 0).is_err());  // can't write u16 in 17 bits
assert!(w.write_unsigned_var::<u32>(33, 0).is_err());  // can't write u32 in 33 bits
assert!(w.write_unsigned_var::<u64>(65, 0).is_err());  // can't write u64 in 65 bits
assert!(w.write_unsigned_var::<u8>(1, 2).is_err());    // can't write   2 in 1 bit
assert!(w.write_unsigned_var::<u8>(2, 4).is_err());    // can't write   4 in 2 bits
assert!(w.write_unsigned_var::<u8>(3, 8).is_err());    // can't write   8 in 3 bits
assert!(w.write_unsigned_var::<u8>(4, 16).is_err());   // can't write  16 in 4 bits
Source

fn write_signed<const BITS: u32, S>(&mut self, value: S) -> Result<()>
where S: SignedInteger,

Writes a twos-complement signed value to the stream with the given const number of bits.

§Errors

Passes along any I/O error from the underlying stream. Returns an error if the value is too large to fit the given number of bits. A compile-time error occurs if the number of bits is 0, since one bit is always needed for the sign. A compile-time error occurs if the given number of bits is larger than the output type.

§Examples
use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], BigEndian);
writer.write_signed::<4, i8>(-5).unwrap();
writer.write_signed::<4, i8>(7).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use bitstream_io::{LittleEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], LittleEndian);
writer.write_signed::<4, i8>(7).unwrap();
writer.write_signed::<4, i8>(-5).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use bitstream_io::{LittleEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], LittleEndian);
// writing a value too large for 4 bits in 4 bits is a runtime error
assert!(writer.write_signed::<4, i8>(i8::MAX).is_err());
use bitstream_io::{LittleEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], LittleEndian);
// writing 9 bits from an i8 is a compile-time error
assert!(writer.write_signed::<9, i8>(1).is_err());
Source

fn write_signed_var<S>(&mut self, bits: u32, value: S) -> Result<()>
where S: SignedInteger,

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 number of bits is 0, since one bit is always needed for the sign. Returns an error if the value is too large to fit the given number of bits.

§Examples
use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], BigEndian);
writer.write_signed_var(4, -5).unwrap();
writer.write_signed_var(4, 7).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
use bitstream_io::{LittleEndian, BitWriter, BitWrite};

let mut writer = BitWriter::endian(vec![], LittleEndian);
writer.write_signed_var(4, 7).unwrap();
writer.write_signed_var(4, -5).unwrap();
assert_eq!(writer.into_writer(), [0b10110111]);
Source

fn write_count<const MAX: u32>(&mut self, _: BitCount<MAX>) -> Result<()>

Writes the given bit count to the stream with the necessary maximum number of bits.

For example, if the maximum bit count is 15 - or 0b1111 - writes the bit count to the stream as a 4-bit unsigned value which can be used in subsequent writes.

Note that MAX must be greater than 0. Unlike the bit reader, the bit count need not be an exact power of two when writing. Any bits higher than the bit count can reach are simply left 0.

§Errors

Passes along an I/O error from the underlying stream.

use bitstream_io::{BigEndian, BitWriter, BitWrite};

let mut w = BitWriter::endian(vec![], BigEndian);
let count = 4;
w.write::<3, u32>(count).unwrap();
// may need to verify count is not larger than u8 at runtime
w.write_var::<u8>(count, 0b1111).unwrap();
w.byte_align().unwrap();
assert_eq!(w.into_writer(), &[0b100_11110]);
use bitstream_io::{BigEndian, BitWriter, BitWrite, BitCount};

let mut w = BitWriter::endian(vec![], BigEndian);
// a bit count of 4, with a maximum of 7 (0b111)
let count: BitCount<0b111> = BitCount::new::<4>();
w.write_count(count).unwrap();
// maximum size of count is known to be 7 bits at compile-time
// so no need to check that 7 bits is larger than a u8 at runtime
w.write_counted::<0b111, u8>(count, 0b1111).unwrap();
w.byte_align().unwrap();
assert_eq!(w.into_writer(), &[0b100_11110]);
use bitstream_io::{BigEndian, BitWriter, BitWrite, BitCount};

let mut w = BitWriter::endian(vec![], BigEndian);
// a bit count of 4, with a maximum of 6 (0b110)
let count: BitCount<0b110> = BitCount::new::<4>();
w.write_count(count).unwrap();
w.write_counted::<0b110, u8>(count, 0b1111).unwrap();
w.byte_align().unwrap();
// bit count is written in 3 bits
// while actual value is written in 4 bits
assert_eq!(w.into_writer(), &[0b100_11110]);
Source

fn write_counted<const MAX: u32, I>( &mut self, bits: BitCount<MAX>, value: I, ) -> Result<()>
where I: Integer + Sized,

Writes a signed or unsigned 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 value is too large to fit the given number of bits.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian, BitCount};

let mut w = BitWriter::endian(vec![], BigEndian);
// writing 4 bits with a maximum of 8 will fit into a u8
// so we only need check the value fits into 4 bits
assert!(w.write_counted::<4, u8>(BitCount::new::<4>(), 0b1111).is_ok());
assert!(w.write_counted::<4, u8>(BitCount::new::<4>(), 0b1111 + 1).is_err());
// writing 4 bits with a maximum of 64 might not fit into a u8
// so need to verify this at runtime
assert!(w.write_counted::<64, u8>(BitCount::new::<4>(), 0b0000).is_ok());
assert_eq!(w.into_writer(), &[0b1111_0000]);
Source

fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> Result<()>

Writes the given constant value to the stream with the given number of bits.

Due to current limitations of constant parameters, this is limited to u32 values.

§Errors

Passes along any I/O error from the underlying stream. A compile-time error occurs if the number of bits is larger than 32 or if the value is too large too fit the requested number of bits.

§Examples
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
assert!(w.write_const::<4, 0b1000>().is_ok());
assert!(w.write_const::<4, 0b1011>().is_ok());
assert_eq!(w.into_writer(), &[0b1000_1011]);
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
// trying to write a 5 bit value in 4 bits is a compile-time error
w.write_const::<4, 0b11111>();
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
// trying to write a 33 bit value is also a compile-time error
w.write_const::<33, 1>();
Source

fn pad(&mut self, bits: u32) -> Result<()>

Pads the stream by writing 0 over the given number of bits.

§Errors

Passes along any I/O error from the underlying stream.

§Example
use bitstream_io::{BitWriter, BitWrite, BigEndian};

let mut w = BitWriter::endian(vec![], BigEndian);
assert!(w.write_bit(true).is_ok());
assert!(w.pad(7).is_ok());
assert_eq!(w.into_writer(), &[0b1_0000000]);
Source

fn write_bytes(&mut self, buf: &[u8]) -> Result<()>

Writes the entirety of a byte buffer to the stream.

§Errors

Passes along any I/O error from the underlying stream.

§Example
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter, BitWrite};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_var(8, 0x66u8).unwrap();
writer.write_var(8, 0x6Fu8).unwrap();
writer.write_var(8, 0x6Fu8).unwrap();
writer.write_bytes(b"bar").unwrap();
assert_eq!(writer.into_writer(), b"foobar");
Examples found in repository?
examples/flac-metadata-write.rs (line 55)
46    fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
47        w.write_from(self.minimum_block_size)?;
48        w.write_from(self.maximum_block_size)?;
49        w.write::<24, _>(self.minimum_frame_size)?;
50        w.write::<24, _>(self.maximum_frame_size)?;
51        w.write::<20, _>(self.sample_rate)?;
52        w.write::<3, _>(self.channels)?;
53        w.write::<5, _>(self.bits_per_sample)?;
54        w.write::<36, _>(self.total_samples)?;
55        w.write_bytes(&self.md5)
56    }
57}
58
59#[derive(Debug, PartialEq, Eq)]
60struct VorbisComment {
61    vendor: String,
62    comment: Vec<String>,
63}
64
65impl VorbisComment {
66    fn len(&self) -> usize {
67        4 + self.vendor.len() + 4 + self.comment.iter().map(|c| 4 + c.len()).sum::<usize>()
68    }
69
70    fn write<W: std::io::Write>(&self, w: &mut ByteWriter<W, LittleEndian>) -> std::io::Result<()> {
71        use std::convert::TryInto;
72
73        fn write_entry<W: std::io::Write>(
74            w: &mut ByteWriter<W, LittleEndian>,
75            s: &str,
76        ) -> std::io::Result<()> {
77            w.write::<u32>(s.len().try_into().unwrap())?;
78            w.write_bytes(s.as_bytes())
79        }
80
81        write_entry(w, &self.vendor)?;
82        w.write::<u32>(self.comment.len().try_into().unwrap())?;
83        self.comment.iter().try_for_each(|s| write_entry(w, s))
84    }
85}
86
87fn main() {
88    let mut flac: Vec<u8> = Vec::new();
89
90    let mut writer = BitWriter::endian(&mut flac, BigEndian);
91
92    // stream marker
93    writer.write_bytes(b"fLaC").unwrap();
94
95    // metadata block header
96    writer
97        .build(&BlockHeader {
98            last_block: false,
99            block_type: 0,
100            block_size: 34,
101        })
102        .unwrap();
103
104    // STREAMINFO block
105    writer
106        .build(&Streaminfo {
107            minimum_block_size: 4096,
108            maximum_block_size: 4096,
109            minimum_frame_size: 1542,
110            maximum_frame_size: 8546,
111            sample_rate: 44100,
112            channels: NonZero::new(2).unwrap(),
113            bits_per_sample: NonZero::new(16).unwrap(),
114            total_samples: 304844,
115            md5: *b"\xFA\xF2\x69\x2F\xFD\xEC\x2D\x5B\x30\x01\x76\xB4\x62\x88\x7D\x92",
116        })
117        .unwrap();
118
119    let comment = VorbisComment {
120        vendor: "reference libFLAC 1.1.4 20070213".to_string(),
121        comment: vec![
122            "title=2ch 44100  16bit".to_string(),
123            "album=Test Album".to_string(),
124            "artist=Assorted".to_string(),
125            "tracknumber=1".to_string(),
126        ],
127    };
128
129    // metadata block header
130    writer
131        .build(&BlockHeader {
132            last_block: false,
133            block_type: 4,
134            block_size: comment.len().try_into().unwrap(),
135        })
136        .unwrap();
137
138    // VORBIS_COMMENT block (little endian)
139    comment
140        .write(&mut ByteWriter::new(writer.writer().unwrap()))
141        .unwrap();
142
143    assert_eq!(flac, include_bytes!("data/metadata-only.flac"));
144}
Source

fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> Result<()>

Writes value number of non STOP_BIT bits to the stream and then writes a STOP_BIT. This field is variably-sized. STOP_BIT must be 0 or 1.

§Errors

Passes along any I/O error from the underyling stream.

§Examples
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter, BitWrite};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_unary::<0>(0).unwrap();
writer.write_unary::<0>(3).unwrap();
writer.write_unary::<0>(10).unwrap();
assert_eq!(writer.into_writer(), [0b01110111, 0b11111110]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter, BitWrite};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write_unary::<0>(0).unwrap();
writer.write_unary::<0>(3).unwrap();
writer.write_unary::<0>(10).unwrap();
assert_eq!(writer.into_writer(), [0b11101110, 0b01111111]);
use std::io::Write;
use bitstream_io::{BigEndian, BitWriter, BitWrite};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_unary::<1>(0).unwrap();
writer.write_unary::<1>(3).unwrap();
writer.write_unary::<1>(10).unwrap();
assert_eq!(writer.into_writer(), [0b10001000, 0b00000001]);
use std::io::Write;
use bitstream_io::{LittleEndian, BitWriter, BitWrite};
let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
writer.write_unary::<1>(0).unwrap();
writer.write_unary::<1>(3).unwrap();
writer.write_unary::<1>(10).unwrap();
assert_eq!(writer.into_writer(), [0b00010001, 0b10000000]);
Source

fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error>

Builds and writes complex type

Examples found in repository?
examples/flac-metadata-write.rs (lines 97-101)
87fn main() {
88    let mut flac: Vec<u8> = Vec::new();
89
90    let mut writer = BitWriter::endian(&mut flac, BigEndian);
91
92    // stream marker
93    writer.write_bytes(b"fLaC").unwrap();
94
95    // metadata block header
96    writer
97        .build(&BlockHeader {
98            last_block: false,
99            block_type: 0,
100            block_size: 34,
101        })
102        .unwrap();
103
104    // STREAMINFO block
105    writer
106        .build(&Streaminfo {
107            minimum_block_size: 4096,
108            maximum_block_size: 4096,
109            minimum_frame_size: 1542,
110            maximum_frame_size: 8546,
111            sample_rate: 44100,
112            channels: NonZero::new(2).unwrap(),
113            bits_per_sample: NonZero::new(16).unwrap(),
114            total_samples: 304844,
115            md5: *b"\xFA\xF2\x69\x2F\xFD\xEC\x2D\x5B\x30\x01\x76\xB4\x62\x88\x7D\x92",
116        })
117        .unwrap();
118
119    let comment = VorbisComment {
120        vendor: "reference libFLAC 1.1.4 20070213".to_string(),
121        comment: vec![
122            "title=2ch 44100  16bit".to_string(),
123            "album=Test Album".to_string(),
124            "artist=Assorted".to_string(),
125            "tracknumber=1".to_string(),
126        ],
127    };
128
129    // metadata block header
130    writer
131        .build(&BlockHeader {
132            last_block: false,
133            block_type: 4,
134            block_size: comment.len().try_into().unwrap(),
135        })
136        .unwrap();
137
138    // VORBIS_COMMENT block (little endian)
139    comment
140        .write(&mut ByteWriter::new(writer.writer().unwrap()))
141        .unwrap();
142
143    assert_eq!(flac, include_bytes!("data/metadata-only.flac"));
144}
Source

fn build_with<'a, T: ToBitStreamWith<'a>>( &mut self, build: &T, context: &T::Context, ) -> Result<(), T::Error>

Builds and writes complex type with context

Source

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, BitWrite};
let mut writer = BitWriter::endian(Vec::new(), BigEndian);
writer.write_var(1, 0u8).unwrap();
writer.byte_align().unwrap();
writer.write_var(8, 0xFFu8).unwrap();
assert_eq!(writer.into_writer(), [0x00, 0xFF]);
Source

fn write_huffman<T>(&mut self, value: T::Symbol) -> Result<()>
where T: ToBits,

Given a symbol, writes its representation to the output stream as bits. Generates no output if the symbol isn’t defined in the Huffman tree.

§Errors

Passes along any I/O error from the underlying stream.

§Example
use bitstream_io::{BigEndian, BitWriter, BitWrite};
use bitstream_io::define_huffman_tree;

define_huffman_tree!(TreeName : char = ['a', ['b', ['c', 'd']]]);
// 'a' is 0
// 'b' is 1 -> 0
// 'c' is 1 -> 1 -> 0
// 'd' is 1 -> 1 -> 1

let mut writer = BitWriter::endian(vec![], BigEndian);
writer.write_huffman::<TreeName>('b').unwrap();
writer.write_huffman::<TreeName>('c').unwrap();
writer.write_huffman::<TreeName>('d').unwrap();
assert_eq!(writer.into_writer(), [0b10_110_111]);
Source

fn by_ref(&mut self) -> &mut Self

Creates a “by reference” adaptor for this BitWrite

The returned adapter also implements BitWrite and will borrow the current reader.

§Example
use bitstream_io::{BitWriter, BitWrite, BigEndian};

fn build<W: BitWrite>(w: W) {
    // perform some building
}

let mut writer = BitWriter::endian(vec![], BigEndian);
// performing building by reference
build(writer.by_ref());
// original owned writer still available
writer.write::<8, u8>(0).unwrap();
assert_eq!(writer.into_writer(), &[0]);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<W: BitWrite + ?Sized> BitWrite for &mut W

Source§

fn write_bit(&mut self, bit: bool) -> Result<()>

Source§

fn write<const BITS: u32, I>(&mut self, value: I) -> Result<()>
where I: Integer,

Source§

fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> Result<()>

Source§

fn write_var<I>(&mut self, bits: u32, value: I) -> Result<()>
where I: Integer,

Source§

fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> Result<()>
where U: UnsignedInteger,

Source§

fn write_unsigned_var<U>(&mut self, bits: u32, value: U) -> Result<()>
where U: UnsignedInteger,

Source§

fn write_signed<const BITS: u32, S>(&mut self, value: S) -> Result<()>
where S: SignedInteger,

Source§

fn write_signed_var<S>(&mut self, bits: u32, value: S) -> Result<()>
where S: SignedInteger,

Source§

fn write_count<const MAX: u32>(&mut self, count: BitCount<MAX>) -> Result<()>

Source§

fn write_counted<const MAX: u32, I>( &mut self, bits: BitCount<MAX>, value: I, ) -> Result<()>
where I: Integer + Sized,

Source§

fn write_unsigned_counted<const BITS: u32, U>( &mut self, bits: BitCount<BITS>, value: U, ) -> Result<()>
where U: UnsignedInteger,

Source§

fn write_signed_counted<const MAX: u32, S>( &mut self, bits: impl TryInto<SignedBitCount<MAX>>, value: S, ) -> Result<()>
where S: SignedInteger,

Source§

fn write_from<V>(&mut self, value: V) -> Result<()>
where V: Primitive,

Source§

fn write_as_from<F, V>(&mut self, value: V) -> Result<()>
where F: Endianness, V: Primitive,

Source§

fn pad(&mut self, bits: u32) -> Result<()>

Source§

fn write_bytes(&mut self, buf: &[u8]) -> Result<()>

Source§

fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> Result<()>

Source§

fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error>

Source§

fn build_with<'a, T: ToBitStreamWith<'a>>( &mut self, build: &T, context: &T::Context, ) -> Result<(), T::Error>

Source§

fn byte_aligned(&self) -> bool

Source§

fn byte_align(&mut self) -> Result<()>

Source§

fn write_huffman<T>(&mut self, value: T::Symbol) -> Result<()>
where T: ToBits,

Implementors§

Source§

impl<N, E> BitWrite for BitCounter<N, E>
where E: Endianness, N: Counter,

Source§

impl<N, E> BitWrite for BitRecorder<N, E>
where E: Endianness, N: Counter,

Source§

impl<N: Counter> BitWrite for BitsWritten<N>

Source§

impl<W: Write, E: Endianness> BitWrite for BitWriter<W, E>