| 1 | /* |
| 2 | * Copyright (c) 2023. |
| 3 | * |
| 4 | * This software is free software; |
| 5 | * |
| 6 | * You can redistribute it or modify it under terms of the MIT, Apache License or Zlib license |
| 7 | */ |
| 8 | //! Traits for reading and writing images in zune |
| 9 | //! |
| 10 | //! |
| 11 | //! This exposes the traits and implementations for readers |
| 12 | //! and writers in the zune family of decoders and encoders. |
| 13 | |
| 14 | use alloc::vec::Vec; |
| 15 | use core::ops::Range; |
| 16 | |
| 17 | /// The underlying reader trait |
| 18 | /// |
| 19 | /// # Considerations |
| 20 | /// |
| 21 | ///- When implementing this for a type, it is recommended to implement methods with |
| 22 | /// `#inline[(always)]` directive to allow the functions to get inlined in call sites, |
| 23 | /// this may make it faster on some situations since the call sites may be in hot loop. |
| 24 | /// |
| 25 | /// - If you are reading from a file and it's small , it is preferable to read it into memory |
| 26 | /// instead of using a file reader. |
| 27 | pub trait ZReaderTrait { |
| 28 | /// Get a single byte which is at position `index` |
| 29 | /// |
| 30 | /// # Arguments |
| 31 | /// - `index`: The position of the bytes |
| 32 | fn get_byte(&self, index: usize) -> Option<&u8>; |
| 33 | |
| 34 | /// Get a slice of bytes from a range of start..end |
| 35 | /// |
| 36 | /// # Arguments |
| 37 | /// |
| 38 | /// * `index`: The range of the bytes to read |
| 39 | /// |
| 40 | /// returns: `Option<&[u8]>` |
| 41 | /// |
| 42 | /// # Examples |
| 43 | /// |
| 44 | /// - Read 10 bytes from |
| 45 | /// ``` |
| 46 | /// extern crate alloc; |
| 47 | /// use alloc::vec::Vec; |
| 48 | /// use zune_core::bytestream::ZReaderTrait; |
| 49 | /// |
| 50 | /// let bytes = vec![0_u8;100]; |
| 51 | /// |
| 52 | /// // get ten bytes from 0..10 |
| 53 | /// let re = bytes.get_slice(0..10).unwrap(); |
| 54 | /// assert_eq!(10,re.len()) |
| 55 | /// |
| 56 | /// ``` |
| 57 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]>; |
| 58 | |
| 59 | /// Get total length of the underlying buffer. |
| 60 | /// |
| 61 | /// This should be the total bytes that are present in |
| 62 | /// the buffer. |
| 63 | /// |
| 64 | /// For files, this includes the file length. |
| 65 | /// For buffers this includes the internal buffer length |
| 66 | fn get_len(&self) -> usize; |
| 67 | } |
| 68 | |
| 69 | impl ZReaderTrait for &[u8] { |
| 70 | #[inline (always)] |
| 71 | fn get_byte(&self, index: usize) -> Option<&u8> { |
| 72 | self.get(index) |
| 73 | } |
| 74 | |
| 75 | #[inline (always)] |
| 76 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]> { |
| 77 | self.get(index) |
| 78 | } |
| 79 | |
| 80 | #[inline (always)] |
| 81 | fn get_len(&self) -> usize { |
| 82 | self.len() |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | impl ZReaderTrait for Vec<u8> { |
| 87 | #[inline (always)] |
| 88 | fn get_byte(&self, index: usize) -> Option<&u8> { |
| 89 | self.get(index) |
| 90 | } |
| 91 | |
| 92 | #[inline (always)] |
| 93 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]> { |
| 94 | self.get(index) |
| 95 | } |
| 96 | |
| 97 | #[inline (always)] |
| 98 | fn get_len(&self) -> usize { |
| 99 | self.len() |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | impl ZReaderTrait for &Vec<u8> { |
| 104 | #[inline (always)] |
| 105 | fn get_byte(&self, index: usize) -> Option<&u8> { |
| 106 | self.get(index) |
| 107 | } |
| 108 | |
| 109 | #[inline (always)] |
| 110 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]> { |
| 111 | self.get(index) |
| 112 | } |
| 113 | |
| 114 | #[inline (always)] |
| 115 | fn get_len(&self) -> usize { |
| 116 | self.len() |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | impl<const N: usize> ZReaderTrait for &[u8; N] { |
| 121 | fn get_byte(&self, index: usize) -> Option<&u8> { |
| 122 | self.get(index) |
| 123 | } |
| 124 | |
| 125 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]> { |
| 126 | self.get(index) |
| 127 | } |
| 128 | |
| 129 | fn get_len(&self) -> usize { |
| 130 | N |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | impl<const N: usize> ZReaderTrait for [u8; N] { |
| 135 | fn get_byte(&self, index: usize) -> Option<&u8> { |
| 136 | self.get(index) |
| 137 | } |
| 138 | |
| 139 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]> { |
| 140 | self.get(index) |
| 141 | } |
| 142 | |
| 143 | fn get_len(&self) -> usize { |
| 144 | N |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | impl ZReaderTrait for dyn AsRef<&[u8]> { |
| 149 | fn get_byte(&self, index: usize) -> Option<&u8> { |
| 150 | self.as_ref().get(index) |
| 151 | } |
| 152 | |
| 153 | fn get_slice(&self, index: Range<usize>) -> Option<&[u8]> { |
| 154 | self.as_ref().get(index) |
| 155 | } |
| 156 | |
| 157 | fn get_len(&self) -> usize { |
| 158 | self.as_ref().len() |
| 159 | } |
| 160 | } |
| 161 | |