Coverage Report

Created: 2025-10-10 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitstream-io-1.10.0/src/write.rs
Line
Count
Source
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,
25
//!     block_type: u8,
26
//!     block_size: u32,
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(7, self.block_type)?;
35
//!         w.write(24, self.block_size)
36
//!     }
37
//! }
38
//!
39
//! #[derive(Debug, PartialEq, Eq)]
40
//! struct Streaminfo {
41
//!     minimum_block_size: u16,
42
//!     maximum_block_size: u16,
43
//!     minimum_frame_size: u32,
44
//!     maximum_frame_size: u32,
45
//!     sample_rate: u32,
46
//!     channels: u8,
47
//!     bits_per_sample: u8,
48
//!     total_samples: u64,
49
//!     md5: [u8; 16],
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(24, self.minimum_frame_size)?;
59
//!         w.write(24, self.maximum_frame_size)?;
60
//!         w.write(20, self.sample_rate)?;
61
//!         w.write(3, self.channels - 1)?;
62
//!         w.write(5, self.bits_per_sample - 1)?;
63
//!         w.write(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
use std::convert::From;
167
use std::io;
168
use std::ops::{AddAssign, Rem};
169
170
use super::{
171
    huffman::WriteHuffmanTree, BitQueue, Endianness, Numeric, PhantomData, Primitive, SignedNumeric,
172
};
173
174
/// For writing bit values to an underlying stream in a given endianness.
175
///
176
/// Because this only writes whole bytes to the underlying stream,
177
/// it is important that output is byte-aligned before the bitstream
178
/// writer's lifetime ends.
179
/// **Partial bytes will be lost** if the writer is disposed of
180
/// before they can be written.
181
pub struct BitWriter<W: io::Write, E: Endianness> {
182
    writer: W,
183
    bitqueue: BitQueue<E, u8>,
184
}
185
186
impl<W: io::Write, E: Endianness> BitWriter<W, E> {
187
    /// Wraps a BitWriter around something that implements `Write`
188
0
    pub fn new(writer: W) -> BitWriter<W, E> {
189
0
        BitWriter {
190
0
            writer,
191
0
            bitqueue: BitQueue::new(),
192
0
        }
193
0
    }
194
195
    /// Wraps a BitWriter around something that implements `Write`
196
    /// with the given endianness.
197
0
    pub fn endian(writer: W, _endian: E) -> BitWriter<W, E> {
198
0
        BitWriter {
199
0
            writer,
200
0
            bitqueue: BitQueue::new(),
201
0
        }
202
0
    }
203
204
    /// Unwraps internal writer and disposes of BitWriter.
205
    ///
206
    /// # Warning
207
    ///
208
    /// Any unwritten partial bits are discarded.
209
    #[inline]
210
0
    pub fn into_writer(self) -> W {
211
0
        self.writer
212
0
    }
213
214
    /// If stream is byte-aligned, provides mutable reference
215
    /// to internal writer.  Otherwise returns `None`
216
    #[inline]
217
0
    pub fn writer(&mut self) -> Option<&mut W> {
218
0
        if self.byte_aligned() {
219
0
            Some(&mut self.writer)
220
        } else {
221
0
            None
222
        }
223
0
    }
224
225
    /// Converts `BitWriter` to `ByteWriter` in the same endianness.
226
    ///
227
    /// # Warning
228
    ///
229
    /// Any written partial bits are discarded.
230
    #[inline]
231
0
    pub fn into_bytewriter(self) -> ByteWriter<W, E> {
232
0
        ByteWriter::new(self.into_writer())
233
0
    }
234
235
    /// If stream is byte-aligned, provides temporary `ByteWriter`
236
    /// in the same endianness.  Otherwise returns `None`
237
    ///
238
    /// # Warning
239
    ///
240
    /// Any unwritten bits left over when `ByteWriter` is dropped are lost.
241
    #[inline]
242
0
    pub fn bytewriter(&mut self) -> Option<ByteWriter<&mut W, E>> {
243
0
        self.writer().map(ByteWriter::new)
244
0
    }
245
246
    /// Consumes writer and returns any un-written partial byte
247
    /// as a `(bits, value)` tuple.
248
    ///
249
    /// # Examples
250
    /// ```
251
    /// use std::io::Write;
252
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
253
    /// let mut data = Vec::new();
254
    /// let (bits, value) = {
255
    ///     let mut writer = BitWriter::endian(&mut data, BigEndian);
256
    ///     writer.write(15, 0b1010_0101_0101_101).unwrap();
257
    ///     writer.into_unwritten()
258
    /// };
259
    /// assert_eq!(data, [0b1010_0101]);
260
    /// assert_eq!(bits, 7);
261
    /// assert_eq!(value, 0b0101_101);
262
    /// ```
263
    ///
264
    /// ```
265
    /// use std::io::Write;
266
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
267
    /// let mut data = Vec::new();
268
    /// let (bits, value) = {
269
    ///     let mut writer = BitWriter::endian(&mut data, BigEndian);
270
    ///     writer.write(8, 0b1010_0101).unwrap();
271
    ///     writer.into_unwritten()
272
    /// };
273
    /// assert_eq!(data, [0b1010_0101]);
274
    /// assert_eq!(bits, 0);
275
    /// assert_eq!(value, 0);
276
    /// ```
277
    #[inline(always)]
278
0
    pub fn into_unwritten(self) -> (u32, u8) {
279
0
        (self.bitqueue.len(), self.bitqueue.value())
280
0
    }
281
282
    /// Flushes output stream to disk, if necessary.
283
    /// Any partial bytes are not flushed.
284
    ///
285
    /// # Errors
286
    ///
287
    /// Passes along any errors from the underlying stream.
288
    #[inline(always)]
289
0
    pub fn flush(&mut self) -> io::Result<()> {
290
0
        self.writer.flush()
291
0
    }
292
}
293
294
/// A trait for anything that can write a variable number of
295
/// potentially un-aligned values to an output stream
296
pub trait BitWrite {
297
    /// Writes a single bit to the stream.
298
    /// `true` indicates 1, `false` indicates 0
299
    ///
300
    /// # Errors
301
    ///
302
    /// Passes along any I/O error from the underlying stream.
303
    fn write_bit(&mut self, bit: bool) -> io::Result<()>;
304
305
    /// Writes an unsigned value to the stream using the given
306
    /// number of bits.
307
    ///
308
    /// # Errors
309
    ///
310
    /// Passes along any I/O error from the underlying stream.
311
    /// Returns an error if the input type is too small
312
    /// to hold the given number of bits.
313
    /// Returns an error if the value is too large
314
    /// to fit the given number of bits.
315
    fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
316
    where
317
        U: Numeric;
318
319
    /// Writes a twos-complement signed value to the stream
320
    /// with the given number of bits.
321
    ///
322
    /// # Errors
323
    ///
324
    /// Passes along any I/O error from the underlying stream.
325
    /// Returns an error if the input type is too small
326
    /// to hold the given number of bits.
327
    /// Returns an error if the value is too large
328
    /// to fit the given number of bits.
329
    fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
330
    where
331
        S: SignedNumeric;
332
333
    /// Writes whole value to the stream whose size in bits
334
    ///  is equal to its type's size.
335
    ///
336
    /// # Errors
337
    ///
338
    /// Passes along any I/O error from the underlying stream.
339
    fn write_from<V>(&mut self, value: V) -> io::Result<()>
340
    where
341
        V: Primitive;
342
343
    /// Writes the entirety of a byte buffer to the stream.
344
    ///
345
    /// # Errors
346
    ///
347
    /// Passes along any I/O error from the underlying stream.
348
    ///
349
    /// # Example
350
    ///
351
    /// ```
352
    /// use std::io::Write;
353
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
354
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
355
    /// writer.write(8, 0x66).unwrap();
356
    /// writer.write(8, 0x6F).unwrap();
357
    /// writer.write(8, 0x6F).unwrap();
358
    /// writer.write_bytes(b"bar").unwrap();
359
    /// assert_eq!(writer.into_writer(), b"foobar");
360
    /// ```
361
    #[inline]
362
0
    fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
363
0
        buf.iter().try_for_each(|b| self.write(8, *b))
364
0
    }
