bitstream_io/write.rs
1// Copyright 2017 Brian Langenberger
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Traits and implementations for writing bits to a stream.
10//!
11//! ## Example
12//!
13//! Writing the initial STREAMINFO block to a FLAC file,
14//! as documented in its
15//! [specification](https://xiph.org/flac/format.html#stream).
16//!
17//! ```
18//! use std::convert::TryInto;
19//! use std::io::Write;
20//! use bitstream_io::{BigEndian, BitWriter, BitWrite, ByteWriter, ByteWrite, LittleEndian, ToBitStream};
21//!
22//! #[derive(Debug, PartialEq, Eq)]
23//! struct BlockHeader {
24//! last_block: bool, // 1 bit
25//! block_type: u8, // 7 bits
26//! block_size: u32, // 24 bits
27//! }
28//!
29//! impl ToBitStream for BlockHeader {
30//! type Error = std::io::Error;
31//!
32//! fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
33//! w.write_bit(self.last_block)?;
34//! w.write_out::<7, _>(self.block_type)?;
35//! w.write_out::<24, _>(self.block_size)
36//! }
37//! }
38//!
39//! #[derive(Debug, PartialEq, Eq)]
40//! struct Streaminfo {
41//! minimum_block_size: u16, // 16 bits
42//! maximum_block_size: u16, // 16 bits
43//! minimum_frame_size: u32, // 24 bits
44//! maximum_frame_size: u32, // 24 bits
45//! sample_rate: u32, // 20 bits
46//! channels: u8, // 3 bits
47//! bits_per_sample: u8, // 5 bits
48//! total_samples: u64, // 36 bits
49//! md5: [u8; 16], // 16 bytes
50//! }
51//!
52//! impl ToBitStream for Streaminfo {
53//! type Error = std::io::Error;
54//!
55//! fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
56//! w.write_from(self.minimum_block_size)?;
57//! w.write_from(self.maximum_block_size)?;
58//! w.write_out::<24, _>(self.minimum_frame_size)?;
59//! w.write_out::<24, _>(self.maximum_frame_size)?;
60//! w.write_out::<20, _>(self.sample_rate)?;
61//! w.write_out::<3, _>(self.channels - 1)?;
62//! w.write_out::<5, _>(self.bits_per_sample - 1)?;
63//! w.write_out::<36, _>(self.total_samples)?;
64//! w.write_bytes(&self.md5)
65//! }
66//! }
67//!
68//! #[derive(Debug, PartialEq, Eq)]
69//! struct VorbisComment {
70//! vendor: String,
71//! comment: Vec<String>,
72//! }
73//!
74//! impl VorbisComment {
75//! fn len(&self) -> usize {
76//! 4 + self.vendor.len() + 4 + self.comment.iter().map(|c| 4 + c.len()).sum::<usize>()
77//! }
78//!
79//! fn write<W: std::io::Write>(&self, w: &mut ByteWriter<W, LittleEndian>) -> std::io::Result<()> {
80//! use std::convert::TryInto;
81//!
82//! fn write_entry<W: std::io::Write>(
83//! w: &mut ByteWriter<W, LittleEndian>,
84//! s: &str,
85//! ) -> std::io::Result<()> {
86//! w.write::<u32>(s.len().try_into().unwrap())?;
87//! w.write_bytes(s.as_bytes())
88//! }
89//!
90//! write_entry(w, &self.vendor)?;
91//! w.write::<u32>(self.comment.len().try_into().unwrap())?;
92//! self.comment.iter().try_for_each(|s| write_entry(w, s))
93//! }
94//! }
95//!
96//! let mut flac: Vec<u8> = Vec::new();
97//!
98//! let mut writer = BitWriter::endian(&mut flac, BigEndian);
99//!
100//! // stream marker
101//! writer.write_bytes(b"fLaC").unwrap();
102//!
103//! // metadata block header
104//! writer.build(&BlockHeader { last_block: false, block_type: 0, block_size: 34 }).unwrap();
105//!
106//! // STREAMINFO block
107//! writer.build(&Streaminfo {
108//! minimum_block_size: 4096,
109//! maximum_block_size: 4096,
110//! minimum_frame_size: 1542,
111//! maximum_frame_size: 8546,
112//! sample_rate: 44100,
113//! channels: 2,
114//! bits_per_sample: 16,
115//! total_samples: 304844,
116//! md5: *b"\xFA\xF2\x69\x2F\xFD\xEC\x2D\x5B\x30\x01\x76\xB4\x62\x88\x7D\x92",
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.build(
131//! &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.write(&mut ByteWriter::new(writer.writer().unwrap())).unwrap();
140//!
141//! assert_eq!(flac, vec![0x66,0x4c,0x61,0x43,0x00,0x00,0x00,0x22,
142//! 0x10,0x00,0x10,0x00,0x00,0x06,0x06,0x00,
143//! 0x21,0x62,0x0a,0xc4,0x42,0xf0,0x00,0x04,
144//! 0xa6,0xcc,0xfa,0xf2,0x69,0x2f,0xfd,0xec,
145//! 0x2d,0x5b,0x30,0x01,0x76,0xb4,0x62,0x88,
146//! 0x7d,0x92,0x04,0x00,0x00,0x7a,0x20,0x00,
147//! 0x00,0x00,0x72,0x65,0x66,0x65,0x72,0x65,
148//! 0x6e,0x63,0x65,0x20,0x6c,0x69,0x62,0x46,
149//! 0x4c,0x41,0x43,0x20,0x31,0x2e,0x31,0x2e,
150//! 0x34,0x20,0x32,0x30,0x30,0x37,0x30,0x32,
151//! 0x31,0x33,0x04,0x00,0x00,0x00,0x16,0x00,
152//! 0x00,0x00,0x74,0x69,0x74,0x6c,0x65,0x3d,
153//! 0x32,0x63,0x68,0x20,0x34,0x34,0x31,0x30,
154//! 0x30,0x20,0x20,0x31,0x36,0x62,0x69,0x74,
155//! 0x10,0x00,0x00,0x00,0x61,0x6c,0x62,0x75,
156//! 0x6d,0x3d,0x54,0x65,0x73,0x74,0x20,0x41,
157//! 0x6c,0x62,0x75,0x6d,0x0f,0x00,0x00,0x00,
158//! 0x61,0x72,0x74,0x69,0x73,0x74,0x3d,0x41,
159//! 0x73,0x73,0x6f,0x72,0x74,0x65,0x64,0x0d,
160//! 0x00,0x00,0x00,0x74,0x72,0x61,0x63,0x6b,
161//! 0x6e,0x75,0x6d,0x62,0x65,0x72,0x3d,0x31]);
162//! ```
163
164#![warn(missing_docs)]
165
166#[cfg(feature = "alloc")]
167use alloc::boxed::Box;
168#[cfg(feature = "alloc")]
169use alloc::vec::Vec;
170#[cfg(feature = "alloc")]
171use core2::io;
172
173#[cfg(not(feature = "alloc"))]
174use std::io;
175
176use core::convert::From;
177use core::ops::{AddAssign, Rem};
178
179use super::{
180 huffman::WriteHuffmanTree, BitQueue, Endianness, Numeric, PhantomData, Primitive, SignedNumeric,
181};
182
183/// For writing bit values to an underlying stream in a given endianness.
184///
185/// Because this only writes whole bytes to the underlying stream,
186/// it is important that output is byte-aligned before the bitstream
187/// writer's lifetime ends.
188/// **Partial bytes will be lost** if the writer is disposed of
189/// before they can be written.
190pub struct BitWriter<W: io::Write, E: Endianness> {
191 writer: W,
192 bitqueue: BitQueue<E, u8>,
193}
194
195impl<W: io::Write, E: Endianness> BitWriter<W, E> {
196 /// Wraps a BitWriter around something that implements `Write`
197 pub fn new(writer: W) -> BitWriter<W, E> {
198 BitWriter {
199 writer,
200 bitqueue: BitQueue::new(),
201 }
202 }
203
204 /// Wraps a BitWriter around something that implements `Write`
205 /// with the given endianness.
206 pub fn endian(writer: W, _endian: E) -> BitWriter<W, E> {
207 BitWriter {
208 writer,
209 bitqueue: BitQueue::new(),
210 }
211 }
212
213 /// Unwraps internal writer and disposes of BitWriter.
214 ///
215 /// # Warning
216 ///
217 /// Any unwritten partial bits are discarded.
218 #[inline]
219 pub fn into_writer(self) -> W {
220 self.writer
221 }
222
223 /// If stream is byte-aligned, provides mutable reference
224 /// to internal writer. Otherwise returns `None`
225 #[inline]
226 pub fn writer(&mut self) -> Option<&mut W> {
227 if self.byte_aligned() {
228 Some(&mut self.writer)
229 } else {
230 None
231 }
232 }
233
234 /// Converts `BitWriter` to `ByteWriter` in the same endianness.
235 ///
236 /// # Warning
237 ///
238 /// Any written partial bits are discarded.
239 #[inline]
240 pub fn into_bytewriter(self) -> ByteWriter<W, E> {
241 ByteWriter::new(self.into_writer())
242 }
243
244 /// If stream is byte-aligned, provides temporary `ByteWriter`
245 /// in the same endianness. Otherwise returns `None`
246 ///
247 /// # Warning
248 ///
249 /// Any unwritten bits left over when `ByteWriter` is dropped are lost.
250 #[inline]
251 pub fn bytewriter(&mut self) -> Option<ByteWriter<&mut W, E>> {
252 self.writer().map(ByteWriter::new)
253 }
254
255 /// Consumes writer and returns any un-written partial byte
256 /// as a `(bits, value)` tuple.
257 ///
258 /// # Examples
259 /// ```
260 /// use std::io::Write;
261 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
262 /// let mut data = Vec::new();
263 /// let (bits, value) = {
264 /// let mut writer = BitWriter::endian(&mut data, BigEndian);
265 /// writer.write(15, 0b1010_0101_0101_101).unwrap();
266 /// writer.into_unwritten()
267 /// };
268 /// assert_eq!(data, [0b1010_0101]);
269 /// assert_eq!(bits, 7);
270 /// assert_eq!(value, 0b0101_101);
271 /// ```
272 ///
273 /// ```
274 /// use std::io::Write;
275 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
276 /// let mut data = Vec::new();
277 /// let (bits, value) = {
278 /// let mut writer = BitWriter::endian(&mut data, BigEndian);
279 /// writer.write(8, 0b1010_0101).unwrap();
280 /// writer.into_unwritten()
281 /// };
282 /// assert_eq!(data, [0b1010_0101]);
283 /// assert_eq!(bits, 0);
284 /// assert_eq!(value, 0);
285 /// ```
286 #[inline(always)]
287 pub fn into_unwritten(self) -> (u32, u8) {
288 (self.bitqueue.len(), self.bitqueue.value())
289 }
290
291 /// Flushes output stream to disk, if necessary.
292 /// Any partial bytes are not flushed.
293 ///
294 /// # Errors
295 ///
296 /// Passes along any errors from the underlying stream.
297 #[inline(always)]
298 pub fn flush(&mut self) -> io::Result<()> {
299 self.writer.flush()
300 }
301}
302
303/// A trait for anything that can write a variable number of
304/// potentially un-aligned values to an output stream
305pub trait BitWrite {
306 /// Writes a single bit to the stream.
307 /// `true` indicates 1, `false` indicates 0
308 ///
309 /// # Errors
310 ///
311 /// Passes along any I/O error from the underlying stream.
312 fn write_bit(&mut self, bit: bool) -> io::Result<()>;
313
314 /// Writes an unsigned value to the stream using the given
315 /// number of bits.
316 ///
317 /// # Errors
318 ///
319 /// Passes along any I/O error from the underlying stream.
320 /// Returns an error if the input type is too small
321 /// to hold the given number of bits.
322 /// Returns an error if the value is too large
323 /// to fit the given number of bits.
324 fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
325 where
326 U: Numeric;
327
328 /// Writes an unsigned value to the stream using the given
329 /// const number of bits.
330 ///
331 /// # Errors
332 ///
333 /// Passes along any I/O error from the underlying stream.
334 /// Returns an error if the value is too large
335 /// to fit the given number of bits.
336 /// A compile-time error occurs if the given number of bits
337 /// is larger than the output type.
338 fn write_out<const BITS: u32, U>(&mut self, value: U) -> io::Result<()>
339 where
340 U: Numeric,
341 {
342 self.write(BITS, value)
343 }
344
345 /// Writes a twos-complement signed value to the stream
346 /// with the given number of bits.
347 ///
348 /// # Errors
349 ///
350 /// Passes along any I/O error from the underlying stream.
351 /// Returns an error if the input type is too small
352 /// to hold the given number of bits.
353 /// Returns an error if the number of bits is 0,
354 /// since one bit is always needed for the sign.
355 /// Returns an error if the value is too large
356 /// to fit the given number of bits.
357 fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
358 where
359 S: SignedNumeric;
360
361 /// Writes a twos-complement signed value to the stream
362 /// with the given const number of bits.
363 ///
364 /// # Errors
365 ///
366 /// Passes along any I/O error from the underlying stream.
367 /// Returns an error if the value is too large
368 /// to fit the given number of bits.
369 /// A compile-time error occurs if the number of bits is 0,
370 /// since one bit is always needed for the sign.
371 /// A compile-time error occurs if the given number of bits
372 /// is larger than the output type.
373 fn write_signed_out<const BITS: u32, S>(&mut self, value: S) -> io::Result<()>
374 where
375 S: SignedNumeric,
376 {
377 self.write_signed(BITS, value)
378 }
379
380 /// Writes whole value to the stream whose size in bits
381 /// is equal to its type's size.
382 ///
383 /// # Errors
384 ///
385 /// Passes along any I/O error from the underlying stream.
386 fn write_from<V>(&mut self, value: V) -> io::Result<()>
387 where
388 V: Primitive;
389
390 /// Writes whole value to the stream whose size in bits
391 /// is equal to its type's size in an endianness that may
392 /// be different from the stream's endianness.
393 ///
394 /// # Errors
395 ///
396 /// Passes along any I/O error from the underlying stream.
397 fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()>
398 where
399 F: Endianness,
400 V: Primitive;
401
402 /// Writes the entirety of a byte buffer to the stream.
403 ///
404 /// # Errors
405 ///
406 /// Passes along any I/O error from the underlying stream.
407 ///
408 /// # Example
409 ///
410 /// ```
411 /// use std::io::Write;
412 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
413 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
414 /// writer.write(8, 0x66).unwrap();
415 /// writer.write(8, 0x6F).unwrap();
416 /// writer.write(8, 0x6F).unwrap();
417 /// writer.write_bytes(b"bar").unwrap();
418 /// assert_eq!(writer.into_writer(), b"foobar");
419 /// ```
420 #[inline]
421 fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
422 buf.iter().try_for_each(|b| self.write_out::<8, _>(*b))
423 }
424
425 /// Writes `value` number of 1 bits to the stream
426 /// and then writes a 0 bit. This field is variably-sized.
427 ///
428 /// # Errors
429 ///
430 /// Passes along any I/O error from the underyling stream.
431 ///
432 /// # Examples
433 /// ```
434 /// use std::io::Write;
435 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
436 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
437 /// writer.write_unary0(0).unwrap();
438 /// writer.write_unary0(3).unwrap();
439 /// writer.write_unary0(10).unwrap();
440 /// assert_eq!(writer.into_writer(), [0b01110111, 0b11111110]);
441 /// ```
442 ///
443 /// ```
444 /// use std::io::Write;
445 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
446 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
447 /// writer.write_unary0(0).unwrap();
448 /// writer.write_unary0(3).unwrap();
449 /// writer.write_unary0(10).unwrap();
450 /// assert_eq!(writer.into_writer(), [0b11101110, 0b01111111]);
451 /// ```
452 fn write_unary0(&mut self, value: u32) -> io::Result<()> {
453 match value {
454 0 => self.write_bit(false),
455 bits @ 1..=31 => self
456 .write(value, (1u32 << bits) - 1)
457 .and_then(|()| self.write_bit(false)),
458 32 => self
459 .write(value, 0xFFFF_FFFFu32)
460 .and_then(|()| self.write_bit(false)),
461 bits @ 33..=63 => self
462 .write(value, (1u64 << bits) - 1)
463 .and_then(|()| self.write_bit(false)),
464 64 => self
465 .write(value, 0xFFFF_FFFF_FFFF_FFFFu64)
466 .and_then(|()| self.write_bit(false)),
467 mut bits => {
468 while bits > 64 {
469 self.write(64, 0xFFFF_FFFF_FFFF_FFFFu64)?;
470 bits -= 64;
471 }
472 self.write_unary0(bits)
473 }
474 }
475 }
476
477 /// Writes `value` number of 0 bits to the stream
478 /// and then writes a 1 bit. This field is variably-sized.
479 ///
480 /// # Errors
481 ///
482 /// Passes along any I/O error from the underyling stream.
483 ///
484 /// # Example
485 /// ```
486 /// use std::io::Write;
487 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
488 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
489 /// writer.write_unary1(0).unwrap();
490 /// writer.write_unary1(3).unwrap();
491 /// writer.write_unary1(10).unwrap();
492 /// assert_eq!(writer.into_writer(), [0b10001000, 0b00000001]);
493 /// ```
494 ///
495 /// ```
496 /// use std::io::Write;
497 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
498 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
499 /// writer.write_unary1(0).unwrap();
500 /// writer.write_unary1(3).unwrap();
501 /// writer.write_unary1(10).unwrap();
502 /// assert_eq!(writer.into_writer(), [0b00010001, 0b10000000]);
503 /// ```
504 fn write_unary1(&mut self, value: u32) -> io::Result<()> {
505 match value {
506 0 => self.write_bit(true),
507 1..=32 => self.write(value, 0u32).and_then(|()| self.write_bit(true)),
508 33..=64 => self.write(value, 0u64).and_then(|()| self.write_bit(true)),
509 mut bits => {
510 while bits > 64 {
511 self.write(64, 0u64)?;
512 bits -= 64;
513 }
514 self.write_unary1(bits)
515 }
516 }
517 }
518
519 /// Builds and writes complex type
520 fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> {
521 build.to_writer(self)
522 }
523
524 /// Builds and writes complex type with context
525 fn build_with<'a, T: ToBitStreamWith<'a>>(
526 &mut self,
527 build: &T,
528 context: &T::Context,
529 ) -> Result<(), T::Error> {
530 build.to_writer(self, context)
531 }
532
533 /// Returns true if the stream is aligned at a whole byte.
534 fn byte_aligned(&self) -> bool;
535
536 /// Pads the stream with 0 bits until it is aligned at a whole byte.
537 /// Does nothing if the stream is already aligned.
538 ///
539 /// # Errors
540 ///
541 /// Passes along any I/O error from the underyling stream.
542 ///
543 /// # Example
544 /// ```
545 /// use std::io::Write;
546 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
547 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
548 /// writer.write(1, 0).unwrap();
549 /// writer.byte_align().unwrap();
550 /// writer.write(8, 0xFF).unwrap();
551 /// assert_eq!(writer.into_writer(), [0x00, 0xFF]);
552 /// ```
553 fn byte_align(&mut self) -> io::Result<()> {
554 while !self.byte_aligned() {
555 self.write_bit(false)?;
556 }
557 Ok(())
558 }
559}
560
561/// A trait for anything that can write Huffman codes
562/// of a given endianness to an output stream
563pub trait HuffmanWrite<E: Endianness> {
564 /// Writes Huffman code for the given symbol to the stream.
565 ///
566 /// # Errors
567 ///
568 /// Passes along any I/O error from the underlying stream.
569 fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
570 where
571 T: Ord + Copy;
572}
573
574impl<W: io::Write, E: Endianness> BitWrite for BitWriter<W, E> {
575 /// # Examples
576 /// ```
577 /// use std::io::Write;
578 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
579 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
580 /// writer.write_bit(true).unwrap();
581 /// writer.write_bit(false).unwrap();
582 /// writer.write_bit(true).unwrap();
583 /// writer.write_bit(true).unwrap();
584 /// writer.write_bit(false).unwrap();
585 /// writer.write_bit(true).unwrap();
586 /// writer.write_bit(true).unwrap();
587 /// writer.write_bit(true).unwrap();
588 /// assert_eq!(writer.into_writer(), [0b10110111]);
589 /// ```
590 ///
591 /// ```
592 /// use std::io::Write;
593 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
594 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
595 /// writer.write_bit(true).unwrap();
596 /// writer.write_bit(true).unwrap();
597 /// writer.write_bit(true).unwrap();
598 /// writer.write_bit(false).unwrap();
599 /// writer.write_bit(true).unwrap();
600 /// writer.write_bit(true).unwrap();
601 /// writer.write_bit(false).unwrap();
602 /// writer.write_bit(true).unwrap();
603 /// assert_eq!(writer.into_writer(), [0b10110111]);
604 /// ```
605 fn write_bit(&mut self, bit: bool) -> io::Result<()> {
606 self.bitqueue.push(1, u8::from(bit));
607 if self.bitqueue.is_full() {
608 write_byte(&mut self.writer, self.bitqueue.pop(8))
609 } else {
610 Ok(())
611 }
612 }
613
614 /// # Examples
615 /// ```
616 /// use std::io::Write;
617 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
618 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
619 /// writer.write(1, 0b1).unwrap();
620 /// writer.write(2, 0b01).unwrap();
621 /// writer.write(5, 0b10111).unwrap();
622 /// assert_eq!(writer.into_writer(), [0b10110111]);
623 /// ```
624 ///
625 /// ```
626 /// use std::io::Write;
627 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
628 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
629 /// writer.write(1, 0b1).unwrap();
630 /// writer.write(2, 0b11).unwrap();
631 /// writer.write(5, 0b10110).unwrap();
632 /// assert_eq!(writer.into_writer(), [0b10110111]);
633 /// ```
634 ///
635 /// ```
636 /// use std::io::{Write, sink};
637 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
638 /// let mut w = BitWriter::endian(sink(), BigEndian);
639 /// assert!(w.write(9, 0u8).is_err()); // can't write u8 in 9 bits
640 /// assert!(w.write(17, 0u16).is_err()); // can't write u16 in 17 bits
641 /// assert!(w.write(33, 0u32).is_err()); // can't write u32 in 33 bits
642 /// assert!(w.write(65, 0u64).is_err()); // can't write u64 in 65 bits
643 /// assert!(w.write(1, 2).is_err()); // can't write 2 in 1 bit
644 /// assert!(w.write(2, 4).is_err()); // can't write 4 in 2 bits
645 /// assert!(w.write(3, 8).is_err()); // can't write 8 in 3 bits
646 /// assert!(w.write(4, 16).is_err()); // can't write 16 in 4 bits
647 /// ```
648 fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
649 where
650 U: Numeric,
651 {
652 if bits > U::BITS_SIZE {
653 Err(io::Error::new(
654 io::ErrorKind::InvalidInput,
655 "excessive bits for type written",
656 ))
657 } else if (bits < U::BITS_SIZE) && (value >= (U::ONE << bits)) {
658 Err(io::Error::new(
659 io::ErrorKind::InvalidInput,
660 "excessive value for bits written",
661 ))
662 } else if bits < self.bitqueue.remaining_len() {
663 self.bitqueue.push(bits, value.to_u8());
664 Ok(())
665 } else {
666 let mut acc = BitQueue::from_value(value, bits);
667 write_unaligned(&mut self.writer, &mut acc, &mut self.bitqueue)?;
668 write_aligned(&mut self.writer, &mut acc)?;
669 self.bitqueue.push(acc.len(), acc.value().to_u8());
670 Ok(())
671 }
672 }
673
674 /// # Examples
675 /// ```
676 /// use std::io::Write;
677 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
678 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
679 /// writer.write_out::<1, _>(0b1).unwrap();
680 /// writer.write_out::<2, _>(0b01).unwrap();
681 /// writer.write_out::<5, _>(0b10111).unwrap();
682 /// assert_eq!(writer.into_writer(), [0b10110111]);
683 /// ```
684 ///
685 /// ```
686 /// use std::io::Write;
687 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
688 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
689 /// writer.write_out::<1, _>(0b1).unwrap();
690 /// writer.write_out::<2, _>(0b11).unwrap();
691 /// writer.write_out::<5, _>(0b10110).unwrap();
692 /// assert_eq!(writer.into_writer(), [0b10110111]);
693 /// ```
694 ///
695 /// ```
696 /// use std::io::{Write, sink};
697 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
698 /// let mut w = BitWriter::endian(sink(), BigEndian);
699 /// assert!(w.write_out::<1, _>(2).is_err()); // can't write 2 in 1 bit
700 /// assert!(w.write_out::<2, _>(4).is_err()); // can't write 4 in 2 bits
701 /// assert!(w.write_out::<3, _>(8).is_err()); // can't write 8 in 3 bits
702 /// assert!(w.write_out::<4, _>(16).is_err()); // can't write 16 in 4 bits
703 /// ```
704 fn write_out<const BITS: u32, U>(&mut self, value: U) -> io::Result<()>
705 where
706 U: Numeric,
707 {
708 const {
709 assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
710 }
711
712 if (BITS < U::BITS_SIZE) && (value >= (U::ONE << BITS)) {
713 Err(io::Error::new(
714 io::ErrorKind::InvalidInput,
715 "excessive value for bits written",
716 ))
717 } else if BITS < self.bitqueue.remaining_len() {
718 self.bitqueue.push_fixed::<BITS>(value.to_u8());
719 Ok(())
720 } else {
721 let mut acc = BitQueue::from_value(value, BITS);
722 write_unaligned(&mut self.writer, &mut acc, &mut self.bitqueue)?;
723 write_aligned(&mut self.writer, &mut acc)?;
724 self.bitqueue.push(acc.len(), acc.value().to_u8());
725 Ok(())
726 }
727 }
728
729 /// # Examples
730 /// ```
731 /// use std::io::Write;
732 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
733 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
734 /// writer.write_signed(4, -5).unwrap();
735 /// writer.write_signed(4, 7).unwrap();
736 /// assert_eq!(writer.into_writer(), [0b10110111]);
737 /// ```
738 ///
739 /// ```
740 /// use std::io::Write;
741 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
742 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
743 /// writer.write_signed(4, 7).unwrap();
744 /// writer.write_signed(4, -5).unwrap();
745 /// assert_eq!(writer.into_writer(), [0b10110111]);
746 /// ```
747 #[inline]
748 fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
749 where
750 S: SignedNumeric,
751 {
752 match bits {
753 0 => Err(io::Error::new(
754 io::ErrorKind::InvalidInput,
755 "signed writes need at least 1 bit for sign",
756 )),
757 bits if bits <= S::BITS_SIZE => E::write_signed(self, bits, value),
758 _ => Err(io::Error::new(
759 io::ErrorKind::InvalidInput,
760 "excessive bits for type written",
761 )),
762 }
763 }
764
765 /// # Examples
766 /// ```
767 /// use std::io::Write;
768 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
769 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
770 /// writer.write_signed_out::<4, _>(-5).unwrap();
771 /// writer.write_signed_out::<4, _>(7).unwrap();
772 /// assert_eq!(writer.into_writer(), [0b10110111]);
773 /// ```
774 ///
775 /// ```
776 /// use std::io::Write;
777 /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
778 /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
779 /// writer.write_signed_out::<4, _>(7).unwrap();
780 /// writer.write_signed_out::<4, _>(-5).unwrap();
781 /// assert_eq!(writer.into_writer(), [0b10110111]);
782 /// ```
783 #[inline]
784 fn write_signed_out<const BITS: u32, S>(&mut self, value: S) -> io::Result<()>
785 where
786 S: SignedNumeric,
787 {
788 const {
789 assert!(BITS > 0, "signed writes need at least 1 bit for sign");
790 assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
791 }
792 E::write_signed_fixed::<_, BITS, S>(self, value)
793 }
794
795 #[inline]
796 fn write_from<V>(&mut self, value: V) -> io::Result<()>
797 where
798 V: Primitive,
799 {
800 E::write_primitive(self, value)
801 }
802
803 #[inline]
804 fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()>
805 where
806 F: Endianness,
807 V: Primitive,
808 {
809 F::write_primitive(self, value)
810 }
811
812 #[inline]
813 fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
814 if self.byte_aligned() {
815 self.writer.write_all(buf)
816 } else {
817 buf.iter().try_for_each(|b| self.write_out::<8, _>(*b))
818 }
819 }
820
821 /// # Example
822 /// ```
823 /// use std::io::{Write, sink};
824 /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
825 /// let mut writer = BitWriter::endian(sink(), BigEndian);
826 /// assert_eq!(writer.byte_aligned(), true);
827 /// writer.write(1, 0).unwrap();
828 /// assert_eq!(writer.byte_aligned(), false);
829 /// writer.write(7, 0).unwrap();
830 /// assert_eq!(writer.byte_aligned(), true);
831 /// ```
832 #[inline(always)]
833 fn byte_aligned(&self) -> bool {
834 self.bitqueue.is_empty()
835 }
836}
837
838impl<W: io::Write, E: Endianness> HuffmanWrite<E> for BitWriter<W, E> {
839 /// # Example
840 /// ```
841 /// use std::io::Write;
842 /// use bitstream_io::{BigEndian, BitWriter, HuffmanWrite};
843 /// use bitstream_io::huffman::compile_write_tree;
844 /// let tree = compile_write_tree(
845 /// vec![('a', vec![0]),
846 /// ('b', vec![1, 0]),
847 /// ('c', vec![1, 1, 0]),
848 /// ('d', vec![1, 1, 1])]).unwrap();
849 /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
850 /// writer.write_huffman(&tree, 'b').unwrap();
851 /// writer.write_huffman(&tree, 'c').unwrap();
852 /// writer.write_huffman(&tree, 'd').unwrap();
853 /// assert_eq!(writer.into_writer(), [0b10110111]);
854 /// ```
855 #[inline]
856 fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
857 where
858 T: Ord + Copy,
859 {
860 tree.get(&symbol)
861 .try_for_each(|(bits, value)| self.write(*bits, *value))
862 }
863}
864
865/// For counting the number of bits written but generating no output.
866///
867/// # Example
868/// ```
869/// use bitstream_io::{BigEndian, BitWrite, BitCounter};
870/// let mut writer: BitCounter<u32, BigEndian> = BitCounter::new();
871/// writer.write(1, 0b1).unwrap();
872/// writer.write(2, 0b01).unwrap();
873/// writer.write(5, 0b10111).unwrap();
874/// assert_eq!(writer.written(), 8);
875/// ```
876#[derive(Default)]
877pub struct BitCounter<N, E: Endianness> {
878 bits: N,
879 phantom: PhantomData<E>,
880}
881
882impl<N: Default + Copy, E: Endianness> BitCounter<N, E> {
883 /// Creates new counter
884 #[inline]
885 pub fn new() -> Self {
886 BitCounter {
887 bits: N::default(),
888 phantom: PhantomData,
889 }
890 }
891
892 /// Returns number of bits written
893 #[inline]
894 pub fn written(&self) -> N {
895 self.bits
896 }
897}
898
899impl<N, E> BitWrite for BitCounter<N, E>
900where
901 E: Endianness,
902 N: Copy + AddAssign + From<u32> + Rem<Output = N> + PartialEq,
903{
904 #[inline]
905 fn write_bit(&mut self, _bit: bool) -> io::Result<()> {
906 self.bits += 1.into();
907 Ok(())
908 }
909
910 #[inline]
911 fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
912 where
913 U: Numeric,
914 {
915 if bits > U::BITS_SIZE {
916 Err(io::Error::new(
917 io::ErrorKind::InvalidInput,
918 "excessive bits for type written",
919 ))
920 } else if (bits < U::BITS_SIZE) && (value >= (U::ONE << bits)) {
921 Err(io::Error::new(
922 io::ErrorKind::InvalidInput,
923 "excessive value for bits written",
924 ))
925 } else {
926 self.bits += bits.into();
927 Ok(())
928 }
929 }
930
931 fn write_out<const BITS: u32, U>(&mut self, value: U) -> io::Result<()>
932 where
933 U: Numeric,
934 {
935 const {
936 assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
937 }
938
939 if (BITS < U::BITS_SIZE) && (value >= (U::ONE << BITS)) {
940 Err(io::Error::new(
941 io::ErrorKind::InvalidInput,
942 "excessive value for bits written",
943 ))
944 } else {
945 self.bits += BITS.into();
946 Ok(())
947 }
948 }
949
950 #[inline]
951 fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
952 where
953 S: SignedNumeric,
954 {
955 match bits {
956 0 => Err(io::Error::new(
957 io::ErrorKind::InvalidInput,
958 "signed writes need at least 1 bit for sign",
959 )),
960 bits if bits <= S::BITS_SIZE => E::write_signed(self, bits, value),
961 _ => Err(io::Error::new(
962 io::ErrorKind::InvalidInput,
963 "excessive bits for type written",
964 )),
965 }
966 }
967
968 #[inline]
969 fn write_signed_out<const BITS: u32, S>(&mut self, value: S) -> io::Result<()>
970 where
971 S: SignedNumeric,
972 {
973 const {
974 assert!(BITS > 0, "signed writes need at least 1 bit for sign");
975 assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
976 }
977 E::write_signed_fixed::<_, BITS, S>(self, value)
978 }
979
980 #[inline]
981 fn write_from<V>(&mut self, value: V) -> io::Result<()>
982 where
983 V: Primitive,
984 {
985 E::write_primitive(self, value)
986 }
987
988 #[inline]
989 fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()>
990 where
991 F: Endianness,
992 V: Primitive,
993 {
994 F::write_primitive(self, value)
995 }
996
997 #[inline]
998 fn write_unary1(&mut self, value: u32) -> io::Result<()> {
999 self.bits += (value + 1).into();
1000 Ok(())
1001 }
1002
1003 #[inline]
1004 fn write_unary0(&mut self, value: u32) -> io::Result<()> {
1005 self.bits += (value + 1).into();
1006 Ok(())
1007 }
1008
1009 #[inline]
1010 fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
1011 self.bits += (buf.len() as u32 * 8).into();
1012 Ok(())
1013 }
1014
1015 #[inline]
1016 fn byte_aligned(&self) -> bool {
1017 self.bits % 8.into() == 0.into()
1018 }
1019}
1020
1021impl<N, E> HuffmanWrite<E> for BitCounter<N, E>
1022where
1023 E: Endianness,
1024 N: AddAssign + From<u32>,
1025{
1026 fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
1027 where
1028 T: Ord + Copy,
1029 {
1030 for &(bits, _) in tree.get(&symbol) {
1031 let bits: N = bits.into();
1032 self.bits += bits;
1033 }
1034 Ok(())
1035 }
1036}
1037
1038/// A generic unsigned value for stream recording purposes
1039pub struct UnsignedValue(InnerUnsignedValue);
1040
1041enum InnerUnsignedValue {
1042 U8(u8),
1043 U16(u16),
1044 U32(u32),
1045 U64(u64),
1046 U128(u128),
1047 I8(i8),
1048 I16(i16),
1049 I32(i32),
1050 I64(i64),
1051 I128(i128),
1052}
1053
1054macro_rules! define_unsigned_value {
1055 ($t:ty, $n:ident) => {
1056 impl From<$t> for UnsignedValue {
1057 #[inline]
1058 fn from(v: $t) -> Self {
1059 UnsignedValue(InnerUnsignedValue::$n(v))
1060 }
1061 }
1062 };
1063}
1064define_unsigned_value!(u8, U8);
1065define_unsigned_value!(u16, U16);
1066define_unsigned_value!(u32, U32);
1067define_unsigned_value!(u64, U64);
1068define_unsigned_value!(u128, U128);
1069define_unsigned_value!(i8, I8);
1070define_unsigned_value!(i16, I16);
1071define_unsigned_value!(i32, I32);
1072define_unsigned_value!(i64, I64);
1073define_unsigned_value!(i128, I128);
1074
1075/// A generic signed value for stream recording purposes
1076pub struct SignedValue(InnerSignedValue);
1077
1078enum InnerSignedValue {
1079 I8(i8),
1080 I16(i16),
1081 I32(i32),
1082 I64(i64),
1083 I128(i128),
1084}
1085
1086macro_rules! define_signed_value {
1087 ($t:ty, $n:ident) => {
1088 impl From<$t> for SignedValue {
1089 #[inline]
1090 fn from(v: $t) -> Self {
1091 SignedValue(InnerSignedValue::$n(v))
1092 }
1093 }
1094 };
1095}
1096define_signed_value!(i8, I8);
1097define_signed_value!(i16, I16);
1098define_signed_value!(i32, I32);
1099define_signed_value!(i64, I64);
1100define_signed_value!(i128, I128);
1101
1102enum WriteRecord {
1103 Bit(bool),
1104 Unsigned { bits: u32, value: UnsignedValue },
1105 Signed { bits: u32, value: SignedValue },
1106 Unary0(u32),
1107 Unary1(u32),
1108 Bytes(Box<[u8]>),
1109}
1110
1111impl WriteRecord {
1112 fn playback<W: BitWrite>(&self, writer: &mut W) -> io::Result<()> {
1113 match self {
1114 WriteRecord::Bit(v) => writer.write_bit(*v),
1115 WriteRecord::Unsigned {
1116 bits,
1117 value: UnsignedValue(value),
1118 } => match value {
1119 InnerUnsignedValue::U8(v) => writer.write(*bits, *v),
1120 InnerUnsignedValue::U16(v) => writer.write(*bits, *v),
1121 InnerUnsignedValue::U32(v) => writer.write(*bits, *v),
1122 InnerUnsignedValue::U64(v) => writer.write(*bits, *v),
1123 InnerUnsignedValue::U128(v) => writer.write(*bits, *v),
1124 InnerUnsignedValue::I8(v) => writer.write(*bits, *v),
1125 InnerUnsignedValue::I16(v) => writer.write(*bits, *v),
1126 InnerUnsignedValue::I32(v) => writer.write(*bits, *v),
1127 InnerUnsignedValue::I64(v) => writer.write(*bits, *v),
1128 InnerUnsignedValue::I128(v) => writer.write(*bits, *v),
1129 },
1130 WriteRecord::Signed {
1131 bits,
1132 value: SignedValue(value),
1133 } => match value {
1134 InnerSignedValue::I8(v) => writer.write_signed(*bits, *v),
1135 InnerSignedValue::I16(v) => writer.write_signed(*bits, *v),
1136 InnerSignedValue::I32(v) => writer.write_signed(*bits, *v),
1137 InnerSignedValue::I64(v) => writer.write_signed(*bits, *v),
1138 InnerSignedValue::I128(v) => writer.write_signed(*bits, *v),
1139 },
1140 WriteRecord::Unary0(v) => writer.write_unary0(*v),
1141 WriteRecord::Unary1(v) => writer.write_unary1(*v),
1142 WriteRecord::Bytes(bytes) => writer.write_bytes(bytes),
1143 }
1144 }
1145}
1146
1147/// For recording writes in order to play them back on another writer
1148/// # Example
1149/// ```
1150/// use std::io::Write;
1151/// use bitstream_io::{BigEndian, BitWriter, BitWrite, BitRecorder};
1152/// let mut recorder: BitRecorder<u32, BigEndian> = BitRecorder::new();
1153/// recorder.write(1, 0b1).unwrap();
1154/// recorder.write(2, 0b01).unwrap();
1155/// recorder.write(5, 0b10111).unwrap();
1156/// assert_eq!(recorder.written(), 8);
1157/// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
1158/// recorder.playback(&mut writer);
1159/// assert_eq!(writer.into_writer(), [0b10110111]);
1160/// ```
1161#[derive(Default)]
1162pub struct BitRecorder<N, E: Endianness> {
1163 counter: BitCounter<N, E>,
1164 records: Vec<WriteRecord>,
1165}
1166
1167impl<N: Default + Copy, E: Endianness> BitRecorder<N, E> {
1168 /// Creates new recorder
1169 #[inline]
1170 pub fn new() -> Self {
1171 BitRecorder {
1172 counter: BitCounter::new(),
1173 records: Vec::new(),
1174 }
1175 }
1176
1177 /// Creates new recorder sized for the given number of writes
1178 #[inline]
1179 pub fn with_capacity(writes: usize) -> Self {
1180 BitRecorder {
1181 counter: BitCounter::new(),
1182 records: Vec::with_capacity(writes),
1183 }
1184 }
1185
1186 /// Creates new recorder with the given endianness
1187 #[inline]
1188 pub fn endian(_endian: E) -> Self {
1189 BitRecorder {
1190 counter: BitCounter::new(),
1191 records: Vec::new(),
1192 }
1193 }
1194
1195 /// Returns number of bits written
1196 #[inline]
1197 pub fn written(&self) -> N {
1198 self.counter.written()
1199 }
1200
1201 /// Plays recorded writes to the given writer
1202 #[inline]
1203 pub fn playback<W: BitWrite>(&self, writer: &mut W) -> io::Result<()> {
1204 self.records
1205 .iter()
1206 .try_for_each(|record| record.playback(writer))
1207 }
1208}
1209
1210impl<N, E> BitWrite for BitRecorder<N, E>
1211where
1212 E: Endianness,
1213 N: Copy + From<u32> + AddAssign + Rem<Output = N> + Eq,
1214{
1215 #[inline]
1216 fn write_bit(&mut self, bit: bool) -> io::Result<()> {
1217 self.records.push(WriteRecord::Bit(bit));
1218 self.counter.write_bit(bit)
1219 }
1220
1221 #[inline]
1222 fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
1223 where
1224 U: Numeric,
1225 {
1226 self.counter.write(bits, value)?;
1227 self.records.push(WriteRecord::Unsigned {
1228 bits,
1229 value: value.unsigned_value(),
1230 });
1231 Ok(())
1232 }
1233
1234 #[inline]
1235 fn write_out<const BITS: u32, U>(&mut self, value: U) -> io::Result<()>
1236 where
1237 U: Numeric,
1238 {
1239 self.counter.write_out::<BITS, U>(value)?;
1240 self.records.push(WriteRecord::Unsigned {
1241 bits: BITS,
1242 value: value.unsigned_value(),
1243 });
1244 Ok(())
1245 }
1246
1247 #[inline]
1248 fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
1249 where
1250 S: SignedNumeric,
1251 {
1252 self.counter.write_signed(bits, value)?;
1253 self.records.push(WriteRecord::Signed {
1254 bits,
1255 value: value.signed_value(),
1256 });
1257 Ok(())
1258 }
1259
1260 #[inline]
1261 fn write_signed_out<const BITS: u32, S>(&mut self, value: S) -> io::Result<()>
1262 where
1263 S: SignedNumeric,
1264 {
1265 self.counter.write_signed_out::<BITS, S>(value)?;
1266 self.records.push(WriteRecord::Signed {
1267 bits: BITS,
1268 value: value.signed_value(),
1269 });
1270 Ok(())
1271 }
1272
1273 #[inline]
1274 fn write_from<V>(&mut self, value: V) -> io::Result<()>
1275 where
1276 V: Primitive,
1277 {
1278 E::write_primitive(self, value)
1279 }
1280
1281 #[inline]
1282 fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()>
1283 where
1284 F: Endianness,
1285 V: Primitive,
1286 {
1287 F::write_primitive(self, value)
1288 }
1289
1290 #[inline]
1291 fn write_unary0(&mut self, value: u32) -> io::Result<()> {
1292 self.records.push(WriteRecord::Unary0(value));
1293 self.counter.write_unary0(value)
1294 }
1295
1296 #[inline]
1297 fn write_unary1(&mut self, value: u32) -> io::Result<()> {
1298 self.records.push(WriteRecord::Unary1(value));
1299 self.counter.write_unary1(value)
1300 }
1301
1302 #[inline]
1303 fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
1304 self.records.push(WriteRecord::Bytes(buf.into()));
1305 self.counter.write_bytes(buf)
1306 }
1307
1308 #[inline]
1309 fn byte_aligned(&self) -> bool {
1310 self.counter.byte_aligned()
1311 }
1312}
1313
1314impl<N, E> HuffmanWrite<E> for BitRecorder<N, E>
1315where
1316 E: Endianness,
1317 N: Copy + From<u32> + AddAssign + Rem<Output = N> + Eq,
1318{
1319 #[inline]
1320 fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
1321 where
1322 T: Ord + Copy,
1323 {
1324 tree.get(&symbol)
1325 .try_for_each(|(bits, value)| self.write(*bits, *value))
1326 }
1327}
1328
1329#[inline]
1330fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
1331where
1332 W: io::Write,
1333{
1334 writer.write_all(core::slice::from_ref(&byte))
1335}
1336
1337fn write_unaligned<W, E, N>(
1338 writer: W,
1339 acc: &mut BitQueue<E, N>,
1340 rem: &mut BitQueue<E, u8>,
1341) -> io::Result<()>
1342where
1343 W: io::Write,
1344 E: Endianness,
1345 N: Numeric,
1346{
1347 if rem.is_empty() {
1348 Ok(())
1349 } else {
1350 use core::cmp::min;
1351 let bits_to_transfer = min(8 - rem.len(), acc.len());
1352 rem.push(bits_to_transfer, acc.pop(bits_to_transfer).to_u8());
1353 if rem.len() == 8 {
1354 write_byte(writer, rem.pop(8))
1355 } else {
1356 Ok(())
1357 }
1358 }
1359}
1360
1361fn write_aligned<W, E, N>(mut writer: W, acc: &mut BitQueue<E, N>) -> io::Result<()>
1362where
1363 W: io::Write,
1364 E: Endianness,
1365 N: Numeric,
1366{
1367 let to_write = (acc.len() / 8) as usize;
1368 if to_write > 0 {
1369 let mut buf = N::buffer();
1370 let buf_ref: &mut [u8] = buf.as_mut();
1371 for b in buf_ref[0..to_write].iter_mut() {
1372 *b = acc.pop_fixed::<8>().to_u8();
1373 }
1374 writer.write_all(&buf_ref[0..to_write])
1375 } else {
1376 Ok(())
1377 }
1378}
1379
1380/// For writing aligned bytes to a stream of bytes in a given endianness.
1381///
1382/// This only writes aligned values and maintains no internal state.
1383pub struct ByteWriter<W: io::Write, E: Endianness> {
1384 phantom: PhantomData<E>,
1385 writer: W,
1386}
1387
1388impl<W: io::Write, E: Endianness> ByteWriter<W, E> {
1389 /// Wraps a ByteWriter around something that implements `Write`
1390 pub fn new(writer: W) -> ByteWriter<W, E> {
1391 ByteWriter {
1392 phantom: PhantomData,
1393 writer,
1394 }
1395 }
1396
1397 /// Wraps a BitWriter around something that implements `Write`
1398 /// with the given endianness.
1399 pub fn endian(writer: W, _endian: E) -> ByteWriter<W, E> {
1400 ByteWriter {
1401 phantom: PhantomData,
1402 writer,
1403 }
1404 }
1405
1406 /// Unwraps internal writer and disposes of `ByteWriter`.
1407 /// Any unwritten partial bits are discarded.
1408 #[inline]
1409 pub fn into_writer(self) -> W {
1410 self.writer
1411 }
1412
1413 /// Provides mutable reference to internal writer.
1414 #[inline]
1415 pub fn writer(&mut self) -> &mut W {
1416 &mut self.writer
1417 }
1418
1419 /// Converts `ByteWriter` to `BitWriter` in the same endianness.
1420 #[inline]
1421 pub fn into_bitwriter(self) -> BitWriter<W, E> {
1422 BitWriter::new(self.into_writer())
1423 }
1424
1425 /// Provides temporary `BitWriter` in the same endianness.
1426 ///
1427 /// # Warning
1428 ///
1429 /// Any unwritten bits left over when `BitWriter` is dropped are lost.
1430 #[inline]
1431 pub fn bitwriter(&mut self) -> BitWriter<&mut W, E> {
1432 BitWriter::new(self.writer())
1433 }
1434}
1435
1436/// A trait for anything that can write aligned values to an output stream
1437pub trait ByteWrite {
1438 /// Writes whole numeric value to stream
1439 ///
1440 /// # Errors
1441 ///
1442 /// Passes along any I/O error from the underlying stream.
1443 /// # Examples
1444 /// ```
1445 /// use std::io::Write;
1446 /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite};
1447 /// let mut writer = ByteWriter::endian(Vec::new(), BigEndian);
1448 /// writer.write(0b0000000011111111u16).unwrap();
1449 /// assert_eq!(writer.into_writer(), [0b00000000, 0b11111111]);
1450 /// ```
1451 ///
1452 /// ```
1453 /// use std::io::Write;
1454 /// use bitstream_io::{LittleEndian, ByteWriter, ByteWrite};
1455 /// let mut writer = ByteWriter::endian(Vec::new(), LittleEndian);
1456 /// writer.write(0b0000000011111111u16).unwrap();
1457 /// assert_eq!(writer.into_writer(), [0b11111111, 0b00000000]);
1458 /// ```
1459 fn write<V>(&mut self, value: V) -> io::Result<()>
1460 where
1461 V: Primitive;
1462
1463 /// Writes whole numeric value to stream in a potentially different endianness
1464 ///
1465 /// # Errors
1466 ///
1467 /// Passes along any I/O error from the underlying stream.
1468 ///
1469 /// # Examples
1470 /// ```
1471 /// use std::io::Write;
1472 /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite, LittleEndian};
1473 /// let mut writer = ByteWriter::endian(Vec::new(), BigEndian);
1474 /// writer.write_as::<LittleEndian, u16>(0b0000000011111111).unwrap();
1475 /// assert_eq!(writer.into_writer(), [0b11111111, 0b00000000]);
1476 /// ```
1477 ///
1478 /// ```
1479 /// use std::io::Write;
1480 /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite, LittleEndian};
1481 /// let mut writer = ByteWriter::endian(Vec::new(), LittleEndian);
1482 /// writer.write_as::<BigEndian, u16>(0b0000000011111111).unwrap();
1483 /// assert_eq!(writer.into_writer(), [0b00000000, 0b11111111]);
1484 /// ```
1485 fn write_as<F, V>(&mut self, value: V) -> io::Result<()>
1486 where
1487 F: Endianness,
1488 V: Primitive;
1489
1490 /// Writes the entirety of a byte buffer to the stream.
1491 ///
1492 /// # Errors
1493 ///
1494 /// Passes along any I/O error from the underlying stream.
1495 fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()>;
1496
1497 /// Builds and writes complex type
1498 fn build<T: ToByteStream>(&mut self, build: &T) -> Result<(), T::Error> {
1499 build.to_writer(self)
1500 }
1501
1502 /// Builds and writes complex type with context
1503 fn build_with<'a, T: ToByteStreamWith<'a>>(
1504 &mut self,
1505 build: &T,
1506 context: &T::Context,
1507 ) -> Result<(), T::Error> {
1508 build.to_writer(self, context)
1509 }
1510
1511 /// Returns mutable reference to underlying writer
1512 fn writer_ref(&mut self) -> &mut dyn io::Write;
1513}
1514
1515impl<W: io::Write, E: Endianness> ByteWrite for ByteWriter<W, E> {
1516 #[inline]
1517 fn write<V>(&mut self, value: V) -> io::Result<()>
1518 where
1519 V: Primitive,
1520 {
1521 E::write_numeric(&mut self.writer, value)
1522 }
1523
1524 #[inline]
1525 fn write_as<F, V>(&mut self, value: V) -> io::Result<()>
1526 where
1527 F: Endianness,
1528 V: Primitive,
1529 {
1530 F::write_numeric(&mut self.writer, value)
1531 }
1532
1533 #[inline]
1534 fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
1535 self.writer.write_all(buf)
1536 }
1537
1538 #[inline]
1539 fn writer_ref(&mut self) -> &mut dyn io::Write {
1540 &mut self.writer
1541 }
1542}
1543
1544/// Implemented by complex types that don't require any additional context
1545/// to build themselves to a writer
1546///
1547/// # Example
1548/// ```
1549/// use std::io::{Cursor, Read};
1550/// use bitstream_io::{BigEndian, BitWrite, BitWriter, ToBitStream};
1551///
1552/// #[derive(Debug, PartialEq, Eq)]
1553/// struct BlockHeader {
1554/// last_block: bool,
1555/// block_type: u8,
1556/// block_size: u32,
1557/// }
1558///
1559/// impl ToBitStream for BlockHeader {
1560/// type Error = std::io::Error;
1561///
1562/// fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
1563/// w.write_bit(self.last_block)?;
1564/// w.write(7, self.block_type)?;
1565/// w.write(24, self.block_size)
1566/// }
1567/// }
1568///
1569/// let mut data = Vec::new();
1570/// let mut writer = BitWriter::endian(&mut data, BigEndian);
1571/// writer.build(&BlockHeader { last_block: false, block_type: 4, block_size: 122 }).unwrap();
1572/// assert_eq!(data, b"\x04\x00\x00\x7A");
1573/// ```
1574pub trait ToBitStream {
1575 /// Error generated during building, such as `io::Error`
1576 type Error;
1577
1578 /// Generate self to writer
1579 fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> Result<(), Self::Error>
1580 where
1581 Self: Sized;
1582}
1583
1584/// Implemented by complex types that require additional context
1585/// to build themselves to a writer
1586pub trait ToBitStreamWith<'a> {
1587 /// Some context to use when writing
1588 type Context: 'a;
1589
1590 /// Error generated during building, such as `io::Error`
1591 type Error;
1592
1593 /// Generate self to writer
1594 fn to_writer<W: BitWrite + ?Sized>(
1595 &self,
1596 w: &mut W,
1597 context: &Self::Context,
1598 ) -> Result<(), Self::Error>
1599 where
1600 Self: Sized;
1601}
1602
1603/// Implemented by complex types that don't require any additional context
1604/// to build themselves to a writer
1605pub trait ToByteStream {
1606 /// Error generated during building, such as `io::Error`
1607 type Error;
1608
1609 /// Generate self to writer
1610 fn to_writer<W: ByteWrite + ?Sized>(&self, w: &mut W) -> Result<(), Self::Error>
1611 where
1612 Self: Sized;
1613}
1614
1615/// Implemented by complex types that require additional context
1616/// to build themselves to a writer
1617pub trait ToByteStreamWith<'a> {
1618 /// Some context to use when writing
1619 type Context: 'a;
1620
1621 /// Error generated during building, such as `io::Error`
1622 type Error;
1623
1624 /// Generate self to writer
1625 fn to_writer<W: ByteWrite + ?Sized>(
1626 &self,
1627 w: &mut W,
1628 context: &Self::Context,
1629 ) -> Result<(), Self::Error>
1630 where
1631 Self: Sized;
1632}