/rust/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/src/reader.rs
Line | Count | Source |
1 | | #[cfg(feature="std")] |
2 | | use std::io::{self, Error, ErrorKind, Read}; |
3 | | #[cfg(feature="std")] |
4 | | pub use alloc_stdlib::StandardAlloc; |
5 | | #[cfg(all(feature="unsafe",feature="std"))] |
6 | | pub use alloc_stdlib::HeapAlloc; |
7 | | pub use huffman::{HuffmanCode, HuffmanTreeGroup}; |
8 | | pub use state::BrotliState; |
9 | | // use io_wrappers::write_all; |
10 | | pub use io_wrappers::{CustomRead, CustomWrite}; |
11 | | #[cfg(feature="std")] |
12 | | pub use io_wrappers::{IntoIoReader, IoReaderWrapper, IoWriterWrapper}; |
13 | | pub use super::decode::{BrotliDecompressStream, BrotliResult}; |
14 | | pub use alloc::{AllocatedStackMemory, Allocator, SliceWrapper, SliceWrapperMut, StackAllocator}; |
15 | | |
16 | | #[cfg(feature="std")] |
17 | | pub struct DecompressorCustomAlloc<R: Read, |
18 | | BufferType : SliceWrapperMut<u8>, |
19 | | AllocU8 : Allocator<u8>, |
20 | | AllocU32 : Allocator<u32>, |
21 | | AllocHC : Allocator<HuffmanCode> >(DecompressorCustomIo<io::Error, |
22 | | IntoIoReader<R>, |
23 | | BufferType, |
24 | | AllocU8, AllocU32, AllocHC>); |
25 | | |
26 | | |
27 | | #[cfg(feature="std")] |
28 | | impl<R: Read, |
29 | | BufferType : SliceWrapperMut<u8>, |
30 | | AllocU8, |
31 | | AllocU32, |
32 | | AllocHC> DecompressorCustomAlloc<R, BufferType, AllocU8, AllocU32, AllocHC> |
33 | | where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode> |
34 | | { |
35 | | |
36 | 0 | pub fn new(r: R, buffer : BufferType, |
37 | 0 | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC) -> Self { |
38 | 0 | DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>( |
39 | 0 | DecompressorCustomIo::<Error, |
40 | 0 | IntoIoReader<R>, |
41 | 0 | BufferType, |
42 | 0 | AllocU8, AllocU32, AllocHC>::new(IntoIoReader::<R>(r), |
43 | 0 | buffer, |
44 | 0 | alloc_u8, alloc_u32, alloc_hc, |
45 | 0 | Error::new(ErrorKind::InvalidData, |
46 | 0 | "Invalid Data"))) |
47 | 0 | } |
48 | | |
49 | 94.3k | pub fn new_with_custom_dictionary(r: R, buffer : BufferType, |
50 | 94.3k | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, |
51 | 94.3k | dict: AllocU8::AllocatedMemory) -> Self { |
52 | 94.3k | DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>( |
53 | 94.3k | DecompressorCustomIo::<Error, |
54 | 94.3k | IntoIoReader<R>, |
55 | 94.3k | BufferType, |
56 | 94.3k | AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r), |
57 | 94.3k | buffer, |
58 | 94.3k | alloc_u8, alloc_u32, alloc_hc, |
59 | 94.3k | dict, |
60 | 94.3k | Error::new(ErrorKind::InvalidData, |
61 | 94.3k | "Invalid Data"))) |
62 | 94.3k | } <brotli_decompressor::reader::DecompressorCustomAlloc<suricata::http2::decompression::HTTP2cursor, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::new_with_custom_dictionary Line | Count | Source | 49 | 68.8k | pub fn new_with_custom_dictionary(r: R, buffer : BufferType, | 50 | 68.8k | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, | 51 | 68.8k | dict: AllocU8::AllocatedMemory) -> Self { | 52 | 68.8k | DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>( | 53 | 68.8k | DecompressorCustomIo::<Error, | 54 | 68.8k | IntoIoReader<R>, | 55 | 68.8k | BufferType, | 56 | 68.8k | AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r), | 57 | 68.8k | buffer, | 58 | 68.8k | alloc_u8, alloc_u32, alloc_hc, | 59 | 68.8k | dict, | 60 | 68.8k | Error::new(ErrorKind::InvalidData, | 61 | 68.8k | "Invalid Data"))) | 62 | 68.8k | } |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomAlloc<_, _, _, _, _>>::new_with_custom_dictionary <brotli_decompressor::reader::DecompressorCustomAlloc<suricata::http2::decompression::HTTP2cursor, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::new_with_custom_dictionary Line | Count | Source | 49 | 25.4k | pub fn new_with_custom_dictionary(r: R, buffer : BufferType, | 50 | 25.4k | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, | 51 | 25.4k | dict: AllocU8::AllocatedMemory) -> Self { | 52 | 25.4k | DecompressorCustomAlloc::<R, BufferType, AllocU8, AllocU32, AllocHC>( | 53 | 25.4k | DecompressorCustomIo::<Error, | 54 | 25.4k | IntoIoReader<R>, | 55 | 25.4k | BufferType, | 56 | 25.4k | AllocU8, AllocU32, AllocHC>::new_with_custom_dictionary(IntoIoReader::<R>(r), | 57 | 25.4k | buffer, | 58 | 25.4k | alloc_u8, alloc_u32, alloc_hc, | 59 | 25.4k | dict, | 60 | 25.4k | Error::new(ErrorKind::InvalidData, | 61 | 25.4k | "Invalid Data"))) | 62 | 25.4k | } |
|
63 | | |
64 | 0 | pub fn get_ref(&self) -> &R { |
65 | 0 | &self.0.get_ref().0 |
66 | 0 | } |
67 | 0 | pub fn get_mut(&mut self) -> &mut R { |
68 | 0 | &mut self.0.get_mut().0 |
69 | 0 | } |
70 | 0 | pub fn into_inner(self) -> R { |
71 | 0 | self.0.into_inner().0 |
72 | 0 | } |
73 | | } |
74 | | #[cfg(feature="std")] |
75 | | impl<R: Read, |
76 | | BufferType : SliceWrapperMut<u8>, |
77 | | AllocU8 : Allocator<u8>, |
78 | | AllocU32 : Allocator<u32>, |
79 | | AllocHC : Allocator<HuffmanCode> > Read for DecompressorCustomAlloc<R, |
80 | | BufferType, |
81 | | AllocU8, |
82 | | AllocU32, |
83 | | AllocHC> { |
84 | 2.46M | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
85 | 2.46M | self.0.read(buf) |
86 | 2.46M | } <brotli_decompressor::reader::DecompressorCustomAlloc<suricata::http2::decompression::HTTP2cursor, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as std::io::Read>::read Line | Count | Source | 84 | 1.98M | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 85 | 1.98M | self.0.read(buf) | 86 | 1.98M | } |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomAlloc<_, _, _, _, _> as std::io::Read>::read <brotli_decompressor::reader::DecompressorCustomAlloc<suricata::http2::decompression::HTTP2cursor, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as std::io::Read>::read Line | Count | Source | 84 | 477k | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 85 | 477k | self.0.read(buf) | 86 | 477k | } |
|
87 | | } |
88 | | |
89 | | |
90 | | #[cfg(not(any(feature="unsafe", not(feature="std"))))] |
91 | | pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R, |
92 | | <StandardAlloc |
93 | | as Allocator<u8>>::AllocatedMemory, |
94 | | StandardAlloc, |
95 | | StandardAlloc, |
96 | | StandardAlloc>); |
97 | | |
98 | | |
99 | | #[cfg(not(any(feature="unsafe", not(feature="std"))))] |
100 | | impl<R: Read> Decompressor<R> { |
101 | 94.3k | pub fn new(r: R, buffer_size: usize) -> Self { |
102 | 94.3k | let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default(); |
103 | 94.3k | Self::new_with_custom_dict(r, buffer_size, dict) |
104 | 94.3k | } <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor>>::new Line | Count | Source | 101 | 68.8k | pub fn new(r: R, buffer_size: usize) -> Self { | 102 | 68.8k | let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default(); | 103 | 68.8k | Self::new_with_custom_dict(r, buffer_size, dict) | 104 | 68.8k | } |
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::new <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor>>::new Line | Count | Source | 101 | 25.4k | pub fn new(r: R, buffer_size: usize) -> Self { | 102 | 25.4k | let dict = <StandardAlloc as Allocator<u8>>::AllocatedMemory::default(); | 103 | 25.4k | Self::new_with_custom_dict(r, buffer_size, dict) | 104 | 25.4k | } |
|
105 | 94.3k | pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self { |
106 | 94.3k | let mut alloc = StandardAlloc::default(); |
107 | 94.3k | let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size}); |
108 | 94.3k | Decompressor::<R>(DecompressorCustomAlloc::<R, |
109 | 94.3k | <StandardAlloc |
110 | 94.3k | as Allocator<u8>>::AllocatedMemory, |
111 | 94.3k | StandardAlloc, |
112 | 94.3k | StandardAlloc, |
113 | 94.3k | StandardAlloc>::new_with_custom_dictionary(r, |
114 | 94.3k | buffer, |
115 | 94.3k | alloc, |
116 | 94.3k | StandardAlloc::default(), |
117 | 94.3k | StandardAlloc::default(), |
118 | 94.3k | dict)) |
119 | 94.3k | } <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor>>::new_with_custom_dict Line | Count | Source | 105 | 68.8k | pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self { | 106 | 68.8k | let mut alloc = StandardAlloc::default(); | 107 | 68.8k | let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size}); | 108 | 68.8k | Decompressor::<R>(DecompressorCustomAlloc::<R, | 109 | 68.8k | <StandardAlloc | 110 | 68.8k | as Allocator<u8>>::AllocatedMemory, | 111 | 68.8k | StandardAlloc, | 112 | 68.8k | StandardAlloc, | 113 | 68.8k | StandardAlloc>::new_with_custom_dictionary(r, | 114 | 68.8k | buffer, | 115 | 68.8k | alloc, | 116 | 68.8k | StandardAlloc::default(), | 117 | 68.8k | StandardAlloc::default(), | 118 | 68.8k | dict)) | 119 | 68.8k | } |
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::new_with_custom_dict <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor>>::new_with_custom_dict Line | Count | Source | 105 | 25.4k | pub fn new_with_custom_dict(r: R, buffer_size: usize, dict: <StandardAlloc as Allocator<u8>>::AllocatedMemory) -> Self { | 106 | 25.4k | let mut alloc = StandardAlloc::default(); | 107 | 25.4k | let buffer = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut alloc, if buffer_size == 0 {4096} else {buffer_size}); | 108 | 25.4k | Decompressor::<R>(DecompressorCustomAlloc::<R, | 109 | 25.4k | <StandardAlloc | 110 | 25.4k | as Allocator<u8>>::AllocatedMemory, | 111 | 25.4k | StandardAlloc, | 112 | 25.4k | StandardAlloc, | 113 | 25.4k | StandardAlloc>::new_with_custom_dictionary(r, | 114 | 25.4k | buffer, | 115 | 25.4k | alloc, | 116 | 25.4k | StandardAlloc::default(), | 117 | 25.4k | StandardAlloc::default(), | 118 | 25.4k | dict)) | 119 | 25.4k | } |
|
120 | | |
121 | 0 | pub fn get_ref(&self) -> &R { |
122 | 0 | &self.0.get_ref() |
123 | 0 | } |
124 | 413k | pub fn get_mut(&mut self) -> &mut R { |
125 | 413k | &mut ((self.0).0).get_mut().0 |
126 | 413k | } <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor>>::get_mut Line | Count | Source | 124 | 277k | pub fn get_mut(&mut self) -> &mut R { | 125 | 277k | &mut ((self.0).0).get_mut().0 | 126 | 277k | } |
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_>>::get_mut <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor>>::get_mut Line | Count | Source | 124 | 135k | pub fn get_mut(&mut self) -> &mut R { | 125 | 135k | &mut ((self.0).0).get_mut().0 | 126 | 135k | } |
|
127 | 0 | pub fn into_inner(self) -> R { |
128 | 0 | self.0.into_inner() |
129 | 0 | } |
130 | | } |
131 | | |
132 | | |
133 | | #[cfg(all(feature="unsafe", feature="std"))] |
134 | | pub struct Decompressor<R: Read>(DecompressorCustomAlloc<R, |
135 | | <HeapAlloc<u8> |
136 | | as Allocator<u8>>::AllocatedMemory, |
137 | | HeapAlloc<u8>, |
138 | | HeapAlloc<u32>, |
139 | | HeapAlloc<HuffmanCode> >); |
140 | | |
141 | | |
142 | | #[cfg(all(feature="unsafe", feature="std"))] |
143 | | impl<R: Read> Decompressor<R> { |
144 | | pub fn new(r: R, buffer_size: usize) -> Self { |
145 | | let dict = <HeapAlloc<u8> as Allocator<u8>>::AllocatedMemory::default(); |
146 | | Self::new_with_custom_dictionary(r, buffer_size, dict) |
147 | | } |
148 | | pub fn new_with_custom_dictionary(r: R, buffer_size: usize, dict: <HeapAlloc<u8> |
149 | | as Allocator<u8>>::AllocatedMemory) -> Self { |
150 | | let mut alloc_u8 = HeapAlloc::<u8>::new(0); |
151 | | let buffer = alloc_u8.alloc_cell(if buffer_size == 0 {4096} else {buffer_size}); |
152 | | let alloc_u32 = HeapAlloc::<u32>::new(0); |
153 | | let alloc_hc = HeapAlloc::<HuffmanCode>::new(HuffmanCode{ |
154 | | bits:0, value: 0, |
155 | | }); |
156 | | Decompressor::<R>(DecompressorCustomAlloc::<R, |
157 | | <HeapAlloc<u8> |
158 | | as Allocator<u8>>::AllocatedMemory, |
159 | | HeapAlloc<u8>, |
160 | | HeapAlloc<u32>, |
161 | | HeapAlloc<HuffmanCode> > |
162 | | ::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict)) |
163 | | } |
164 | | |
165 | | pub fn get_ref(&self) -> &R { |
166 | | self.0.get_ref() |
167 | | } |
168 | | pub fn get_mut(&mut self) -> &mut R { |
169 | | &mut (self.0).0.get_mut().0 |
170 | | } |
171 | | pub fn into_inner(self) -> R { |
172 | | self.0.into_inner() |
173 | | } |
174 | | } |
175 | | |
176 | | |
177 | | #[cfg(feature="std")] |
178 | | impl<R: Read> Read for Decompressor<R> { |
179 | 2.46M | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { |
180 | 2.46M | self.0.read(buf) |
181 | 2.46M | } <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor> as std::io::Read>::read Line | Count | Source | 179 | 1.98M | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 180 | 1.98M | self.0.read(buf) | 181 | 1.98M | } |
Unexecuted instantiation: <brotli_decompressor::reader::Decompressor<_> as std::io::Read>::read <brotli_decompressor::reader::Decompressor<suricata::http2::decompression::HTTP2cursor> as std::io::Read>::read Line | Count | Source | 179 | 477k | fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> { | 180 | 477k | self.0.read(buf) | 181 | 477k | } |
|
182 | | } |
183 | | |
184 | | pub struct DecompressorCustomIo<ErrType, |
185 | | R: CustomRead<ErrType>, |
186 | | BufferType: SliceWrapperMut<u8>, |
187 | | AllocU8: Allocator<u8>, |
188 | | AllocU32: Allocator<u32>, |
189 | | AllocHC: Allocator<HuffmanCode>> |
190 | | { |
191 | | input_buffer: BufferType, |
192 | | total_out: usize, |
193 | | input_offset: usize, |
194 | | input_len: usize, |
195 | | input: R, |
196 | | error_if_invalid_data: Option<ErrType>, |
197 | | state: BrotliState<AllocU8, AllocU32, AllocHC>, |
198 | | done: bool, |
199 | | } |
200 | | |
201 | | impl<ErrType, |
202 | | R: CustomRead<ErrType>, |
203 | | BufferType : SliceWrapperMut<u8>, |
204 | | AllocU8, |
205 | | AllocU32, |
206 | | AllocHC> DecompressorCustomIo<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC> |
207 | | where AllocU8 : Allocator<u8>, AllocU32 : Allocator<u32>, AllocHC : Allocator<HuffmanCode> |
208 | | { |
209 | | |
210 | 0 | pub fn new(r: R, buffer : BufferType, |
211 | 0 | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, |
212 | 0 | invalid_data_error_type : ErrType) -> Self { |
213 | 0 | let dict = AllocU8::AllocatedMemory::default(); |
214 | 0 | Self::new_with_custom_dictionary(r, buffer, alloc_u8, alloc_u32, alloc_hc, dict, invalid_data_error_type) |
215 | 0 | } |
216 | 94.3k | pub fn new_with_custom_dictionary(r: R, buffer : BufferType, |
217 | 94.3k | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, |
218 | 94.3k | dict: AllocU8::AllocatedMemory, |
219 | 94.3k | invalid_data_error_type : ErrType) -> Self { |
220 | 94.3k | DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{ |
221 | 94.3k | input_buffer : buffer, |
222 | 94.3k | total_out : 0, |
223 | 94.3k | input_offset : 0, |
224 | 94.3k | input_len : 0, |
225 | 94.3k | input: r, |
226 | 94.3k | state : BrotliState::new_with_custom_dictionary(alloc_u8, |
227 | 94.3k | alloc_u32, |
228 | 94.3k | alloc_hc, |
229 | 94.3k | dict), |
230 | 94.3k | error_if_invalid_data : Some(invalid_data_error_type), |
231 | 94.3k | done: false, |
232 | 94.3k | } |
233 | 94.3k | } <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::new_with_custom_dictionary Line | Count | Source | 216 | 68.8k | pub fn new_with_custom_dictionary(r: R, buffer : BufferType, | 217 | 68.8k | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, | 218 | 68.8k | dict: AllocU8::AllocatedMemory, | 219 | 68.8k | invalid_data_error_type : ErrType) -> Self { | 220 | 68.8k | DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{ | 221 | 68.8k | input_buffer : buffer, | 222 | 68.8k | total_out : 0, | 223 | 68.8k | input_offset : 0, | 224 | 68.8k | input_len : 0, | 225 | 68.8k | input: r, | 226 | 68.8k | state : BrotliState::new_with_custom_dictionary(alloc_u8, | 227 | 68.8k | alloc_u32, | 228 | 68.8k | alloc_hc, | 229 | 68.8k | dict), | 230 | 68.8k | error_if_invalid_data : Some(invalid_data_error_type), | 231 | 68.8k | done: false, | 232 | 68.8k | } | 233 | 68.8k | } |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::new_with_custom_dictionary <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::new_with_custom_dictionary Line | Count | Source | 216 | 25.4k | pub fn new_with_custom_dictionary(r: R, buffer : BufferType, | 217 | 25.4k | alloc_u8 : AllocU8, alloc_u32 : AllocU32, alloc_hc : AllocHC, | 218 | 25.4k | dict: AllocU8::AllocatedMemory, | 219 | 25.4k | invalid_data_error_type : ErrType) -> Self { | 220 | 25.4k | DecompressorCustomIo::<ErrType, R, BufferType, AllocU8, AllocU32, AllocHC>{ | 221 | 25.4k | input_buffer : buffer, | 222 | 25.4k | total_out : 0, | 223 | 25.4k | input_offset : 0, | 224 | 25.4k | input_len : 0, | 225 | 25.4k | input: r, | 226 | 25.4k | state : BrotliState::new_with_custom_dictionary(alloc_u8, | 227 | 25.4k | alloc_u32, | 228 | 25.4k | alloc_hc, | 229 | 25.4k | dict), | 230 | 25.4k | error_if_invalid_data : Some(invalid_data_error_type), | 231 | 25.4k | done: false, | 232 | 25.4k | } | 233 | 25.4k | } |
|
234 | | |
235 | 0 | pub fn get_ref(&self) -> &R { |
236 | 0 | &self.input |
237 | 0 | } |
238 | 413k | pub fn get_mut(&mut self) -> &mut R { |
239 | 413k | &mut self.input |
240 | 413k | } <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::get_mut Line | Count | Source | 238 | 277k | pub fn get_mut(&mut self) -> &mut R { | 239 | 277k | &mut self.input | 240 | 277k | } |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::get_mut <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::get_mut Line | Count | Source | 238 | 135k | pub fn get_mut(&mut self) -> &mut R { | 239 | 135k | &mut self.input | 240 | 135k | } |
|
241 | 0 | pub fn into_inner(self) -> R { |
242 | 0 | match self { |
243 | | DecompressorCustomIo { |
244 | 0 | input_buffer: _ib, |
245 | 0 | total_out: _to, |
246 | 0 | state: _state, |
247 | 0 | input_offset: _io, |
248 | 0 | input_len: _il, |
249 | 0 | error_if_invalid_data:_eiid, |
250 | 0 | input, |
251 | 0 | done: _done, |
252 | | } =>{ |
253 | 0 | input |
254 | | } |
255 | | } |
256 | 0 | } |
257 | | |
258 | 1.72M | pub fn copy_to_front(&mut self) { |
259 | 1.72M | let avail_in = self.input_len - self.input_offset; |
260 | 1.72M | if self.input_offset == self.input_buffer.slice_mut().len() { |
261 | 3.04k | self.input_offset = 0; |
262 | 3.04k | self.input_len = 0; |
263 | 1.72M | } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset { |
264 | 345 | let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset); |
265 | 345 | self.input_len -= self.input_offset; |
266 | 345 | first[0..avail_in].clone_from_slice(&second[0..avail_in]); |
267 | 345 | self.input_offset = 0; |
268 | 1.72M | } |
269 | 1.72M | } <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::copy_to_front Line | Count | Source | 258 | 1.44M | pub fn copy_to_front(&mut self) { | 259 | 1.44M | let avail_in = self.input_len - self.input_offset; | 260 | 1.44M | if self.input_offset == self.input_buffer.slice_mut().len() { | 261 | 2.05k | self.input_offset = 0; | 262 | 2.05k | self.input_len = 0; | 263 | 1.44M | } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset { | 264 | 236 | let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset); | 265 | 236 | self.input_len -= self.input_offset; | 266 | 236 | first[0..avail_in].clone_from_slice(&second[0..avail_in]); | 267 | 236 | self.input_offset = 0; | 268 | 1.44M | } | 269 | 1.44M | } |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _>>::copy_to_front <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc>>::copy_to_front Line | Count | Source | 258 | 284k | pub fn copy_to_front(&mut self) { | 259 | 284k | let avail_in = self.input_len - self.input_offset; | 260 | 284k | if self.input_offset == self.input_buffer.slice_mut().len() { | 261 | 987 | self.input_offset = 0; | 262 | 987 | self.input_len = 0; | 263 | 283k | } else if self.input_offset + 256 > self.input_buffer.slice_mut().len() && avail_in < self.input_offset { | 264 | 109 | let (first, second) = self.input_buffer.slice_mut().split_at_mut(self.input_offset); | 265 | 109 | self.input_len -= self.input_offset; | 266 | 109 | first[0..avail_in].clone_from_slice(&second[0..avail_in]); | 267 | 109 | self.input_offset = 0; | 268 | 283k | } | 269 | 284k | } |
|
270 | | } |
271 | | |
272 | | impl<ErrType, |
273 | | R: CustomRead<ErrType>, |
274 | | BufferType : SliceWrapperMut<u8>, |
275 | | AllocU8 : Allocator<u8>, |
276 | | AllocU32 : Allocator<u32>, |
277 | | AllocHC : Allocator<HuffmanCode> > CustomRead<ErrType> for DecompressorCustomIo<ErrType, |
278 | | R, |
279 | | BufferType, |
280 | | AllocU8, |
281 | | AllocU32, |
282 | | AllocHC> { |
283 | | /// This variant of read will return Ok(number of bytes read) until the file |
284 | | /// Is completed at which point it will return Ok(0). |
285 | | /// However if there are additional unconsumed bytes in the buffer, it will |
286 | | /// return Err(InvalidData) at that point. Otherwise it will keep returning |
287 | | /// Ok(0). |
288 | | /// |
289 | | /// # Arguments |
290 | | /// |
291 | | /// * `buf` - The buffer to read into |
292 | | /// |
293 | | /// # Errors |
294 | | /// |
295 | | /// Returns Ok(0) if the file has been fully decompressed. |
296 | | /// If the file has been fully decompressed but there are additional |
297 | | /// non-brotli bytes in the buffer, then return an InvalidData error. |
298 | | /// Also upstream errors from the reader are returned. |
299 | 2.46M | fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > { |
300 | 2.46M | let mut output_offset : usize = 0; |
301 | 2.46M | let mut avail_out = buf.len() - output_offset; |
302 | 2.46M | let mut avail_in = self.input_len - self.input_offset; |
303 | 2.59M | while avail_out == buf.len() { |
304 | 2.59M | match BrotliDecompressStream(&mut avail_in, |
305 | 2.59M | &mut self.input_offset, |
306 | 2.59M | &self.input_buffer.slice_mut()[..], |
307 | 2.59M | &mut avail_out, |
308 | 2.59M | &mut output_offset, |
309 | 2.59M | buf, |
310 | 2.59M | &mut self.total_out, |
311 | 2.59M | &mut self.state) { |
312 | | BrotliResult::NeedsMoreInput => { |
313 | 1.72M | self.copy_to_front(); |
314 | 1.72M | if output_offset != 0 { |
315 | | // The decompressor successfully decoded some bytes, but still requires more |
316 | | // we do not wish to risk self.input.read returning an error, so instead we |
317 | | // opt to return what we have and do not invoke the read trait method |
318 | 1.50M | return Ok(output_offset); |
319 | 222k | } |
320 | 222k | match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) { |
321 | 84.9k | Err(e) => { |
322 | 84.9k | return Err(e); |
323 | | }, |
324 | 137k | Ok(size) => if size == 0 { |
325 | 0 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)); Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#0}Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read::{closure#0}Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#0} |
326 | 137k | }else { |
327 | 137k | self.input_len += size; |
328 | 137k | avail_in = self.input_len - self.input_offset; |
329 | 137k | }, |
330 | | } |
331 | | }, |
332 | | BrotliResult::NeedsMoreOutput => { |
333 | 792k | break; |
334 | | }, |
335 | | BrotliResult::ResultSuccess => { |
336 | 34.7k | if output_offset == 0 { |
337 | 24.8k | if !self.done { |
338 | 11.8k | self.done = true; |
339 | 12.9k | } else if self.input_len != self.input_offset { |
340 | | // Did not consume entire input; report error. |
341 | 884 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset)); <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#1}Line | Count | Source | 341 | 555 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset)); |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read::{closure#1}<brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#1}Line | Count | Source | 341 | 329 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset)); |
|
342 | 12.0k | } |
343 | 9.94k | } |
344 | 33.8k | return Ok(output_offset); |
345 | | } |
346 | 42.5k | BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)), <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#2}Line | Count | Source | 346 | 29.9k | BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)), |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read::{closure#2}<brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read::{closure#2}Line | Count | Source | 346 | 12.5k | BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)), |
|
347 | | } |
348 | | } |
349 | 792k | Ok(output_offset) |
350 | 2.46M | } <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read Line | Count | Source | 299 | 1.98M | fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > { | 300 | 1.98M | let mut output_offset : usize = 0; | 301 | 1.98M | let mut avail_out = buf.len() - output_offset; | 302 | 1.98M | let mut avail_in = self.input_len - self.input_offset; | 303 | 2.07M | while avail_out == buf.len() { | 304 | 2.07M | match BrotliDecompressStream(&mut avail_in, | 305 | 2.07M | &mut self.input_offset, | 306 | 2.07M | &self.input_buffer.slice_mut()[..], | 307 | 2.07M | &mut avail_out, | 308 | 2.07M | &mut output_offset, | 309 | 2.07M | buf, | 310 | 2.07M | &mut self.total_out, | 311 | 2.07M | &mut self.state) { | 312 | | BrotliResult::NeedsMoreInput => { | 313 | 1.44M | self.copy_to_front(); | 314 | 1.44M | if output_offset != 0 { | 315 | | // The decompressor successfully decoded some bytes, but still requires more | 316 | | // we do not wish to risk self.input.read returning an error, so instead we | 317 | | // opt to return what we have and do not invoke the read trait method | 318 | 1.29M | return Ok(output_offset); | 319 | 145k | } | 320 | 145k | match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) { | 321 | 53.6k | Err(e) => { | 322 | 53.6k | return Err(e); | 323 | | }, | 324 | 91.7k | Ok(size) => if size == 0 { | 325 | 0 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)); | 326 | 91.7k | }else { | 327 | 91.7k | self.input_len += size; | 328 | 91.7k | avail_in = self.input_len - self.input_offset; | 329 | 91.7k | }, | 330 | | } | 331 | | }, | 332 | | BrotliResult::NeedsMoreOutput => { | 333 | 573k | break; | 334 | | }, | 335 | | BrotliResult::ResultSuccess => { | 336 | 27.1k | if output_offset == 0 { | 337 | 19.1k | if !self.done { | 338 | 9.49k | self.done = true; | 339 | 9.63k | } else if self.input_len != self.input_offset { | 340 | | // Did not consume entire input; report error. | 341 | 555 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset)); | 342 | 9.08k | } | 343 | 7.98k | } | 344 | 26.5k | return Ok(output_offset); | 345 | | } | 346 | 29.9k | BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)), | 347 | | } | 348 | | } | 349 | 573k | Ok(output_offset) | 350 | 1.98M | } |
Unexecuted instantiation: <brotli_decompressor::reader::DecompressorCustomIo<_, _, _, _, _, _> as brotli_decompressor::io_wrappers::CustomRead<_>>::read <brotli_decompressor::reader::DecompressorCustomIo<std::io::error::Error, brotli_decompressor::io_wrappers::IntoIoReader<suricata::http2::decompression::HTTP2cursor>, alloc_stdlib::heap_alloc::WrapBox<u8>, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc, alloc_stdlib::std_alloc::StandardAlloc> as brotli_decompressor::io_wrappers::CustomRead<std::io::error::Error>>::read Line | Count | Source | 299 | 477k | fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrType > { | 300 | 477k | let mut output_offset : usize = 0; | 301 | 477k | let mut avail_out = buf.len() - output_offset; | 302 | 477k | let mut avail_in = self.input_len - self.input_offset; | 303 | 523k | while avail_out == buf.len() { | 304 | 523k | match BrotliDecompressStream(&mut avail_in, | 305 | 523k | &mut self.input_offset, | 306 | 523k | &self.input_buffer.slice_mut()[..], | 307 | 523k | &mut avail_out, | 308 | 523k | &mut output_offset, | 309 | 523k | buf, | 310 | 523k | &mut self.total_out, | 311 | 523k | &mut self.state) { | 312 | | BrotliResult::NeedsMoreInput => { | 313 | 284k | self.copy_to_front(); | 314 | 284k | if output_offset != 0 { | 315 | | // The decompressor successfully decoded some bytes, but still requires more | 316 | | // we do not wish to risk self.input.read returning an error, so instead we | 317 | | // opt to return what we have and do not invoke the read trait method | 318 | 207k | return Ok(output_offset); | 319 | 76.6k | } | 320 | 76.6k | match self.input.read(&mut self.input_buffer.slice_mut()[self.input_len..]) { | 321 | 31.2k | Err(e) => { | 322 | 31.2k | return Err(e); | 323 | | }, | 324 | 45.3k | Ok(size) => if size == 0 { | 325 | 0 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)); | 326 | 45.3k | }else { | 327 | 45.3k | self.input_len += size; | 328 | 45.3k | avail_in = self.input_len - self.input_offset; | 329 | 45.3k | }, | 330 | | } | 331 | | }, | 332 | | BrotliResult::NeedsMoreOutput => { | 333 | 218k | break; | 334 | | }, | 335 | | BrotliResult::ResultSuccess => { | 336 | 7.64k | if output_offset == 0 { | 337 | 5.68k | if !self.done { | 338 | 2.36k | self.done = true; | 339 | 3.32k | } else if self.input_len != self.input_offset { | 340 | | // Did not consume entire input; report error. | 341 | 329 | return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(output_offset)); | 342 | 2.99k | } | 343 | 1.96k | } | 344 | 7.31k | return Ok(output_offset); | 345 | | } | 346 | 12.5k | BrotliResult::ResultFailure => return self.error_if_invalid_data.take().map(|e| Err(e)).unwrap_or(Ok(0)), | 347 | | } | 348 | | } | 349 | 218k | Ok(output_offset) | 350 | 477k | } |
|
351 | | } |
352 | | |
353 | | #[cfg(feature="std")] |
354 | | #[test] |
355 | | fn test_no_vanishing_bytes() { |
356 | | use std::string::ToString; |
357 | | |
358 | | // Output from this command: |
359 | | let compressed_with_extra = b"\x8f\x02\x80\x68\x65\x6c\x6c\x6f\x0a\x03\x67\x6f\x6f\x64\x62\x79\x65\x0a"; |
360 | | // Make sure that read_to_string returns the data. |
361 | | let cursor = std::io::Cursor::new(compressed_with_extra); |
362 | | let mut reader = super::Decompressor::new(cursor, 8000); |
363 | | assert_eq!(std::io::read_to_string(&mut reader).unwrap(), "hello\n"); |
364 | | |
365 | | // However you can call read extra times to make sure there's no data. |
366 | | let cursor = std::io::Cursor::new(compressed_with_extra); |
367 | | let mut reader = super::Decompressor::new(cursor, 8000); |
368 | | let mut data = std::vec::Vec::<u8>::default(); |
369 | | loop { |
370 | | let mut buf = [0u8;5]; |
371 | | let offset = reader.read(&mut buf).unwrap(); |
372 | | if offset == 0 { |
373 | | break; |
374 | | } |
375 | | data.extend_from_slice(&buf[..offset]); |
376 | | } |
377 | | assert_eq!( |
378 | | &data, |
379 | | &['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '\n' as u8]); |
380 | | |
381 | | // But calling read, one last time, results in an error because there |
382 | | // were leftover bytes in the buffer. |
383 | | let mut buf = [0u8;5]; |
384 | | assert_eq!(reader.read(&mut buf).unwrap_err().kind(), |
385 | | io::ErrorKind::InvalidData); |
386 | | data.clear(); |
387 | | |
388 | | |
389 | | } |
390 | | |
391 | | #[cfg(feature="std")] |
392 | | #[test] |
393 | | fn test_repeated_read_returns_zero() { |
394 | | use std::string::ToString; |
395 | | |
396 | | // Output from this command: |
397 | | let compressed_without_extra = b"\x8f\x02\x80\x68\x65\x6c\x6c\x6f\x0a\x03"; |
398 | | // Make sure that read_to_string returns the data. |
399 | | let cursor = std::io::Cursor::new(compressed_without_extra); |
400 | | let mut reader = super::Decompressor::new(cursor, 8000); |
401 | | assert_eq!(std::io::read_to_string(&mut reader).unwrap(), "hello\n"); |
402 | | |
403 | | // However you can call read extra times to make sure there's no data. |
404 | | let cursor = std::io::Cursor::new(compressed_without_extra); |
405 | | let mut reader = super::Decompressor::new(cursor, 8000); |
406 | | let mut data = std::vec::Vec::<u8>::default(); |
407 | | loop { |
408 | | let mut buf = [0u8;5]; |
409 | | let offset = reader.read(&mut buf).unwrap(); |
410 | | if offset == 0 { |
411 | | break; |
412 | | } |
413 | | data.extend_from_slice(&buf[..offset]); |
414 | | } |
415 | | assert_eq!(&data, &['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, '\n' as u8]); |
416 | | let mut buf = [0u8;5]; |
417 | | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
418 | | data.clear(); |
419 | | |
420 | | |
421 | | } |
422 | | |