365
366
    /// Writes `value` number of 1 bits to the stream
367
    /// and then writes a 0 bit.  This field is variably-sized.
368
    ///
369
    /// # Errors
370
    ///
371
    /// Passes along any I/O error from the underyling stream.
372
    ///
373
    /// # Examples
374
    /// ```
375
    /// use std::io::Write;
376
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
377
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
378
    /// writer.write_unary0(0).unwrap();
379
    /// writer.write_unary0(3).unwrap();
380
    /// writer.write_unary0(10).unwrap();
381
    /// assert_eq!(writer.into_writer(), [0b01110111, 0b11111110]);
382
    /// ```
383
    ///
384
    /// ```
385
    /// use std::io::Write;
386
    /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
387
    /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
388
    /// writer.write_unary0(0).unwrap();
389
    /// writer.write_unary0(3).unwrap();
390
    /// writer.write_unary0(10).unwrap();
391
    /// assert_eq!(writer.into_writer(), [0b11101110, 0b01111111]);
392
    /// ```
393
0
    fn write_unary0(&mut self, value: u32) -> io::Result<()> {
394
0
        match value {
395
0
            0 => self.write_bit(false),
396
0
            bits @ 1..=31 => self
397
0
                .write(value, (1u32 << bits) - 1)
398
0
                .and_then(|()| self.write_bit(false)),
399
0
            32 => self
400
0
                .write(value, 0xFFFF_FFFFu32)
401
0
                .and_then(|()| self.write_bit(false)),
402
0
            bits @ 33..=63 => self
403
0
                .write(value, (1u64 << bits) - 1)
404
0
                .and_then(|()| self.write_bit(false)),
405
0
            64 => self
406
0
                .write(value, 0xFFFF_FFFF_FFFF_FFFFu64)
407
0
                .and_then(|()| self.write_bit(false)),
408
0
            mut bits => {
409
0
                while bits > 64 {
410
0
                    self.write(64, 0xFFFF_FFFF_FFFF_FFFFu64)?;
411
0
                    bits -= 64;
412
                }
413
0
                self.write_unary0(bits)
414
            }
415
        }
416
0
    }
417
418
    /// Writes `value` number of 0 bits to the stream
419
    /// and then writes a 1 bit.  This field is variably-sized.
420
    ///
421
    /// # Errors
422
    ///
423
    /// Passes along any I/O error from the underyling stream.
424
    ///
425
    /// # Example
426
    /// ```
427
    /// use std::io::Write;
428
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
429
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
430
    /// writer.write_unary1(0).unwrap();
431
    /// writer.write_unary1(3).unwrap();
432
    /// writer.write_unary1(10).unwrap();
433
    /// assert_eq!(writer.into_writer(), [0b10001000, 0b00000001]);
434
    /// ```
435
    ///
436
    /// ```
437
    /// use std::io::Write;
438
    /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
439
    /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
440
    /// writer.write_unary1(0).unwrap();
441
    /// writer.write_unary1(3).unwrap();
442
    /// writer.write_unary1(10).unwrap();
443
    /// assert_eq!(writer.into_writer(), [0b00010001, 0b10000000]);
444
    /// ```
