core/io: add the finish() and new_read_boxed() to FileReader
[nihav.git] / nihav-core / src / io / byteio.rs
1 //! Bytestream reading/writing functionality.
2 pub use std::io::SeekFrom;
3 use std::io::prelude::*;
4 use std::ptr;
5
6 /// A list specifying general bytestream reading and writing errors.
7 #[derive(Debug)]
8 pub enum ByteIOError {
9 /// End of stream.
10 EOF,
11 /// Wrong seek position was provided.
12 WrongRange,
13 /// Tried to call read() on bytestream writer or write() on bytestream reader.
14 WrongIOMode,
15 /// Functionality is not implemented.
16 NotImplemented,
17 /// Read error.
18 ReadError,
19 /// Write error.
20 WriteError,
21 /// Seeking failed.
22 SeekError,
23 }
24
25 /// A specialised `Result` type for bytestream operations.
26 pub type ByteIOResult<T> = Result<T, ByteIOError>;
27
28 /// Common trait for bytestream operations.
29 pub trait ByteIO {
30 /// Reads data into provided buffer. Fails if it cannot fill whole buffer.
31 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
32 /// Reads data into provided buffer. Partial read is treated as success.
33 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
34 /// Reads data into provided buffer but does not advance read position.
35 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize>;
36 /// Reads single byte from the stream.
37 fn read_byte(&mut self) -> ByteIOResult<u8>;
38 /// Returns the next byte value in the stream without advancing read position.
39 fn peek_byte(&mut self) -> ByteIOResult<u8>;
40 /// Writes buffer to the stream.
41 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()>;
42 /// Returns current read or write position.
43 fn tell(&mut self) -> u64;
44 /// Seeks to the provided position.
45 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64>;
46 /// Tells whether this is end of stream.
47 fn is_eof(&self) -> bool;
48 /// Reports whether stream is seekable or not.
49 fn is_seekable(&mut self) -> bool;
50 /// Returns stream size or -1 if it is not known.
51 fn size(&mut self) -> i64;
52 /// Flushes output if possible.
53 fn flush(&mut self) -> ByteIOResult<()>;
54 }
55
56 /// High-level bytestream reader.
57 ///
58 /// User is supposed to create some reader implementing [`ByteIO`] trait e.g. [`MemoryReader`] and use it to create `ByteReader` which can be used for reading e.g. various integer types.
59 ///
60 /// # Examples
61 ///
62 /// ````
63 /// use nihav_core::io::byteio::{MemoryReader,ByteReader};
64 /// # use nihav_core::io::byteio::ByteIOResult;
65 ///
66 /// # fn foo() -> ByteIOResult<()> {
67 /// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
68 /// let mut mr = MemoryReader::new_read(&memory);
69 /// let mut br = ByteReader::new(&mut mr);
70 /// let val = br.read_u16be()?; // read 16-bit big-endian integer, should be 42
71 /// let val = br.read_u16le()?; // read 16-bit little-endian integer, should be 42 as well
72 /// # Ok(())
73 /// # }
74 /// ````
75 ///
76 /// [`ByteIO`]: ./trait.ByteIO.html
77 /// [`MemoryReader`]: ./struct.MemoryReader.html
78 #[allow(dead_code)]
79 pub struct ByteReader<'a> {
80 io: &'a mut dyn ByteIO,
81 }
82
83 /// Bytestream reader from memory.
84 pub struct MemoryReader<'a> {
85 buf: &'a [u8],
86 pos: usize,
87 }
88
89 /// Bytestream reader from anything implementing `std::io::Read` and `std::io::Seek`.
90 pub struct FileReader<T: Read+Seek> {
91 file: Box<T>,
92 eof: bool,
93 }
94
95 /// Bytestream reader from anything implementing `std::io::Read` and `std::io::Seek` that operates only on a part of the input.
96 pub struct BoundedFileReader<T: Read+Seek> {
97 file: Box<T>,
98 start: u64,
99 end: Option<u64>,
100 eof: bool,
101 }
102
103 macro_rules! read_int {
104 ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
105 unsafe {
106 let mut buf: $inttype = 0;
107 $s.read_buf(&mut *(&mut buf as *mut $inttype as *mut [u8; $size]))?;
108 Ok(buf.$which())
109 }
110 })
111 }
112
113 macro_rules! peek_int {
114 ($s: ident, $inttype: ty, $size: expr, $which: ident) => ({
115 unsafe {
116 let mut buf: $inttype = 0;
117 $s.peek_buf(&mut *(&mut buf as *mut $inttype as *mut [u8; $size]))?;
118 Ok(buf.$which())
119 }
120 })
121 }
122
123 macro_rules! read_int_func {
124 ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
125 /// Reads integer of certain size and endianness.
126 pub fn $s(src: &[u8]) -> ByteIOResult<$inttype> {
127 if src.len() < $size { return Err(ByteIOError::ReadError); }
128 unsafe {
129 let mut buf: $inttype = 0;
130 ptr::copy_nonoverlapping(src.as_ptr(), &mut buf as *mut $inttype as *mut u8, std::mem::size_of::<$inttype>());
131 Ok(buf.$which())
132 }
133 }
134 }
135 }
136
137 read_int_func!(read_u16be, u16, 2, to_be);
138 read_int_func!(read_u16le, u16, 2, to_le);
139 read_int_func!(read_u32be, u32, 4, to_be);
140 read_int_func!(read_u32le, u32, 4, to_le);
141 read_int_func!(read_u64be, u64, 8, to_be);
142 read_int_func!(read_u64le, u64, 8, to_le);
143
144 /// Reads 24-bit big-endian integer.
145 ///
146 /// # Example
147 ///
148 /// ````
149 /// use nihav_core::io::byteio::read_u24be;
150 /// # use nihav_core::io::byteio::ByteIOResult;
151 ///
152 /// # fn foo() -> ByteIOResult<()> {
153 /// let src: [u8; 3] = [ 1, 2, 3];
154 /// let value = read_u24be(&src)?; // should return 0x010203
155 /// # Ok(())
156 /// # }
157 /// ````
158 pub fn read_u24be(src: &[u8]) -> ByteIOResult<u32> {
159 if src.len() < 3 { return Err(ByteIOError::ReadError); }
160 Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
161 }
162 /// Reads 24-bit little-endian integer.
163 pub fn read_u24le(src: &[u8]) -> ByteIOResult<u32> {
164 if src.len() < 3 { return Err(ByteIOError::ReadError); }
165 Ok((u32::from(src[2]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[0]))
166 }
167 /// Reads 32-bit big-endian floating point number.
168 pub fn read_f32be(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32be(src)?)) }
169 /// Reads 32-bit little-endian floating point number.
170 pub fn read_f32le(src: &[u8]) -> ByteIOResult<f32> { Ok(f32::from_bits(read_u32le(src)?)) }
171 /// Reads 64-bit big-endian floating point number.
172 pub fn read_f64be(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64be(src)?)) }
173 /// Reads 64-bit little-endian floating point number.
174 pub fn read_f64le(src: &[u8]) -> ByteIOResult<f64> { Ok(f64::from_bits(read_u64le(src)?)) }
175
176 macro_rules! write_int_func {
177 ($s: ident, $inttype: ty, $size: expr, $which: ident) => {
178 /// Writes integer of certain size and endianness into byte buffer.
179 pub fn $s(dst: &mut [u8], val: $inttype) -> ByteIOResult<()> {
180 if dst.len() < $size { return Err(ByteIOError::WriteError); }
181 unsafe {
182 let val = val.$which();
183 ptr::copy_nonoverlapping(&val as *const $inttype as *const u8, dst.as_mut_ptr(), std::mem::size_of::<$inttype>());
184 }
185 Ok(())
186 }
187 }
188 }
189
190 write_int_func!(write_u16be, u16, 2, to_be);
191 write_int_func!(write_u16le, u16, 2, to_le);
192 write_int_func!(write_u32be, u32, 4, to_be);
193 write_int_func!(write_u32le, u32, 4, to_le);
194 write_int_func!(write_u64be, u64, 8, to_be);
195 write_int_func!(write_u64le, u64, 8, to_le);
196
197 /// Writes 24-bit big-endian integer to the provided buffer.
198 ///
199 /// # Example
200 ///
201 /// ````
202 /// use nihav_core::io::byteio::write_u24be;
203 /// # use nihav_core::io::byteio::ByteIOResult;
204 ///
205 /// # fn foo() -> ByteIOResult<()> {
206 /// let mut dst = [0u8; 3];
207 /// write_u24be(&mut dst, 0x010203)?;
208 /// // dst should contain [ 1, 2, 3] now
209 /// # Ok(())
210 /// # }
211 /// ````
212 #[allow(clippy::identity_op)]
213 pub fn write_u24be(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
214 if dst.len() < 3 { return Err(ByteIOError::WriteError); }
215 dst[0] = (val >> 16) as u8;
216 dst[1] = (val >> 8) as u8;
217 dst[2] = (val >> 0) as u8;
218 Ok(())
219 }
220 /// Writes 24-bit little-endian integer to the provided buffer.
221 #[allow(clippy::identity_op)]
222 pub fn write_u24le(dst: &mut [u8], val: u32) -> ByteIOResult<()> {
223 if dst.len() < 3 { return Err(ByteIOError::WriteError); }
224 dst[0] = (val >> 0) as u8;
225 dst[1] = (val >> 8) as u8;
226 dst[2] = (val >> 16) as u8;
227 Ok(())
228 }
229 /// Writes 32-bit big-endian floating point number to the provided buffer.
230 pub fn write_f32be(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32be(dst, val.to_bits()) }
231 /// Writes 32-bit little-endian floating point number to the provided buffer.
232 pub fn write_f32le(dst: &mut [u8], val: f32) -> ByteIOResult<()> { write_u32le(dst, val.to_bits()) }
233 /// Writes 64-bit big-endian floating point number to the provided buffer.
234 pub fn write_f64be(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64be(dst, val.to_bits()) }
235 /// Writes 64-bit little-endian floating point number to the provided buffer.
236 pub fn write_f64le(dst: &mut [u8], val: f64) -> ByteIOResult<()> { write_u64le(dst, val.to_bits()) }
237
238 impl<'a> ByteReader<'a> {
239 /// Constructs a new instance of bytestream reader.
240 ///
241 /// # Examples
242 ///
243 /// ````
244 /// use nihav_core::io::byteio::{MemoryReader,ByteReader};
245 /// # use nihav_core::io::byteio::ByteIOResult;
246 ///
247 /// # fn foo() -> ByteIOResult<()> {
248 /// let memory: [u8; 4] = [ 0, 42, 42, 0 ];
249 /// let mut mr = MemoryReader::new_read(&memory);
250 /// let mut br = ByteReader::new(&mut mr);
251 /// # Ok(())
252 /// # }
253 /// ````
254 pub fn new(io: &'a mut dyn ByteIO) -> Self { ByteReader { io } }
255
256 /// Reads data into provided buffer. Partial read is treated as success.
257 pub fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
258 self.io.read_buf(buf)
259 }
260
261 /// Reads data into provided buffer. Partial read is treated as success.
262 pub fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
263 self.io.read_buf_some(buf)
264 }
265
266 /// Reads data into provided buffer but does not advance read position.
267 pub fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
268 self.io.peek_buf(buf)
269 }
270
271 /// Reads single byte from the stream.
272 pub fn read_byte(&mut self) -> ByteIOResult<u8> {
273 self.io.read_byte()
274 }
275
276 /// Returns the next byte value in the stream without advancing read position.
277 pub fn peek_byte(&mut self) -> ByteIOResult<u8> {
278 self.io.peek_byte()
279 }
280
281 /// Reads four-byte array from the stream.
282 pub fn read_tag(&mut self) -> ByteIOResult<[u8; 4]> {
283 let mut buf = [0u8; 4];
284 self.io.read_buf(&mut buf)?;
285 Ok(buf)
286 }
287
288 /// Reads four-byte array from the stream without advancing read position.
289 pub fn peek_tag(&mut self) -> ByteIOResult<[u8; 4]> {
290 let mut buf = [0u8; 4];
291 self.io.peek_buf(&mut buf)?;
292 Ok(buf)
293 }
294
295 /// Reads 16-bit big-endian integer from the stream.
296 pub fn read_u16be(&mut self) -> ByteIOResult<u16> {
297 read_int!(self, u16, 2, to_be)
298 }
299
300 /// Reads 16-bit big-endian integer from the stream without advancing read position.
301 pub fn peek_u16be(&mut self) -> ByteIOResult<u16> {
302 peek_int!(self, u16, 2, to_be)
303 }
304
305 /// Reads 24-bit big-endian integer from the stream.
306 pub fn read_u24be(&mut self) -> ByteIOResult<u32> {
307 let p16 = self.read_u16be()?;
308 let p8 = self.read_byte()?;
309 Ok((u32::from(p16) << 8) | u32::from(p8))
310 }
311
312 /// Reads 24-bit big-endian integer from the stream without advancing read position.
313 pub fn peek_u24be(&mut self) -> ByteIOResult<u32> {
314 let mut src: [u8; 3] = [0; 3];
315 self.peek_buf(&mut src)?;
316 Ok((u32::from(src[0]) << 16) | (u32::from(src[1]) << 8) | u32::from(src[2]))
317 }
318
319 /// Reads 32-bit big-endian integer from the stream.
320 pub fn read_u32be(&mut self) -> ByteIOResult<u32> {
321 read_int!(self, u32, 4, to_be)
322 }
323
324 /// Reads 32-bit big-endian integer from the stream without advancing read position.
325 pub fn peek_u32be(&mut self) -> ByteIOResult<u32> {
326 peek_int!(self, u32, 4, to_be)
327 }
328
329 /// Reads 64-bit big-endian integer from the stream.
330 pub fn read_u64be(&mut self) -> ByteIOResult<u64> {
331 read_int!(self, u64, 8, to_be)
332 }
333
334 /// Reads 64-bit big-endian integer from the stream without advancing read position.
335 pub fn peek_u64be(&mut self) -> ByteIOResult<u64> {
336 peek_int!(self, u64, 8, to_be)
337 }
338
339 /// Reads 32-bit big-endian floating point number from the stream.
340 pub fn read_f32be(&mut self) -> ByteIOResult<f32> {
341 Ok(f32::from_bits(self.read_u32be()?))
342 }
343
344 /// Reads 32-bit big-endian floating point number from the stream without advancing read position.
345 pub fn peek_f32be(&mut self) -> ByteIOResult<f32> {
346 Ok(f32::from_bits(self.peek_u32be()?))
347 }
348
349 /// Reads 64-bit big-endian floating point number from the stream.
350 pub fn read_f64be(&mut self) -> ByteIOResult<f64> {
351 Ok(f64::from_bits(self.read_u64be()?))
352 }
353
354 /// Reads 64-bit big-endian floating point number from the stream without advancing read position.
355 pub fn peek_f64be(&mut self) -> ByteIOResult<f64> {
356 Ok(f64::from_bits(self.peek_u64be()?))
357 }
358
359 /// Reads 16-bit little-endian integer from the stream.
360 pub fn read_u16le(&mut self) -> ByteIOResult<u16> {
361 read_int!(self, u16, 2, to_le)
362 }
363
364 /// Reads 16-bit little-endian integer from the stream without advancing read position.
365 pub fn peek_u16le(&mut self) -> ByteIOResult<u16> {
366 peek_int!(self, u16, 2, to_le)
367 }
368
369 /// Reads 24-bit little-endian integer from the stream.
370 pub fn read_u24le(&mut self) -> ByteIOResult<u32> {
371 let p8 = self.read_byte()?;
372 let p16 = self.read_u16le()?;
373 Ok((u32::from(p16) << 8) | u32::from(p8))
374 }
375
376 /// Reads 24-bit little-endian integer from the stream without advancing read position.
377 pub fn peek_u24le(&mut self) -> ByteIOResult<u32> {
378 let mut src: [u8; 3] = [0; 3];
379 self.peek_buf(&mut src)?;
380 Ok(u32::from(src[0]) | (u32::from(src[1]) << 8) | (u32::from(src[2]) << 16))
381 }
382
383 /// Reads 32-bit little-endian integer from the stream.
384 pub fn read_u32le(&mut self) -> ByteIOResult<u32> {
385 read_int!(self, u32, 4, to_le)
386 }
387
388 /// Reads 32-bit little-endian integer from the stream without advancing read position.
389 pub fn peek_u32le(&mut self) -> ByteIOResult<u32> {
390 peek_int!(self, u32, 4, to_le)
391 }
392
393 /// Reads 64-bit little-endian integer from the stream.
394 pub fn read_u64le(&mut self) -> ByteIOResult<u64> {
395 read_int!(self, u64, 8, to_le)
396 }
397
398 /// Reads 64-bit little-endian integer from the stream without advancing read position.
399 pub fn peek_u64le(&mut self) -> ByteIOResult<u64> {
400 peek_int!(self, u64, 8, to_le)
401 }
402
403 /// Reads 32-bit little-endian floating point number from the stream.
404 pub fn read_f32le(&mut self) -> ByteIOResult<f32> {
405 Ok(f32::from_bits(self.read_u32le()?))
406 }
407
408 /// Reads 32-bit little-endian floating point number from the stream without advancing read position.
409 pub fn peek_f32le(&mut self) -> ByteIOResult<f32> {
410 Ok(f32::from_bits(self.peek_u32le()?))
411 }
412
413 /// Reads 64-bit little-endian floating point number from the stream.
414 pub fn read_f64le(&mut self) -> ByteIOResult<f64> {
415 Ok(f64::from_bits(self.read_u64le()?))
416 }
417
418 /// Reads 64-bit little-endian floating point number from the stream without advancing read position.
419 pub fn peek_f64le(&mut self) -> ByteIOResult<f64> {
420 Ok(f64::from_bits(self.peek_u64le()?))
421 }
422
423 /// Skips requested number of bytes.
424 pub fn read_skip(&mut self, len: usize) -> ByteIOResult<()> {
425 if self.io.is_seekable() {
426 self.io.seek(SeekFrom::Current(len as i64))?;
427 } else {
428 let mut ssize = len;
429 let mut buf : [u8; 16] = [0; 16];
430 let bref = &mut buf;
431 while ssize > bref.len() {
432 self.io.read_buf(bref)?;
433 ssize -= bref.len();
434 }
435 while ssize > 0 {
436 self.io.read_byte()?;
437 ssize -= 1;
438 }
439 }
440 Ok(())
441 }
442
443 /// Returns current read position.
444 pub fn tell(&mut self) -> u64 {
445 self.io.tell()
446 }
447
448 /// Seeks to the provided position.
449 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
450 self.io.seek(pos)
451 }
452
453 /// Tells whether this is end of stream.
454 pub fn is_eof(&self) -> bool {
455 self.io.is_eof()
456 }
457
458 /// Returns stream size or -1 if it is not known.
459 pub fn size(&mut self) -> i64 {
460 self.io.size()
461 }
462
463 /// Reports number of bytes left in the stream.
464 pub fn left(&mut self) -> i64 {
465 let size = self.io.size();
466 if size == -1 { return -1; }
467 size - (self.io.tell() as i64)
468 }
469 }
470
471 impl<'a> MemoryReader<'a> {
472 /// Constructs a new instance of `MemoryReader`.
473 pub fn new_read(buf: &'a [u8]) -> Self {
474 MemoryReader { buf, pos: 0 }
475 }
476
477 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
478 if pos < 0 || (pos as usize) > self.buf.len() {
479 return Err(ByteIOError::WrongRange);
480 }
481 self.pos = pos as usize;
482 Ok(pos as u64)
483 }
484 }
485
486 impl<'a> ByteIO for MemoryReader<'a> {
487 fn read_byte(&mut self) -> ByteIOResult<u8> {
488 if self.is_eof() { return Err(ByteIOError::EOF); }
489 let res = self.buf[self.pos];
490 self.pos += 1;
491 Ok(res)
492 }
493
494 fn peek_byte(&mut self) -> ByteIOResult<u8> {
495 if self.is_eof() { return Err(ByteIOError::EOF); }
496 Ok(self.buf[self.pos])
497 }
498
499 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
500 let copy_size = if self.buf.len() - self.pos < buf.len() { self.buf.len() - self.pos } else { buf.len() };
501 if copy_size == 0 { return Err(ByteIOError::EOF); }
502 let dst = &mut buf[0..copy_size];
503 dst.copy_from_slice(&self.buf[self.pos..][..copy_size]);
504 Ok(copy_size)
505 }
506
507 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
508 let read_size = self.peek_buf(buf)?;
509 if read_size < buf.len() { return Err(ByteIOError::EOF); }
510 self.pos += read_size;
511 Ok(read_size)
512 }
513
514 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
515 let read_size = self.peek_buf(buf)?;
516 self.pos += read_size;
517 Ok(read_size)
518 }
519
520 #[allow(unused_variables)]
521 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
522 Err(ByteIOError::NotImplemented)
523 }
524
525 fn tell(&mut self) -> u64 {
526 self.pos as u64
527 }
528
529 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
530 let cur_pos = self.pos as i64;
531 let cur_size = self.buf.len() as i64;
532 match pos {
533 SeekFrom::Start(x) => self.real_seek(x as i64),
534 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
535 SeekFrom::End(x) => self.real_seek(cur_size + x),
536 }
537 }
538
539 fn is_eof(&self) -> bool {
540 self.pos >= self.buf.len()
541 }
542
543 fn is_seekable(&mut self) -> bool {
544 true
545 }
546
547 fn size(&mut self) -> i64 {
548 self.buf.len() as i64
549 }
550
551 fn flush(&mut self) -> ByteIOResult<()> { Ok(()) }
552 }
553
554 impl<T: Read+Seek> FileReader<T> {
555
556 /// Constructs a new instance of `FileReader`.
557 pub fn new_read(file: T) -> Self {
558 FileReader { file: Box::new(file), eof : false }
559 }
560 /// Constructs a new instance of `FileReader` using a boxed resource.
561 pub fn new_read_boxed(file: Box<T>) -> Self {
562 FileReader { file, eof : false }
563 }
564 /// Destroys the reader and releases the reader resource for a further use.
565 pub fn finish(self) -> Box<T> { self.file }
566 }
567
568 impl<T: Read+Seek> ByteIO for FileReader<T> {
569 fn read_byte(&mut self) -> ByteIOResult<u8> {
570 let mut byte : [u8; 1] = [0];
571 let ret = self.file.read(&mut byte);
572 if ret.is_err() { return Err(ByteIOError::ReadError); }
573 let sz = ret.unwrap();
574 if sz == 0 { self.eof = true; return Err(ByteIOError::EOF); }
575 Ok (byte[0])
576 }
577
578 fn peek_byte(&mut self) -> ByteIOResult<u8> {
579 let b = self.read_byte()?;
580 self.seek(SeekFrom::Current(-1))?;
581 Ok(b)
582 }
583
584 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
585 match self.file.read_exact(buf) {
586 Ok(()) => Ok(buf.len()),
587 Err(err) => {
588 if err.kind() == std::io::ErrorKind::UnexpectedEof {
589 self.eof = true;
590 Err(ByteIOError::EOF)
591 } else {
592 Err(ByteIOError::ReadError)
593 }
594 },
595 }
596 }
597
598 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
599 let ret = self.file.read(buf);
600 if ret.is_err() { return Err(ByteIOError::ReadError); }
601 let sz = ret.unwrap();
602 if sz < buf.len() {
603 if let Err(_err) = self.file.read(&mut buf[sz..][..1]) {
604 self.eof = true;
605 } else {
606 return Ok(sz + 1);
607 }
608 }
609 Ok(sz)
610 }
611
612 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
613 let size = self.read_buf(buf)?;
614 self.seek(SeekFrom::Current(-(size as i64)))?;
615 Ok(size)
616 }
617
618 #[allow(unused_variables)]
619 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
620 Err(ByteIOError::NotImplemented)
621 }
622
623 fn tell(&mut self) -> u64 {
624 self.file.seek(SeekFrom::Current(0)).unwrap()
625 }
626
627 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
628 let res = self.file.seek(pos);
629 match res {
630 Ok(r) => Ok(r),
631 Err(_) => Err(ByteIOError::SeekError),
632 }
633 }
634
635 fn is_eof(&self) -> bool {
636 self.eof
637 }
638
639 fn is_seekable(&mut self) -> bool {
640 true
641 }
642
643 fn size(&mut self) -> i64 {
644 -1
645 }
646
647 fn flush(&mut self) -> ByteIOResult<()> { Ok(()) }
648 }
649
650
651 impl<T: Read+Seek> BoundedFileReader<T> {
652
653 /// Constructs a new instance of `BoundedFileReader`. The reader pretends that data before `start` and after `end` (if set) does not exist.
654 pub fn new_read(file: T, start: u64, end: Option<u64>) -> ByteIOResult<Self> {
655 let mut file = Box::new(file);
656 if let Some(epos) = end {
657 if start > epos {
658 return Err(ByteIOError::WrongRange);
659 }
660 }
661 if start > 0 && file.seek(SeekFrom::Start(start)).is_err() {
662 return Err(ByteIOError::SeekError);
663 }
664 Ok(Self { file, start, end, eof : false })
665 }
666 /// Constructs a new instance of `BoundedFileReader` using a boxed resource. The reader pretends that data before `start` and after `end` (if set) does not exist.
667 pub fn new_read_boxed(mut file: Box<T>, start: u64, end: Option<u64>) -> ByteIOResult<Self> {
668 if let Some(epos) = end {
669 if start > epos {
670 return Err(ByteIOError::WrongRange);
671 }
672 }
673 if start > 0 && file.seek(SeekFrom::Start(start)).is_err() {
674 return Err(ByteIOError::SeekError);
675 }
676 Ok(Self { file, start, end, eof : false })
677 }
678 /// Destroys the reader and releases the reader resource for a further use.
679 pub fn finish(self) -> Box<T> { self.file }
680 fn real_tell(&mut self) -> u64 {
681 self.file.seek(SeekFrom::Current(0)).unwrap()
682 }
683 fn max_read_len(&mut self, len: usize) -> usize {
684 if let Some(epos) = self.end {
685 (len as u64).min(epos - self.real_tell()) as usize
686 } else {
687 len
688 }
689 }
690 }
691
692 impl<T: Read+Seek> ByteIO for BoundedFileReader<T> {
693 fn read_byte(&mut self) -> ByteIOResult<u8> {
694 if let Some(epos) = self.end {
695 if self.real_tell() >= epos {
696 self.eof = true;
697 return Err(ByteIOError::EOF);
698 }
699 }
700 let mut byte : [u8; 1] = [0];
701 let ret = self.file.read(&mut byte);
702 if ret.is_err() { return Err(ByteIOError::ReadError); }
703 let sz = ret.unwrap();
704 if sz == 0 { self.eof = true; return Err(ByteIOError::EOF); }
705 Ok (byte[0])
706 }
707
708 fn peek_byte(&mut self) -> ByteIOResult<u8> {
709 let b = self.read_byte()?;
710 if self.file.seek(SeekFrom::Current(-1)).is_err() {
711 return Err(ByteIOError::SeekError);
712 }
713 Ok(b)
714 }
715
716 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
717 let len = self.max_read_len(buf.len());
718 match self.file.read_exact(&mut buf[..len]) {
719 Ok(()) if len == buf.len() => Ok(buf.len()),
720 Ok(()) => {
721 self.eof = true;
722 Err(ByteIOError::EOF)
723 },
724 Err(err) => {
725 if err.kind() == std::io::ErrorKind::UnexpectedEof {
726 self.eof = true;
727 Err(ByteIOError::EOF)
728 } else {
729 Err(ByteIOError::ReadError)
730 }
731 },
732 }
733 }
734
735 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
736 let len = self.max_read_len(buf.len());
737 let ret = self.file.read(&mut buf[..len]);
738 if ret.is_err() { return Err(ByteIOError::ReadError); }
739 let sz = ret.unwrap();
740 if sz < len {
741 if let Err(_err) = self.file.read(&mut buf[sz..][..1]) {
742 self.eof = true;
743 } else {
744 return Ok(sz + 1);
745 }
746 }
747 Ok(sz)
748 }
749
750 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
751 let len = self.max_read_len(buf.len());
752 let size = self.read_buf(&mut buf[..len])?;
753 if self.file.seek(SeekFrom::Current(-(size as i64))).is_err() {
754 return Err(ByteIOError::SeekError);
755 }
756 Ok(size)
757 }
758
759 #[allow(unused_variables)]
760 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
761 Err(ByteIOError::NotImplemented)
762 }
763
764 fn tell(&mut self) -> u64 {
765 self.file.seek(SeekFrom::Current(0)).unwrap() - self.start
766 }
767
768 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
769 let res = match pos {
770 SeekFrom::Start(off) => {
771 let dpos = self.start + off;
772 if let Some(epos) = self.end {
773 if dpos > epos {
774 return Err(ByteIOError::WrongRange);
775 }
776 }
777 self.file.seek(SeekFrom::Start(dpos))
778 },
779 SeekFrom::Current(off) => {
780 let dpos = (self.real_tell() as i64) + off;
781 let end = self.end.unwrap_or(dpos as u64);
782 if dpos < 0 || ((dpos as u64) < self.start) || ((dpos as u64) > end) {
783 return Err(ByteIOError::WrongRange);
784 }
785 self.file.seek(pos)
786 },
787 SeekFrom::End(off) => {
788 if let Some(epos) = self.end {
789 let dpos = (epos as i64) + off;
790 if dpos < (self.start as i64) || ((dpos as u64) > epos) {
791 return Err(ByteIOError::WrongRange);
792 }
793 self.file.seek(SeekFrom::Start(dpos as u64))
794 } else {
795 self.file.seek(pos)
796 }
797 },
798 };
799 match res {
800 Ok(r) => Ok(r),
801 Err(_) => Err(ByteIOError::SeekError),
802 }
803 }
804
805 fn is_eof(&self) -> bool {
806 self.eof
807 }
808
809 fn is_seekable(&mut self) -> bool {
810 true
811 }
812
813 fn size(&mut self) -> i64 {
814 -1
815 }
816
817 fn flush(&mut self) -> ByteIOResult<()> { Ok(()) }
818 }
819
820
821 /// High-level bytestream writer.
822 ///
823 /// User is supposed to create some writer implementing [`ByteIO`] trait e.g. [`MemoryWriter`] and use it to create `ByteWriter` which can be used for writing e.g. various integer types.
824 ///
825 /// # Examples
826 ///
827 /// ````
828 /// use nihav_core::io::byteio::{MemoryWriter,ByteWriter};
829 /// # use nihav_core::io::byteio::ByteIOResult;
830 ///
831 /// # fn foo() -> ByteIOResult<()> {
832 /// let mut memory = [0u8; 4];
833 /// let mut mw = MemoryWriter::new_write(&mut memory);
834 /// let mut bw = ByteWriter::new(&mut mw);
835 /// let val = bw.write_u16be(42)?; // memory should be [ 0, 42, 0, 0 ]
836 /// let val = bw.write_u16le(42)?; // memory should be [ 0, 42, 42, 0 ]
837 /// # Ok(())
838 /// # }
839 /// ````
840 ///
841 /// [`ByteIO`]: ./trait.ByteIO.html
842 /// [`MemoryWriter`]: ./struct.MemoryWriter.html
843 #[allow(dead_code)]
844 pub struct ByteWriter<'a> {
845 io: &'a mut dyn ByteIO,
846 }
847
848 /// Bytestream writer to memory.
849 pub struct MemoryWriter<'a> {
850 buf: &'a mut [u8],
851 pos: usize,
852 }
853
854 /// Bytestream writer to anything implementing `std::io::Write` and `std::io::Seek`.
855 pub struct FileWriter<T: Write+Seek> {
856 file: Box<T>,
857 }
858
859 /// Bytestream writer to memory.
860 ///
861 /// Unlike [`MemoryWriter`] which writes to an array of fixed size, `GrowableMemoryWriter` grows output size when output size exceeds capacity.
862 ///
863 /// [`MemoryWriter`]: ./struct.MemoryWriter.html
864 pub struct GrowableMemoryWriter<'a> {
865 buf: &'a mut Vec<u8>,
866 pos: usize,
867 }
868
869 impl<'a> ByteWriter<'a> {
870 /// Constructs a new instance of `ByteWriter`.
871 pub fn new(io: &'a mut dyn ByteIO) -> Self { ByteWriter { io } }
872
873 /// Writes byte array to the output.
874 pub fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
875 self.io.write_buf(buf)
876 }
877
878 /// Writes single byte to the output.
879 pub fn write_byte(&mut self, val: u8) -> ByteIOResult<()> {
880 let buf: [u8; 1] = [val];
881 self.io.write_buf(&buf)
882 }
883
884 /// Writes 16-bit big-endian integer to the output.
885 pub fn write_u16be(&mut self, val: u16) -> ByteIOResult<()> {
886 let buf: [u8; 2] = [((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
887 self.io.write_buf(&buf)
888 }
889
890 /// Writes 16-bit little-endian integer to the output.
891 pub fn write_u16le(&mut self, val: u16) -> ByteIOResult<()> {
892 let buf: [u8; 2] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8];
893 self.io.write_buf(&buf)
894 }
895
896 /// Writes 24-bit big-endian integer to the output.
897 pub fn write_u24be(&mut self, val: u32) -> ByteIOResult<()> {
898 let buf: [u8; 3] = [((val >> 16) & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, (val & 0xFF) as u8];
899 self.write_buf(&buf)
900 }
901
902 /// Writes 24-bit little-endian integer to the output.
903 pub fn write_u24le(&mut self, val: u32) -> ByteIOResult<()> {
904 let buf: [u8; 3] = [(val & 0xFF) as u8, ((val >> 8) & 0xFF) as u8, ((val >> 16) & 0xFF) as u8];
905 self.write_buf(&buf)
906 }
907
908 /// Writes 32-bit big-endian integer to the output.
909 pub fn write_u32be(&mut self, val: u32) -> ByteIOResult<()> {
910 self.write_u16be(((val >> 16) & 0xFFFF) as u16)?;
911 self.write_u16be((val & 0xFFFF) as u16)
912 }
913
914 /// Writes 32-bit little-endian integer to the output.
915 pub fn write_u32le(&mut self, val: u32) -> ByteIOResult<()> {
916 self.write_u16le((val & 0xFFFF) as u16)?;
917 self.write_u16le(((val >> 16) & 0xFFFF) as u16)
918 }
919
920 /// Writes 64-bit big-endian integer to the output.
921 pub fn write_u64be(&mut self, val: u64) -> ByteIOResult<()> {
922 self.write_u32be((val >> 32) as u32)?;
923 self.write_u32be(val as u32)
924 }
925
926 /// Writes 64-bit little-endian integer to the output.
927 pub fn write_u64le(&mut self, val: u64) -> ByteIOResult<()> {
928 self.write_u32le(val as u32)?;
929 self.write_u32le((val >> 32) as u32)
930 }
931
932 /// Writes 32-bit big-endian floating point number to the output.
933 pub fn write_f32be(&mut self, val: f32) -> ByteIOResult<()> {
934 self.write_u32be(val.to_bits())
935 }
936
937 /// Writes 32-bit little-endian floating point number to the output.
938 pub fn write_f32le(&mut self, val: f32) -> ByteIOResult<()> {
939 self.write_u32le(val.to_bits())
940 }
941
942 /// Writes 64-bit big-endian floating point number to the output.
943 pub fn write_f64be(&mut self, val: f64) -> ByteIOResult<()> {
944 self.write_u64be(val.to_bits())
945 }
946
947 /// Writes 64-bit little-endian floating point number to the output.
948 pub fn write_f64le(&mut self, val: f64) -> ByteIOResult<()> {
949 self.write_u64le(val.to_bits())
950 }
951
952 /// Reports the current write position.
953 pub fn tell(&mut self) -> u64 {
954 self.io.tell()
955 }
956
957 /// Seeks to the requested position.
958 pub fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
959 self.io.seek(pos)
960 }
961
962 /// Reports the amount of bytes the writer can still write (-1 if unknown).
963 pub fn size_left(&mut self) -> i64 {
964 let sz = self.io.size();
965 if sz == -1 { return -1; }
966 sz - (self.tell() as i64)
967 }
968
969 /// Flushes output stream if possible.
970 pub fn flush(&mut self) -> ByteIOResult<()> {
971 self.io.flush()
972 }
973 }
974
975 impl<'a> MemoryWriter<'a> {
976
977 /// Constructs a new instance of `MemoryWriter`.
978 pub fn new_write(buf: &'a mut [u8]) -> Self {
979 MemoryWriter { buf, pos: 0 }
980 }
981
982 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
983 if pos < 0 || (pos as usize) > self.buf.len() {
984 return Err(ByteIOError::WrongRange)
985 }
986 self.pos = pos as usize;
987 Ok(pos as u64)
988 }
989 }
990
991 impl<'a> ByteIO for MemoryWriter<'a> {
992 #[allow(unused_variables)]
993 fn read_byte(&mut self) -> ByteIOResult<u8> {
994 Err(ByteIOError::NotImplemented)
995 }
996
997 #[allow(unused_variables)]
998 fn peek_byte(&mut self) -> ByteIOResult<u8> {
999 Err(ByteIOError::NotImplemented)
1000 }
1001
1002 #[allow(unused_variables)]
1003 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1004 Err(ByteIOError::NotImplemented)
1005 }
1006
1007 #[allow(unused_variables)]
1008 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1009 Err(ByteIOError::NotImplemented)
1010 }
1011
1012 #[allow(unused_variables)]
1013 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1014 Err(ByteIOError::NotImplemented)
1015 }
1016
1017 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
1018 if self.pos + buf.len() > self.buf.len() { return Err(ByteIOError::WriteError); }
1019 self.buf[self.pos..][..buf.len()].copy_from_slice(buf);
1020 self.pos += buf.len();
1021 Ok(())
1022 }
1023
1024 fn tell(&mut self) -> u64 {
1025 self.pos as u64
1026 }
1027
1028 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
1029 let cur_pos = self.pos as i64;
1030 let cur_size = self.buf.len() as i64;
1031 match pos {
1032 SeekFrom::Start(x) => self.real_seek(x as i64),
1033 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
1034 SeekFrom::End(x) => self.real_seek(cur_size + x),
1035 }
1036 }
1037
1038 fn is_eof(&self) -> bool {
1039 self.pos >= self.buf.len()
1040 }
1041
1042 fn is_seekable(&mut self) -> bool {
1043 true
1044 }
1045
1046 fn size(&mut self) -> i64 {
1047 self.buf.len() as i64
1048 }
1049
1050 fn flush(&mut self) -> ByteIOResult<()> { Ok(()) }
1051 }
1052
1053 impl<'a> GrowableMemoryWriter<'a> {
1054
1055 /// Constructs a new instance of `GrowableMemoryWriter`.
1056 pub fn new_write(buf: &'a mut Vec<u8>) -> Self {
1057 GrowableMemoryWriter { buf, pos: 0 }
1058 }
1059
1060 fn real_seek(&mut self, pos: i64) -> ByteIOResult<u64> {
1061 if pos < 0 || (pos as usize) > self.buf.len() {
1062 return Err(ByteIOError::WrongRange)
1063 }
1064 self.pos = pos as usize;
1065 Ok(pos as u64)
1066 }
1067 }
1068
1069 impl<'a> ByteIO for GrowableMemoryWriter<'a> {
1070 #[allow(unused_variables)]
1071 fn read_byte(&mut self) -> ByteIOResult<u8> {
1072 Err(ByteIOError::NotImplemented)
1073 }
1074
1075 #[allow(unused_variables)]
1076 fn peek_byte(&mut self) -> ByteIOResult<u8> {
1077 Err(ByteIOError::NotImplemented)
1078 }
1079
1080 #[allow(unused_variables)]
1081 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1082 Err(ByteIOError::NotImplemented)
1083 }
1084
1085 #[allow(unused_variables)]
1086 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1087 Err(ByteIOError::NotImplemented)
1088 }
1089
1090 #[allow(unused_variables)]
1091 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1092 Err(ByteIOError::NotImplemented)
1093 }
1094
1095 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
1096 if self.pos + buf.len() > self.buf.len() {
1097 self.buf.resize(self.pos + buf.len(), 0);
1098 }
1099 self.buf[self.pos..][..buf.len()].copy_from_slice(buf);
1100 self.pos += buf.len();
1101 Ok(())
1102 }
1103
1104 fn tell(&mut self) -> u64 {
1105 self.pos as u64
1106 }
1107
1108 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
1109 let cur_pos = self.pos as i64;
1110 let cur_size = self.buf.len() as i64;
1111 match pos {
1112 SeekFrom::Start(x) => self.real_seek(x as i64),
1113 SeekFrom::Current(x) => self.real_seek(cur_pos + x),
1114 SeekFrom::End(x) => self.real_seek(cur_size + x),
1115 }
1116 }
1117
1118 fn is_eof(&self) -> bool {
1119 self.pos >= self.buf.len()
1120 }
1121
1122 fn is_seekable(&mut self) -> bool {
1123 true
1124 }
1125
1126 fn size(&mut self) -> i64 {
1127 self.buf.len() as i64
1128 }
1129
1130 fn flush(&mut self) -> ByteIOResult<()> { Ok(()) }
1131 }
1132
1133 impl<T: Write+Seek> FileWriter<T> {
1134 /// Constructs a new instance of `FileWriter`.
1135 pub fn new_write(file: T) -> Self {
1136 FileWriter { file: Box::new(file) }
1137 }
1138 }
1139
1140 impl<T: Write+Seek> ByteIO for FileWriter<T> {
1141 #[allow(unused_variables)]
1142 fn read_byte(&mut self) -> ByteIOResult<u8> {
1143 Err(ByteIOError::NotImplemented)
1144 }
1145
1146 #[allow(unused_variables)]
1147 fn peek_byte(&mut self) -> ByteIOResult<u8> {
1148 Err(ByteIOError::NotImplemented)
1149 }
1150
1151 #[allow(unused_variables)]
1152 fn read_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1153 Err(ByteIOError::NotImplemented)
1154 }
1155
1156 #[allow(unused_variables)]
1157 fn read_buf_some(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1158 Err(ByteIOError::NotImplemented)
1159 }
1160
1161 #[allow(unused_variables)]
1162 fn peek_buf(&mut self, buf: &mut [u8]) -> ByteIOResult<usize> {
1163 Err(ByteIOError::NotImplemented)
1164 }
1165
1166 fn write_buf(&mut self, buf: &[u8]) -> ByteIOResult<()> {
1167 match self.file.write_all(buf) {
1168 Ok(()) => Ok(()),
1169 Err(_) => Err(ByteIOError::WriteError),
1170 }
1171 }
1172
1173 fn tell(&mut self) -> u64 {
1174 self.file.seek(SeekFrom::Current(0)).unwrap()
1175 }
1176
1177 fn seek(&mut self, pos: SeekFrom) -> ByteIOResult<u64> {
1178 let res = self.file.seek(pos);
1179 match res {
1180 Ok(r) => Ok(r),
1181 Err(_) => Err(ByteIOError::SeekError),
1182 }
1183 }
1184
1185 fn is_eof(&self) -> bool {
1186 false
1187 }
1188
1189 fn is_seekable(&mut self) -> bool {
1190 true
1191 }
1192
1193 fn size(&mut self) -> i64 {
1194 -1
1195 }
1196
1197 fn flush(&mut self) -> ByteIOResult<()> {
1198 match self.file.flush() {
1199 Ok(()) => Ok(()),
1200 Err(_) => Err(ByteIOError::WriteError),
1201 }
1202 }
1203 }
1204
1205 #[cfg(test)]
1206 mod test {
1207 use super::*;
1208 use std::fs::File;
1209
1210 #[test]
1211 fn test_read() {
1212 //const DATA : &'static [u8] = include_bytes!("../../assets/file");
1213 let buf: [u8; 64] = [1; 64];
1214 let mut mr = MemoryReader::new_read(&buf);
1215 let mut reader = ByteReader::new(&mut mr);
1216 assert_eq!(reader.read_byte().unwrap(), 0x01u8);
1217 assert_eq!(reader.read_u16le().unwrap(), 0x0101u16);
1218 assert_eq!(reader.read_u24le().unwrap(), 0x010101u32);
1219 assert_eq!(reader.read_u32le().unwrap(), 0x01010101u32);
1220 assert_eq!(reader.read_u64le().unwrap(), 0x0101010101010101u64);
1221 let mut file = File::open("assets/Misc/MaoMacha.asx").unwrap();
1222 let mut fr = FileReader::new_read(&mut file);
1223 let mut br2 = ByteReader::new(&mut fr);
1224 assert_eq!(br2.read_byte().unwrap(), 0x30);
1225 assert_eq!(br2.read_u24be().unwrap(), 0x26B275);
1226 assert_eq!(br2.read_u24le().unwrap(), 0xCF668E);
1227 assert_eq!(br2.read_u32be().unwrap(), 0x11A6D900);
1228 assert_eq!(br2.read_u32le().unwrap(), 0xCE6200AA);
1229 }
1230 #[test]
1231 fn test_write() {
1232 let mut buf: [u8; 64] = [0; 64];
1233 {
1234 let mut mw = MemoryWriter::new_write(&mut buf);
1235 let mut bw = ByteWriter::new(&mut mw);
1236 bw.write_byte(0x00).unwrap();
1237 bw.write_u16be(0x0102).unwrap();
1238 bw.write_u24be(0x030405).unwrap();
1239 bw.write_u32be(0x06070809).unwrap();
1240 bw.write_u64be(0x0A0B0C0D0E0F1011).unwrap();
1241 bw.write_byte(0x00).unwrap();
1242 bw.write_u16le(0x0201).unwrap();
1243 bw.write_u24le(0x050403).unwrap();
1244 bw.write_u32le(0x09080706).unwrap();
1245 bw.write_u64le(0x11100F0E0D0C0B0A).unwrap();
1246 assert_eq!(bw.size_left(), 28);
1247 }
1248 for i in 0..0x12 {
1249 assert_eq!(buf[(i + 0x00) as usize], i);
1250 assert_eq!(buf[(i + 0x12) as usize], i);
1251 }
1252 }
1253 }