From 1c6d97565a77133ed865ff12a521ebb6e5b90caa Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 15 Aug 2021 18:51:45 +0100 Subject: [PATCH] multipart: wip ComponentIterator Signed-off-by: Ian Jackson --- src/multipart.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/multipart.rs b/src/multipart.rs index b076458..08570a3 100644 --- a/src/multipart.rs +++ b/src/multipart.rs @@ -80,6 +80,59 @@ pub fn process_boundary<'b>(warnings: &mut Warnings, Some(Component { name: part_name.unwrap_or(expected), payload: rhs }) } +pub struct ComponentIterator<'b> { + at_boundary: &'b [u8], + boundary_finder: BoundaryFinder, +} + +#[derive(Error,Debug)] +#[error("missing mime multipart boundary")] +pub struct MissingBoundary; + +impl<'b> ComponentIterator<'b> { + #[throws(MissingBoundary)] + pub fn resume_mid_component(buf: &'b [u8], boundary_finder: BoundaryFinder) + -> (&'b [u8], Self) { + let next_boundary = boundary_finder.find(buf).ok_or(MissingBoundary)?; + let part = &buf[0..next_boundary]; + let part = Self::payload_trim(part); + (part, ComponentIterator { + at_boundary: &buf[next_boundary..], + boundary_finder, + }) + } + + fn payload_trim(payload: &[u8]) -> &[u8] { + payload.strip_suffix(b"\r").unwrap_or(payload) + } + + #[throws(AE)] + pub fn next(&mut self, warnings: &mut Warnings, expected: PartName) + -> Option> { + if self.at_boundary.is_empty() { return None } + + let mut comp = match { + let boundary_len = self.boundary_finder.needle().len(); + process_boundary(warnings, + &self.at_boundary[boundary_len..], + expected)? + } { + None => { + self.at_boundary = &self.at_boundary[0..0]; + return None; + }, + Some(c) => c, + }; + + let next_boundary = self.boundary_finder.find(&comp.payload) + .ok_or(MissingBoundary)?; + + comp.payload = Self::payload_trim(&comp.payload[0..next_boundary]); + self.at_boundary = &self.at_boundary[next_boundary..]; + Some(comp) + } +} + pub struct MetadataFieldIterator<'b> { buf: &'b [u8], last: Option, -- 2.30.2