445
0
    fn write_unary1(&mut self, value: u32) -> io::Result<()> {
446
0
        match value {
447
0
            0 => self.write_bit(true),
448
0
            1..=32 => self.write(value, 0u32).and_then(|()| self.write_bit(true)),
449
0
            33..=64 => self.write(value, 0u64).and_then(|()| self.write_bit(true)),
450
0
            mut bits => {
451
0
                while bits > 64 {
452
0
                    self.write(64, 0u64)?;
453
0
                    bits -= 64;
454
                }
455
0
                self.write_unary1(bits)
456
            }
457
        }
458
0
    }
459
460
    /// Builds and writes complex type
461
0
    fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> {
462
0
        build.to_writer(self)
463
0
    }
464
465
    /// Builds and writes complex type with context
466
0
    fn build_with<T: ToBitStreamWith>(
467
0
        &mut self,
468
0
        build: &T,
469
0
        context: &T::Context,
470
0
    ) -> Result<(), T::Error> {
471
0
        build.to_writer(self, context)
472
0
    }
473
474
    /// Returns true if the stream is aligned at a whole byte.
475
    fn byte_aligned(&self) -> bool;
476
477
    /// Pads the stream with 0 bits until it is aligned at a whole byte.
478
    /// Does nothing if the stream is already aligned.
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(1, 0).unwrap();
490
    /// writer.byte_align().unwrap();
491
    /// writer.write(8, 0xFF).unwrap();
492
    /// assert_eq!(writer.into_writer(), [0x00, 0xFF]);
493
    /// ```
494
0
    fn byte_align(&mut self) -> io::Result<()> {
495
0
        while !self.byte_aligned() {
496
0
            self.write_bit(false)?;
497
        }
498
0
        Ok(())
499
0
    }
500
}
501
502
/// A trait for anything that can write Huffman codes
503
/// of a given endianness to an output stream
504
pub trait HuffmanWrite<E: Endianness> {
505
    /// Writes Huffman code for the given symbol to the stream.
506
    ///
507
    /// # Errors
508
    ///
509
    /// Passes along any I/O error from the underlying stream.
510
    fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
511
    where
512
        T: Ord + Copy;
513
}
514
515
impl<W: io::Write, E: Endianness> BitWrite for BitWriter<W, E> {
516
    /// # Examples
517
    /// ```
518
    /// use std::io::Write;
519
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
520
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
521
    /// writer.write_bit(true).unwrap();
522
    /// writer.write_bit(false).unwrap();
523
    /// writer.write_bit(true).unwrap();
524
    /// writer.write_bit(true).unwrap();
525
    /// writer.write_bit(false).unwrap();
526
    /// writer.write_bit(true).unwrap();
527
    /// writer.write_bit(true).unwrap();
528
    /// writer.write_bit(true).unwrap();
529
    /// assert_eq!(writer.into_writer(), [0b10110111]);
530
    /// ```
531
    ///
532
    /// ```
533
    /// use std::io::Write;
534
    /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
535
    /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
536
    /// writer.write_bit(true).unwrap();
537
    /// writer.write_bit(true).unwrap();
538
    /// writer.write_bit(true).unwrap();
539
    /// writer.write_bit(false).unwrap();
540
    /// writer.write_bit(true).unwrap();
541
    /// writer.write_bit(true).unwrap();
542
    /// writer.write_bit(false).unwrap();
543
    /// writer.write_bit(true).unwrap();
544
    /// assert_eq!(writer.into_writer(), [0b10110111]);
545
    /// ```
546
0
    fn write_bit(&mut self, bit: bool) -> io::Result<()> {
547
0
        self.bitqueue.push(1, u8::from(bit));
548
0
        if self.bitqueue.is_full() {
549
0
            write_byte(&mut self.writer, self.bitqueue.pop(8))
550
        } else {
551
0
            Ok(())
552
        }
553
0
    }
554
555
    /// # Examples
556
    /// ```
557
    /// use std::io::Write;
558
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
559
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
560
    /// writer.write(1, 0b1).unwrap();
561
    /// writer.write(2, 0b01).unwrap();
562
    /// writer.write(5, 0b10111).unwrap();
563
    /// assert_eq!(writer.into_writer(), [0b10110111]);
564
    /// ```
565
    ///
566
    /// ```
567
    /// use std::io::Write;
568
    /// use bitstream_io::{LittleEndian, BitWriter, BitWrite};
569
    /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian);
570
    /// writer.write(1, 0b1).unwrap();
571
    /// writer.write(2, 0b11).unwrap();
572
    /// writer.write(5, 0b10110).unwrap();
573
    /// assert_eq!(writer.into_writer(), [0b10110111]);
574
    /// ```
575
    ///
576
    /// ```
577
    /// use std::io::{Write, sink};
578
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
579
    /// let mut w = BitWriter::endian(sink(), BigEndian);
580
    /// assert!(w.write(9, 0u8).is_err());    // can't write  u8 in 9 bits
581
    /// assert!(w.write(17, 0u16).is_err());  // can't write u16 in 17 bits
582
    /// assert!(w.write(33, 0u32).is_err());  // can't write u32 in 33 bits
583
    /// assert!(w.write(65, 0u64).is_err());  // can't write u64 in 65 bits
584
    /// assert!(w.write(1, 2).is_err());      // can't write   2 in 1 bit
585
    /// assert!(w.write(2, 4).is_err());      // can't write   4 in 2 bits
586
    /// assert!(w.write(3, 8).is_err());      // can't write   8 in 3 bits
587
    /// assert!(w.write(4, 16).is_err());     // can't write  16 in 4 bits
588
    /// ```
589
0
    fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
590
0
    where
591
0
        U: Numeric,
