> I'm looking to develop an alternative to an existing piece of code that
reads email parts into byte slices and then returns these after decoding
Aside: are you actually seeing invalid (unpadded) base64-encoded MIME parts
in the wild?
Since a padded base64-encoded block will always be a multiple of 4
characters (excluding whitespace) I guess you could make a reader which
counts these as it goes; if it sees EOF when N%4 is 2 or 3, it adds 2 or 1
"=" characters respectively. (N%4 == 1 can never occur unless the base64
stream is corrupt).
On Sunday, 12 January 2025 at 18:53:29 UTC Rory Campbell-Lange wrote:
> I'm looking to develop an alternative to an existing piece of code that
> reads email parts into byte slices and then returns these after decoding.
>
> As library users may not wish to use these email parts and because there a
> multiple byte slice copies being used, I'm attempting to rationalise the
> process by simply wrapping the provided io.Reader with the necessary
> decoders to reduce memory usage and unnecessary processing.
>
> The wrapping strategy seems to work ok. However there is a particular
> issue in detecting base64.StdEncoding versus base64.RawStdEncoding, which
> requires draining the io.Reader using base64.StdEncoding and (based on the
> current implementation) switching to base64.RawStdEncoding if an
> io.ErrUnexpectedEOF is found.
>
> I'd be grateful for any thoughts on the most efficient way of dealing with
> this type of issue, avoiding the need for lots of in-memory copies of --
> say -- a 50MB email attachment. Unfortunately neither net/mail.Message.Body
> or mime/multipart.Part, which provide the input to this func, provide
> ReadSeekers.
>
> Code snippet below.
>
> Thanks!
> Rory
>
>
> // decodeContent wraps the content io.Reader in either a base64 or
> // quoted printable decoder if applicable. It further wraps the reader
> // in a transform character decoder if an encoding is supplied.
> func decodeContent(content io.Reader, e encoding.Encoding, cte
> ContentTransferEncoding) io.Reader {
>
> var contentReader io.Reader
>
> switch cte {
> case cteBase64:
>
> contentReader = base64.NewDecoder(base64.StdEncoding, content)
> // ideally check for errors.Is(err, io.ErrUnexpectedEOF); switch decoder to
> // contentReader = base64.NewDecoder(base64.RawStdEncoding, content)
>
> case cteQuotedPrintable:
> contentReader = quotedprintable.NewReader(content)
> default:
> contentReader = content
> }
>
> if e == nil {
> return contentReader
> }
> return transform.NewReader(contentReader, e.NewDecoder())
> }
>
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/golang-nuts/ff7ff2f2-8838-4620-a518-f06a95e4e302n%40googlegroups.com.