1use core::fmt;
11use std::{
12 collections::TryReserveError,
13 future::poll_fn,
14 io::{
15 Error,
16 ErrorKind,
17 Result,
18 },
19 pin::Pin,
20 task::{
21 Context,
22 Poll,
23 },
24};
25
26use qubit_io::{
27 AsyncBufferedInput,
28 AsyncInput,
29 Buffer,
30};
31use qubit_utils::{
32 SliceRange,
33 allocation_error,
34};
35
36use crate::{
37 CapacityError,
38 TranscodeProgress,
39 Transcoder,
40};
41
42use super::{
43 async_transcode_decode_step::AsyncTranscodeDecodeStep,
44 transcode_progress_validation::validate_decode_progress,
45};
46
47#[must_use]
56pub struct AsyncTranscodeDecodeInput<I>
57where
58 I: AsyncInput,
59 I::Item: Copy + Default,
60{
61 input: AsyncBufferedInput<I>,
63}
64
65impl<I> AsyncTranscodeDecodeInput<I>
66where
67 I: AsyncInput,
68 I::Item: Copy + Default,
69{
70 pub fn new(inner: I) -> Self {
80 Self {
81 input: AsyncBufferedInput::new(inner),
82 }
83 }
84
85 pub fn with_capacity(inner: I, capacity: usize) -> Self {
96 Self {
97 input: AsyncBufferedInput::with_capacity(inner, capacity),
98 }
99 }
100
101 pub fn try_with_capacity(
109 inner: I,
110 capacity: usize,
111 ) -> std::result::Result<Self, TryReserveError> {
112 Ok(Self {
113 input: AsyncBufferedInput::try_with_capacity(inner, capacity)?,
114 })
115 }
116
117 #[must_use]
122 pub const fn inner(&self) -> &I {
123 self.input.inner()
124 }
125
126 #[must_use]
131 pub fn inner_mut(&mut self) -> &mut I {
132 self.input.inner_mut()
133 }
134
135 #[must_use]
137 pub const fn unread_len(&self) -> usize {
138 self.input.unread_len()
139 }
140
141 #[must_use]
143 pub fn unread(&self) -> &[I::Item] {
144 self.input.unread()
145 }
146
147 #[must_use]
149 pub fn capacity(&self) -> usize {
150 self.input.capacity()
151 }
152
153 pub fn consume(&mut self, count: usize) {
159 assert!(
160 count <= self.unread_len(),
161 "cannot consume beyond buffered input",
162 );
163 unsafe {
165 self.input.consume(count);
166 }
167 }
168
169 pub unsafe fn copy_unread_to(
177 &self,
178 output: &mut [I::Item],
179 output_index: usize,
180 count: usize,
181 ) {
182 unsafe {
184 self.input.copy_unread_to(output, output_index, count);
185 }
186 }
187
188 #[must_use = "the returned input and unread buffer must be handled"]
190 pub fn into_parts(self) -> (I, Buffer<I::Item>) {
191 self.input.into_parts()
192 }
193
194 pub fn reset<D, M, Value>(
204 &self,
205 decoder: &mut D,
206 map_error: &mut M,
207 output: &mut [Value],
208 output_index: usize,
209 count: usize,
210 ) -> Result<usize>
211 where
212 D: Transcoder<Input = I::Item, Output = Value>,
213 M: FnMut(D::Error) -> Error,
214 {
215 let required = decoder
216 .max_reset_output_len()
217 .map_err(capacity_to_io_error)?;
218 let output_end = SliceRange::checked_range_end(
219 output.len(),
220 output_index,
221 count,
222 "reset output range exceeds destination buffer",
223 )?;
224 if count < required {
225 return Err(Error::new(
226 ErrorKind::InvalidData,
227 "insufficient output for decoder reset bound",
228 ));
229 }
230 let output = &mut output[..output_end];
231 let written = decoder
232 .reset(output, output_index)
233 .map_err(&mut *map_error)?;
234 assert!(written <= required, "reset wrote beyond its bound");
235 Ok(written)
236 }
237
238 pub fn finish<D, M, Value>(
249 &self,
250 decoder: &mut D,
251 map_error: &mut M,
252 output: &mut [Value],
253 output_index: usize,
254 count: usize,
255 ) -> Result<usize>
256 where
257 D: Transcoder<Input = I::Item, Output = Value>,
258 M: FnMut(D::Error) -> Error,
259 {
260 let required = decoder
261 .max_finish_output_len()
262 .map_err(capacity_to_io_error)?;
263 let output_end = SliceRange::checked_range_end(
264 output.len(),
265 output_index,
266 count,
267 "finish output range exceeds destination buffer",
268 )?;
269 if count < required {
270 return Err(Error::new(
271 ErrorKind::InvalidData,
272 "insufficient output for decoder finish bound",
273 ));
274 }
275 let output = &mut output[..output_end];
276 let written = decoder
277 .finish(output, output_index)
278 .map_err(&mut *map_error)?;
279 assert!(written <= required, "finish wrote beyond its bound");
280 Ok(written)
281 }
282}
283
284impl<I> AsyncTranscodeDecodeInput<I>
285where
286 I: AsyncInput + Unpin,
287 I::Item: Copy + Default + Unpin,
288{
289 pub async fn fill_more_async(&mut self) -> Result<bool> {
299 self.input.fill_more_async().await
300 }
301
302 pub async fn fill_until_async(&mut self, count: usize) -> Result<bool> {
313 if count > self.input.capacity() {
314 self.input
315 .try_reserve_capacity(count)
316 .map_err(allocation_error)?;
317 }
318 self.input.fill_until_async(count).await
319 }
320
321 pub fn poll_transcode<D, M, Value>(
335 mut self: Pin<&mut Self>,
336 cx: &mut Context<'_>,
337 decoder: &mut D,
338 map_error: &mut M,
339 output: &mut [Value],
340 output_index: usize,
341 count: usize,
342 ) -> Poll<Result<AsyncTranscodeDecodeStep>>
343 where
344 D: Transcoder<Input = I::Item, Output = Value>,
345 M: FnMut(D::Error) -> Error,
346 {
347 let output_end = SliceRange::checked_range_end(
348 output.len(),
349 output_index,
350 count,
351 "decoded output range exceeds destination buffer",
352 )?;
353 if count == 0 {
354 return Poll::Ready(Ok(AsyncTranscodeDecodeStep::Progress(
355 TranscodeProgress::complete(0, 0),
356 )));
357 }
358 let output = &mut output[..output_end];
359 if self.as_ref().get_ref().unread_len() == 0 {
360 let this = self.as_mut().get_mut();
361 match Pin::new(&mut this.input).poll_fill_more(cx) {
362 Poll::Ready(Ok(true)) => {}
363 Poll::Ready(Ok(false)) => {
364 return Poll::Ready(Ok(
365 AsyncTranscodeDecodeStep::EndOfInput,
366 ));
367 }
368 Poll::Ready(Err(error)) => return Poll::Ready(Err(error)),
369 Poll::Pending => return Poll::Pending,
370 }
371 }
372 let this = self.as_mut().get_mut();
373 let available_input = this.unread_len();
374 let progress = decoder
375 .transcode(this.unread(), 0, output, output_index)
376 .map_err(&mut *map_error)
377 .and_then(|progress| {
378 validate_decode_progress(
379 progress,
380 0,
381 available_input,
382 output_index,
383 count,
384 )
385 });
386 let progress = match progress {
387 Ok(progress) => progress,
388 Err(error) => return Poll::Ready(Err(error)),
389 };
390 this.consume(progress.read());
391 Poll::Ready(Ok(AsyncTranscodeDecodeStep::Progress(progress)))
392 }
393
394 pub fn transcode_eof_step<D, M, Value>(
405 &mut self,
406 decoder: &mut D,
407 map_error: &mut M,
408 output: &mut [Value],
409 output_index: usize,
410 count: usize,
411 ) -> Result<TranscodeProgress>
412 where
413 D: Transcoder<Input = I::Item, Output = Value>,
414 M: FnMut(D::Error) -> Error,
415 {
416 let output_end = SliceRange::checked_range_end(
417 output.len(),
418 output_index,
419 count,
420 "decoded EOF output range exceeds destination buffer",
421 )?;
422 if count == 0 {
423 return Ok(TranscodeProgress::complete(0, 0));
424 }
425 if self.unread_len() == 0 {
426 return Ok(TranscodeProgress::complete(0, 0));
427 }
428 let available_input = self.unread_len();
429 let progress = decoder
430 .transcode_eof(
431 self.unread(),
432 0,
433 &mut output[..output_end],
434 output_index,
435 )
436 .map_err(&mut *map_error)
437 .and_then(|progress| {
438 validate_decode_progress(
439 progress,
440 0,
441 available_input,
442 output_index,
443 count,
444 )
445 })?;
446 self.consume(progress.read());
447 Ok(progress)
448 }
449
450 pub async fn transcode_async<D, M, Value>(
457 &mut self,
458 decoder: &mut D,
459 map_error: &mut M,
460 output: &mut [Value],
461 output_index: usize,
462 count: usize,
463 ) -> Result<AsyncTranscodeDecodeStep>
464 where
465 D: Transcoder<Input = I::Item, Output = Value>,
466 M: FnMut(D::Error) -> Error,
467 {
468 poll_fn(|cx| {
469 Pin::new(&mut *self).poll_transcode(
470 cx,
471 decoder,
472 map_error,
473 output,
474 output_index,
475 count,
476 )
477 })
478 .await
479 }
480}
481
482impl<I> AsyncInput for AsyncTranscodeDecodeInput<I>
483where
484 I: AsyncInput,
485 I::Item: Copy + Default,
486{
487 type Item = I::Item;
489
490 fn is_buffered(&self) -> bool {
492 true
493 }
494
495 unsafe fn poll_read_unchecked(
501 mut self: Pin<&mut Self>,
502 cx: &mut Context<'_>,
503 output: &mut [Self::Item],
504 index: usize,
505 count: usize,
506 ) -> Poll<Result<usize>> {
507 let input = unsafe {
509 Pin::new_unchecked(&mut self.as_mut().get_unchecked_mut().input)
510 };
511 unsafe { input.poll_read_unchecked(cx, output, index, count) }
513 }
514}
515
516impl<I> fmt::Debug for AsyncTranscodeDecodeInput<I>
517where
518 I: AsyncInput,
519 I::Item: Copy + Default,
520 AsyncBufferedInput<I>: fmt::Debug,
521{
522 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
524 formatter
525 .debug_struct("AsyncTranscodeDecodeInput")
526 .field("input", &self.input)
527 .finish()
528 }
529}
530
531fn capacity_to_io_error(error: CapacityError) -> Error {
533 Error::new(ErrorKind::InvalidData, error)
534}