592
    {
593
0
        if bits > U::BITS_SIZE {
594
0
            Err(io::Error::new(
595
0
                io::ErrorKind::InvalidInput,
596
0
                "excessive bits for type written",
597
0
            ))
598
0
        } else if (bits < U::BITS_SIZE) && (value >= (U::ONE << bits)) {
599
0
            Err(io::Error::new(
600
0
                io::ErrorKind::InvalidInput,
601
0
                "excessive value for bits written",
602
0
            ))
603
0
        } else if bits < self.bitqueue.remaining_len() {
604
0
            self.bitqueue.push(bits, value.to_u8());
605
0
            Ok(())
606
        } else {
607
0
            let mut acc = BitQueue::from_value(value, bits);
608
0
            write_unaligned(&mut self.writer, &mut acc, &mut self.bitqueue)?;
609
0
            write_aligned(&mut self.writer, &mut acc)?;
610
0
            self.bitqueue.push(acc.len(), acc.value().to_u8());
611
0
            Ok(())
612
        }
613
0
    }
614
615
    /// # Examples
616
    /// ```
617
    /// use std::io::Write;
618
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
619
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
620
    /// writer.write_signed(4, -5).unwrap();
621
    /// writer.write_signed(4, 7).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_signed(4, 7).unwrap();
630
    /// writer.write_signed(4, -5).unwrap();
631
    /// assert_eq!(writer.into_writer(), [0b10110111]);
632
    /// ```
633
    #[inline]
634
0
    fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
635
0
    where
636
0
        S: SignedNumeric,
637
    {
638
0
        E::write_signed(self, bits, value)
639
0
    }
640
641
    #[inline]
642
0
    fn write_from<V>(&mut self, value: V) -> io::Result<()>
643
0
    where
644
0
        V: Primitive,
645
    {
646
0
        E::write_primitive(self, value)
647
0
    }
648
649
    #[inline]
650
0
    fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
651
0
        if self.byte_aligned() {
652
0
            self.writer.write_all(buf)
653
        } else {
654
0
            buf.iter().try_for_each(|b| self.write(8, *b))
655
        }
656
0
    }
657
658
    /// # Example
659
    /// ```
660
    /// use std::io::{Write, sink};
661
    /// use bitstream_io::{BigEndian, BitWriter, BitWrite};
662
    /// let mut writer = BitWriter::endian(sink(), BigEndian);
663
    /// assert_eq!(writer.byte_aligned(), true);
664
    /// writer.write(1, 0).unwrap();
665
    /// assert_eq!(writer.byte_aligned(), false);
666
    /// writer.write(7, 0).unwrap();
667
    /// assert_eq!(writer.byte_aligned(), true);
668
    /// ```
669
    #[inline(always)]
670
0
    fn byte_aligned(&self) -> bool {
671
0
        self.bitqueue.is_empty()
672
0
    }
673
}
674
675
impl<W: io::Write, E: Endianness> HuffmanWrite<E> for BitWriter<W, E> {
676
    /// # Example
677
    /// ```
678
    /// use std::io::Write;
679
    /// use bitstream_io::{BigEndian, BitWriter, HuffmanWrite};
680
    /// use bitstream_io::huffman::compile_write_tree;
681
    /// let tree = compile_write_tree(
682
    ///     vec![('a', vec![0]),
683
    ///          ('b', vec![1, 0]),
684
    ///          ('c', vec![1, 1, 0]),
685
    ///          ('d', vec![1, 1, 1])]).unwrap();
686
    /// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
687
    /// writer.write_huffman(&tree, 'b').unwrap();
688
    /// writer.write_huffman(&tree, 'c').unwrap();
689
    /// writer.write_huffman(&tree, 'd').unwrap();
690
    /// assert_eq!(writer.into_writer(), [0b10110111]);
691
    /// ```
692
    #[inline]
693
0
    fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
694
0
    where
695
0
        T: Ord + Copy,
696
    {
697
0
        tree.get(&symbol)
698
0
            .try_for_each(|(bits, value)| self.write(*bits, *value))
699
0
    }
700
}
701
702
/// For counting the number of bits written but generating no output.
703
///
704
/// # Example
705
/// ```
706
/// use bitstream_io::{BigEndian, BitWrite, BitCounter};
707
/// let mut writer: BitCounter<u32, BigEndian> = BitCounter::new();
708
/// writer.write(1, 0b1).unwrap();
709
/// writer.write(2, 0b01).unwrap();
710
/// writer.write(5, 0b10111).unwrap();
711
/// assert_eq!(writer.written(), 8);
712
/// ```
713
#[derive(Default)]
714
pub struct BitCounter<N, E: Endianness> {
715
    bits: N,
716
    phantom: PhantomData<E>,
717
}
718
719
impl<N: Default + Copy, E: Endianness> BitCounter<N, E> {
720
    /// Creates new counter
721
    #[inline]
722
0
    pub fn new() -> Self {
723
0
        BitCounter {
724
0
            bits: N::default(),
725
0
            phantom: PhantomData,
726
0
        }
727
0
    }
728
729
    /// Returns number of bits written
730
    #[inline]
731
0
    pub fn written(&self) -> N {
732
0
        self.bits
733
0
    }
734
}
735
736
impl<N, E> BitWrite for BitCounter<N, E>
737
where
738
    E: Endianness,
739
    N: Copy + AddAssign + From<u32> + Rem<Output = N> + PartialEq,
