Also, see this https://stackoverflow.com/questions/69753478/use-base64-stdencoding-or-base64-rawstdencoding-to-decode-base64-string-in-go as I expected the error should be reported earlier than the end of stream if the chosen format is wrong.
> On Jan 12, 2025, at 2:57 PM, robert engels <reng...@ix.netcom.com> wrote: > > Also, this is what Gemini provided which looks basically correct - but I > think encapsulating it with a Rewind() method would be easier to understand. > > > > While Go doesn't have a built-in PushbackReader like some other languages > (e.g., Java), you can implement similar functionality using a custom struct > and a buffer. > > Here's an example implementation: > > package main > > import ( > "bytes" > "io" > ) > > type PushbackReader struct { > reader io.Reader > buffer *bytes.Buffer > } > > func NewPushbackReader(r io.Reader) *PushbackReader { > return &PushbackReader{ > reader: r, > buffer: new(bytes.Buffer), > } > } > > func (p *PushbackReader) Read(b []byte) (n int, err error) { > if p.buffer.Len() > 0 { > return p.buffer.Read(b) > } > return p.reader.Read(b) > } > > func (p *PushbackReader) UnreadByte() error { > if p.buffer.Len() == 0 { > return io.EOF > } > lastByte := p.buffer.Bytes()[p.buffer.Len()-1] > p.buffer.Truncate(p.buffer.Len() - 1) > p.buffer.WriteByte(lastByte) > return nil > } > > func (p *PushbackReader) Unread(buf []byte) error { > if p.buffer.Len() == 0 { > return io.EOF > } > p.buffer.Write(buf) > return nil > } > > func main() { > // Example usage > r := NewPushbackReader(bytes.NewBufferString("Hello, World!")) > buf := make([]byte, 5) > r.Read(buf) > r.UnreadByte() > r.Read(buf) > } > > Explanation: > PushbackReader struct: This struct holds the underlying io.Reader and a > buffer to store the pushed-back bytes. > NewPushbackReader: This function creates a new PushbackReader from an > existing io.Reader. > Read method: This method reads bytes from either the buffer (if it contains > data) or the underlying reader. > UnreadByte method: This method pushes back a single byte into the buffer. > Unread method: This method pushes back a slice of bytes into the buffer. > Important Considerations: > The buffer size is not managed automatically. You may need to adjust the > buffer size based on your use case. > This implementation does not handle pushing back beyond the initially read > data. If you need to support arbitrary pushback, you'll need a more complex > solution. > > Generative AI is experimental. > >> On Jan 12, 2025, at 2:53 PM, Robert Engels <reng...@ix.netcom.com> wrote: >> >> You can see the two pass reader here >> https://stackoverflow.com/questions/20666594/how-can-i-push-bytes-into-a-reader-in-go >> >> But yea, the basic premise is that you buffer the data so you can rewind if >> needed >> >> Are you certain it is reading to the end to return EOF? It may be returning >> eof once the parsing fails. >> >> Otherwise I would expect this is being decoded wrong - eg the mime type or >> encoding type should tell you the correct format before you start decoding. >> >>> On Jan 12, 2025, at 2:46 PM, Rory Campbell-Lange <r...@campbell-lange.net> >>> wrote: >>> >>> Thanks for the suggestion of a ReadSeeker to wrap an io.Reader. >>> >>> My google fu must be deserting me. I can find PushbackReader >>> implementations in Java, but the only similar thing for Go I could find was >>> https://gitlab.com/osaki-lab/iowrapper. If you have a specific >>> recommendation for a ReadSeeker wrapper to an io.Reader that would be great >>> to know. >>> >>> Since the base64 decoding error I'm looking for is an EOF, I guess the >>> wrapper approach will not work when the EOF byte position is > than the >>> io.ReadSeeker buffer size. >>> >>> Rory >>> >>> On 12/01/25, robert engels (reng...@ix.netcom.com) wrote: >>>> create a ReadSeeker that wraps the Reader providing the buffering (mark & >>>> reset) - normally the buffer only needs to be large enough to detect the >>>> format contained in the Reader. >>>> >>>> You can search Google for PushbackReader in Go and you’ll get a basic >>>> implementation. >>>> >>>>> On Jan 12, 2025, at 12:52 PM, Rory Campbell-Lange >>>>> <r...@campbell-lange.net> wrote: >>> ... >>>>> I'm attempting to rationalise the process [of avoiding reading email >>>>> parts into byte slices] 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. >>>>> >> >> >> -- >> 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 golang-nuts+unsubscr...@googlegroups.com >> <mailto:golang-nuts+unsubscr...@googlegroups.com>. >> To view this discussion visit >> https://groups.google.com/d/msgid/golang-nuts/DD0C1480-D237-447A-B978-78FC8951FE05%40ix.netcom.com >> >> <https://groups.google.com/d/msgid/golang-nuts/DD0C1480-D237-447A-B978-78FC8951FE05%40ix.netcom.com?utm_medium=email&utm_source=footer>. > -- 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 golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/91D0EDE1-F519-4F8D-A544-958BE8D3FEB3%40ix.netcom.com.