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.

Reply via email to