740
{
741
    #[inline]
742
0
    fn write_bit(&mut self, _bit: bool) -> io::Result<()> {
743
0
        self.bits += 1.into();
744
0
        Ok(())
745
0
    }
746
747
    #[inline]
748
0
    fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
749
0
    where
750
0
        U: Numeric,
751
    {
752
0
        if bits > U::BITS_SIZE {
753
0
            Err(io::Error::new(
754
0
                io::ErrorKind::InvalidInput,
755
0
                "excessive bits for type written",
756
0
            ))
757
0
        } else if (bits < U::BITS_SIZE) && (value >= (U::ONE << bits)) {
758
0
            Err(io::Error::new(
759
0
                io::ErrorKind::InvalidInput,
760
0
                "excessive value for bits written",
761
0
            ))
762
        } else {
763
0
            self.bits += bits.into();
764
0
            Ok(())
765
        }
766
0
    }
767
768
    #[inline]
769
0
    fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
770
0
    where
771
0
        S: SignedNumeric,
772
    {
773
0
        E::write_signed(self, bits, value)
774
0
    }
775
776
    #[inline]
777
0
    fn write_from<V>(&mut self, value: V) -> io::Result<()>
778
0
    where
779
0
        V: Primitive,
780
    {
781
0
        E::write_primitive(self, value)
782
0
    }
783
784
    #[inline]
785
0
    fn write_unary1(&mut self, value: u32) -> io::Result<()> {
786
0
        self.bits += (value + 1).into();
787
0
        Ok(())
788
0
    }
789
790
    #[inline]
791
0
    fn write_unary0(&mut self, value: u32) -> io::Result<()> {
792
0
        self.bits += (value + 1).into();
793
0
        Ok(())
794
0
    }
795
796
    #[inline]
797
0
    fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
798
0
        self.bits += (buf.len() as u32 * 8).into();
799
0
        Ok(())
800
0
    }
801
802
    #[inline]
803
0
    fn byte_aligned(&self) -> bool {
804
0
        self.bits % 8.into() == 0.into()
805
0
    }
806
}
807
808
impl<N, E> HuffmanWrite<E> for BitCounter<N, E>
809
where
810
    E: Endianness,
811
    N: AddAssign + From<u32>,
