/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 | | } |