812
{
813
0
    fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
814
0
    where
815
0
        T: Ord + Copy,
816
    {
817
0
        for &(bits, _) in tree.get(&symbol) {
818
0
            let bits: N = bits.into();
819
0
            self.bits += bits;
820
0
        }
821
0
        Ok(())
822
0
    }
823
}
824
825
/// A generic unsigned value for stream recording purposes
826
pub struct UnsignedValue(InnerUnsignedValue);
827
828
enum InnerUnsignedValue {
829
    U8(u8),
830
    U16(u16),
831
    U32(u32),
832
    U64(u64),
833
    U128(u128),
834
    I8(i8),
835
    I16(i16),
836
    I32(i32),
837
    I64(i64),
838
    I128(i128),
839
}
840
841
macro_rules! define_unsigned_value {
842
    ($t:ty, $n:ident) => {
843
        impl From<$t> for UnsignedValue {
844
            #[inline]
845
0
            fn from(v: $t) -> Self {
846
0
                UnsignedValue(InnerUnsignedValue::$n(v))
847
0
            }
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<u8>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<u16>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<u32>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<u64>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<u128>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<i8>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<i16>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<i32>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<i64>>::from
Unexecuted instantiation: <bitstream_io::write::UnsignedValue as core::convert::From<i128>>::from
848
        }
849
    };
850
}
851
define_unsigned_value!(u8, U8);
852
define_unsigned_value!(u16, U16);
853
define_unsigned_value!(u32, U32);
854
define_unsigned_value!(u64, U64);
855
define_unsigned_value!(u128, U128);
856
define_unsigned_value!(i8, I8);
857
define_unsigned_value!(i16, I16);
858
define_unsigned_value!(i32, I32);
859
define_unsigned_value!(i64, I64);
860
define_unsigned_value!(i128, I128);
861
862
/// A generic signed value for stream recording purposes
863
pub struct SignedValue(InnerSignedValue);
864
865
enum InnerSignedValue {
866
    I8(i8),
867
    I16(i16),
868
    I32(i32),
869
    I64(i64),
870
    I128(i128),
871
}
872
873
macro_rules! define_signed_value {
874
    ($t:ty, $n:ident) => {
875
        impl From<$t> for SignedValue {
876
            #[inline]
877
0
            fn from(v: $t) -> Self {
878
0
                SignedValue(InnerSignedValue::$n(v))
879
0
            }
Unexecuted instantiation: <bitstream_io::write::SignedValue as core::convert::From<i8>>::from
Unexecuted instantiation: <bitstream_io::write::SignedValue as core::convert::From<i16>>::from
Unexecuted instantiation: <bitstream_io::write::SignedValue as core::convert::From<i32>>::from
Unexecuted instantiation: <bitstream_io::write::SignedValue as core::convert::From<i64>>::from
Unexecuted instantiation: <bitstream_io::write::SignedValue as core::convert::From<i128>>::from
880
        }
881
    };
882
}
883
define_signed_value!(i8, I8);
884
define_signed_value!(i16, I16);
885
define_signed_value!(i32, I32);
886
define_signed_value!(i64, I64);
887
define_signed_value!(i128, I128);
888
889
enum WriteRecord {
890
    Bit(bool),
891
    Unsigned { bits: u32, value: UnsignedValue },
892
    Signed { bits: u32, value: SignedValue },
893
    Unary0(u32),
894
    Unary1(u32),
895
    Bytes(Box<[u8]>),
896
}
897
898
impl WriteRecord {
899
0
    fn playback<W: BitWrite>(&self, writer: &mut W) -> io::Result<()> {
900
0
        match self {
901
0
            WriteRecord::Bit(v) => writer.write_bit(*v),
902
            WriteRecord::Unsigned {
903
0
                bits,
904
0
                value: UnsignedValue(value),
905
0
            } => match value {
906
0
                InnerUnsignedValue::U8(v) => writer.write(*bits, *v),
907
0
                InnerUnsignedValue::U16(v) => writer.write(*bits, *v),
908
0
                InnerUnsignedValue::U32(v) => writer.write(*bits, *v),
909
0
                InnerUnsignedValue::U64(v) => writer.write(*bits, *v),
910
0
                InnerUnsignedValue::U128(v) => writer.write(*bits, *v),
911
0
                InnerUnsignedValue::I8(v) => writer.write(*bits, *v),
912
0
                InnerUnsignedValue::I16(v) => writer.write(*bits, *v),
913
0
                InnerUnsignedValue::I32(v) => writer.write(*bits, *v),
914
0
                InnerUnsignedValue::I64(v) => writer.write(*bits, *v),
915
0
                InnerUnsignedValue::I128(v) => writer.write(*bits, *v),
916
            },
917
            WriteRecord::Signed {
918
0
                bits,
919
0
                value: SignedValue(value),
920
0
            } => match value {
921
0
                InnerSignedValue::I8(v) => writer.write_signed(*bits, *v),
922
0
                InnerSignedValue::I16(v) => writer.write_signed(*bits, *v),
923
0
                InnerSignedValue::I32(v) => writer.write_signed(*bits, *v),
924
0
                InnerSignedValue::I64(v) => writer.write_signed(*bits, *v),
925
0
                InnerSignedValue::I128(v) => writer.write_signed(*bits, *v),
926
            },
927
0
            WriteRecord::Unary0(v) => writer.write_unary0(*v),
928
0
            WriteRecord::Unary1(v) => writer.write_unary1(*v),
929
0
            WriteRecord::Bytes(bytes) => writer.write_bytes(bytes),
930
        }
931
0
    }
932
}
933
934
/// For recording writes in order to play them back on another writer
935
/// # Example
936
/// ```
937
/// use std::io::Write;
938
/// use bitstream_io::{BigEndian, BitWriter, BitWrite, BitRecorder};
939
/// let mut recorder: BitRecorder<u32, BigEndian> = BitRecorder::new();
940
/// recorder.write(1, 0b1).unwrap();
941
/// recorder.write(2, 0b01).unwrap();
942
/// recorder.write(5, 0b10111).unwrap();
943
/// assert_eq!(recorder.written(), 8);
944
/// let mut writer = BitWriter::endian(Vec::new(), BigEndian);
945
/// recorder.playback(&mut writer);
946
/// assert_eq!(writer.into_writer(), [0b10110111]);
947
/// ```
948
#[derive(Default)]
949
pub struct BitRecorder<N, E: Endianness> {
950
    counter: BitCounter<N, E>,
951
    records: Vec<WriteRecord>,
952
}
953
954
impl<N: Default + Copy, E: Endianness> BitRecorder<N, E> {
955
    /// Creates new recorder
956
    #[inline]
957
0
    pub fn new() -> Self {
958
0
        BitRecorder {
959
0
            counter: BitCounter::new(),
960
0
            records: Vec::new(),
961
0
        }
962
0
    }
963
964
    /// Creates new recorder sized for the given number of writes
965
    #[inline]
966
0
    pub fn with_capacity(writes: usize) -> Self {
967
0
        BitRecorder {
968
0
            counter: BitCounter::new(),
969
0
            records: Vec::with_capacity(writes),
970
0
        }
971
0
    }
972
973
    /// Creates new recorder with the given endianness
974
    #[inline]
975
0
    pub fn endian(_endian: E) -> Self {
976
0
        BitRecorder {
977
0
            counter: BitCounter::new(),
978
0
            records: Vec::new(),
979
0
        }
980
0
    }
981
982
    /// Returns number of bits written
983
    #[inline]
984
0
    pub fn written(&self) -> N {
985
0
        self.counter.written()
986
0
    }
987
988
    /// Plays recorded writes to the given writer
989
    #[inline]
990
0
    pub fn playback<W: BitWrite>(&self, writer: &mut W) -> io::Result<()> {
991
0
        self.records
992
0
            .iter()
993
0
            .try_for_each(|record| record.playback(writer))
994
0
    }
995
}
996
997
impl<N, E> BitWrite for BitRecorder<N, E>
998
where
999
    E: Endianness,
1000
    N: Copy + From<u32> + AddAssign + Rem<Output = N> + Eq,
1001
{
1002
    #[inline]
1003
0
    fn write_bit(&mut self, bit: bool) -> io::Result<()> {
1004
0
        self.records.push(WriteRecord::Bit(bit));
1005
0
        self.counter.write_bit(bit)
1006
0
    }
1007
1008
    #[inline]
1009
0
    fn write<U>(&mut self, bits: u32, value: U) -> io::Result<()>
1010
0
    where
1011
0
        U: Numeric,
1012
    {
1013
0
        self.counter.write(bits, value)?;
1014
0
        self.records.push(WriteRecord::Unsigned {
1015
0
            bits,
1016
0
            value: value.unsigned_value(),
1017
0
        });
1018
0
        Ok(())
1019
0
    }
1020
1021
    #[inline]
1022
0
    fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()>
1023
0
    where
1024
0
        S: SignedNumeric,
1025
    {
1026
0
        self.counter.write_signed(bits, value)?;
1027
0
        self.records.push(WriteRecord::Signed {
1028
0
            bits,
1029
0
            value: value.signed_value(),
1030
0
        });
1031
0
        Ok(())
1032
0
    }
1033
1034
    #[inline]
1035
0
    fn write_from<V>(&mut self, value: V) -> io::Result<()>
1036
0
    where
1037
0
        V: Primitive,
1038
    {
1039
0
        E::write_primitive(self, value)
1040
0
    }
1041
1042
    #[inline]
1043
0
    fn write_unary0(&mut self, value: u32) -> io::Result<()> {
1044
0
        self.records.push(WriteRecord::Unary0(value));
1045
0
        self.counter.write_unary0(value)
1046
0
    }
1047
1048
    #[inline]
1049
0
    fn write_unary1(&mut self, value: u32) -> io::Result<()> {
1050
0
        self.records.push(WriteRecord::Unary1(value));
1051
0
        self.counter.write_unary1(value)
1052
0
    }
1053
1054
    #[inline]
1055
0
    fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
1056
0
        self.records.push(WriteRecord::Bytes(buf.into()));
1057
0
        self.counter.write_bytes(buf)
1058
0
    }
1059
1060
    #[inline]
1061
0
    fn byte_aligned(&self) -> bool {
1062
0
        self.counter.byte_aligned()
1063
0
    }
1064
}
1065
1066
impl<N, E> HuffmanWrite<E> for BitRecorder<N, E>
1067
where
1068
    E: Endianness,
1069
    N: Copy + From<u32> + AddAssign + Rem<Output = N> + Eq,
1070
{
1071
    #[inline]
1072
0
    fn write_huffman<T>(&mut self, tree: &WriteHuffmanTree<E, T>, symbol: T) -> io::Result<()>
1073
0
    where
1074
0
        T: Ord + Copy,
1075
    {
1076
0
        tree.get(&symbol)
1077
0
            .try_for_each(|(bits, value)| self.write(*bits, *value))
1078
0
    }
1079
}
1080
1081
#[inline]
1082
0
fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
1083
0
where
1084
0
    W: io::Write,
1085
{
1086
0
    writer.write_all(std::slice::from_ref(&byte))
1087
0
}
1088
1089
0
fn write_unaligned<W, E, N>(
1090
0
    writer: W,
1091
0
    acc: &mut BitQueue<E, N>,
1092
0
    rem: &mut BitQueue<E, u8>,
1093
0
) -> io::Result<()>
1094
0
where
1095
0
    W: io::Write,
1096
0
    E: Endianness,
1097
0
    N: Numeric,
1098
{
1099
0
    if rem.is_empty() {
1100
0
        Ok(())
1101
    } else {
1102
        use std::cmp::min;
1103
0
        let bits_to_transfer = min(8 - rem.len(), acc.len());
1104
0
        rem.push(bits_to_transfer, acc.pop(bits_to_transfer).to_u8());
1105
0
        if rem.len() == 8 {
1106
0
            write_byte(writer, rem.pop(8))
1107
        } else {
1108
0
            Ok(())
1109
        }
1110
    }
1111
0
}
1112
1113
0
fn write_aligned<W, E, N>(mut writer: W, acc: &mut BitQueue<E, N>) -> io::Result<()>
1114
0
where
1115
0
    W: io::Write,
1116
0
    E: Endianness,
1117
0
    N: Numeric,
1118
{
1119
0
    let to_write = (acc.len() / 8) as usize;
1120
0
    if to_write > 0 {
1121
0
        let mut buf = N::buffer();
1122
0
        let buf_ref: &mut [u8] = buf.as_mut();
1123
0
        for b in buf_ref[0..to_write].iter_mut() {
1124
0
            *b = acc.pop(8).to_u8();
1125
0
        }
1126
0
        writer.write_all(&buf_ref[0..to_write])
1127
    } else {
1128
0
        Ok(())
1129
    }
1130
0
}
1131
1132
/// For writing aligned bytes to a stream of bytes in a given endianness.
1133
///
1134
/// This only writes aligned values and maintains no internal state.
1135
pub struct ByteWriter<W: io::Write, E: Endianness> {
1136
    phantom: PhantomData<E>,
1137
    writer: W,
1138
}
1139
1140
impl<W: io::Write, E: Endianness> ByteWriter<W, E> {
1141
    /// Wraps a ByteWriter around something that implements `Write`
1142
0
    pub fn new(writer: W) -> ByteWriter<W, E> {
1143
0
        ByteWriter {
1144
0
            phantom: PhantomData,
1145
0
            writer,
1146
0
        }
1147
0
    }
1148
1149
    /// Wraps a BitWriter around something that implements `Write`
1150
    /// with the given endianness.
1151
0
    pub fn endian(writer: W, _endian: E) -> ByteWriter<W, E> {
1152
0
        ByteWriter {
1153
0
            phantom: PhantomData,
1154
0
            writer,
1155
0
        }
1156
0
    }
1157
1158
    /// Unwraps internal writer and disposes of `ByteWriter`.
1159
    /// Any unwritten partial bits are discarded.
1160
    #[inline]
1161
0
    pub fn into_writer(self) -> W {
1162
0
        self.writer
1163
0
    }
1164
1165
    /// Provides mutable reference to internal writer.
1166
    #[inline]
1167
0
    pub fn writer(&mut self) -> &mut W {
1168
0
        &mut self.writer
1169
0
    }
1170
1171
    /// Converts `ByteWriter` to `BitWriter` in the same endianness.
1172
    #[inline]
1173
0
    pub fn into_bitwriter(self) -> BitWriter<W, E> {
1174
0
        BitWriter::new(self.into_writer())
1175
0
    }
1176
1177
    /// Provides temporary `BitWriter` in the same endianness.
1178
    ///
1179
    /// # Warning
1180
    ///
1181
    /// Any unwritten bits left over when `BitWriter` is dropped are lost.
1182
    #[inline]
1183
0
    pub fn bitwriter(&mut self) -> BitWriter<&mut W, E> {
1184
0
        BitWriter::new(self.writer())
1185
0
    }
1186
}
1187
1188
/// A trait for anything that can write aligned values to an output stream
1189
pub trait ByteWrite {
1190
    /// Writes whole numeric value to stream
1191
    ///
1192
    /// # Errors
1193
    ///
1194
    /// Passes along any I/O error from the underlying stream.
1195
    /// # Examples
1196
    /// ```
1197
    /// use std::io::Write;
1198
    /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite};
1199
    /// let mut writer = ByteWriter::endian(Vec::new(), BigEndian);
1200
    /// writer.write(0b0000000011111111u16).unwrap();
1201
    /// assert_eq!(writer.into_writer(), [0b00000000, 0b11111111]);
1202
    /// ```
1203
    ///
1204
    /// ```
1205
    /// use std::io::Write;
1206
    /// use bitstream_io::{LittleEndian, ByteWriter, ByteWrite};
1207
    /// let mut writer = ByteWriter::endian(Vec::new(), LittleEndian);
1208
    /// writer.write(0b0000000011111111u16).unwrap();
1209
    /// assert_eq!(writer.into_writer(), [0b11111111, 0b00000000]);
1210
    /// ```
1211
    fn write<N: Numeric>(&mut self, value: N) -> io::Result<()>;
1212
1213
    /// Writes the entirety of a byte buffer to the stream.
1214
    ///
1215
    /// # Errors
1216
    ///
1217
    /// Passes along any I/O error from the underlying stream.
1218
    fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()>;
1219
1220
    /// Builds and writes complex type
1221
0
    fn build<T: ToByteStream>(&mut self, build: &T) -> Result<(), T::Error> {
1222
0
        build.to_writer(self)
1223
0
    }
1224
1225
    /// Builds and writes complex type with context
1226
0
    fn build_with<T: ToByteStreamWith>(
1227
0
        &mut self,
1228
0
        build: &T,
1229
0
        context: &T::Context,
1230
0
    ) -> Result<(), T::Error> {
1231
0
        build.to_writer(self, context)
1232
0
    }
1233
1234
    /// Returns mutable reference to underlying writer
1235
    fn writer_ref(&mut self) -> &mut dyn io::Write;
1236
}
1237
1238
impl<W: io::Write, E: Endianness> ByteWrite for ByteWriter<W, E> {
1239
    #[inline]
1240
0
    fn write<N: Numeric>(&mut self, value: N) -> io::Result<()> {
1241
0
        E::write_numeric(&mut self.writer, value)
1242
0
    }
1243
1244
    #[inline]
1245
0
    fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> {
1246
0
        self.writer.write_all(buf)
1247
0
    }
1248
1249
    #[inline]
1250
0
    fn writer_ref(&mut self) -> &mut dyn io::Write {
1251
0
        &mut self.writer
1252
0
    }
1253
}
1254
1255
/// Implemented by complex types that don't require any additional context
1256
/// to build themselves to a writer
1257
///
1258
/// # Example
1259
/// ```
1260
/// use std::io::{Cursor, Read};
1261
/// use bitstream_io::{BigEndian, BitWrite, BitWriter, ToBitStream};
1262
///
1263
/// #[derive(Debug, PartialEq, Eq)]
1264
/// struct BlockHeader {
1265
///     last_block: bool,
1266
///     block_type: u8,
1267
///     block_size: u32,
1268
/// }
1269
///
1270
/// impl ToBitStream for BlockHeader {
1271
///     type Error = std::io::Error;
1272
///
1273
///     fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> {
1274
///         w.write_bit(self.last_block)?;
1275
///         w.write(7, self.block_type)?;
1276
///         w.write(24, self.block_size)
1277
///     }
1278
/// }
1279
///
1280
/// let mut data = Vec::new();
1281
/// let mut writer = BitWriter::endian(&mut data, BigEndian);
1282
/// writer.build(&BlockHeader { last_block: false, block_type: 4, block_size: 122 }).unwrap();
1283
/// assert_eq!(data, b"\x04\x00\x00\x7A");
1284
/// ```
1285
pub trait ToBitStream {
1286
    /// Error generated during building, such as `io::Error`
1287
    type Error;
1288
1289
    /// Generate self to writer
1290
    fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> Result<(), Self::Error>
1291
    where
1292
        Self: Sized;
1293
}
1294
1295
/// Implemented by complex types that require additional context
1296
/// to build themselves to a writer
1297
pub trait ToBitStreamWith {
1298
    /// Some context to use when writing
1299
    type Context;
1300
1301
    /// Error generated during building, such as `io::Error`
1302
    type Error;
1303
1304
    /// Generate self to writer
1305
    fn to_writer<W: BitWrite + ?Sized>(
1306
        &self,
1307
        w: &mut W,
1308
        context: &Self::Context,
1309
    ) -> Result<(), Self::Error>
1310
    where
1311
        Self: Sized;
1312
}
1313
1314
/// Implemented by complex types that don't require any additional context
1315
/// to build themselves to a writer
1316
pub trait ToByteStream {
1317
    /// Error generated during building, such as `io::Error`
1318
    type Error;
1319
1320
    /// Generate self to writer
1321
    fn to_writer<W: ByteWrite + ?Sized>(&self, w: &mut W) -> Result<(), Self::Error>
1322
    where
1323
        Self: Sized;
1324
}
1325
1326
/// Implemented by complex types that require additional context
1327
/// to build themselves to a writer
1328
pub trait ToByteStreamWith {
1329
    /// Some context to use when writing
1330
    type Context;
1331
1332
    /// Error generated during building, such as `io::Error`
1333
    type Error;
1334
1335
    /// Generate self to writer
1336
    fn to_writer<W: ByteWrite + ?Sized>(
1337
        &self,
1338
        w: &mut W,
1339
        context: &Self::Context,
1340
    ) -> Result<(), Self::Error>
1341
    where
1342
        Self: Sized;
1343
}