We have a case where we need to peek certain amount of incoming characters. The length for which is not fixed. bufio.Reader.Peek can only peek up to the maximum size of its initialized buffer. Any attempt to Peek larger results in ErrBufferFull
Problem:
package main
import (
"bufio"
"fmt"
"strings"
)
func main() {
data := "In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content."
dataLen := len([]rune(data))
fmt.Printf("Length of data: %d\n", dataLen)
r := bufio.NewReaderSize(strings.NewReader(data), 16)
bufferSize := r.Size()
fmt.Printf("buffer size: %d\n", bufferSize)
GetPeekedCharacters(r, dataLen)
}
func GetPeekedCharacters(r *bufio.Reader, dataLen int) {
b, err := r.Peek(dataLen)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("peeked: %s\n", b)
}
}
I have been trying to see if we could maybe kind of swap the Peek with our own implementation but we require the internal fields of bufio.Reader like buf/r/w
// Reader implements buffering for an io.Reader object.
type Reader struct {
buf []byte
rd io.Reader // reader provided by the client
r, w int // buf read and write positions
err error
lastByte int // last byte read for UnreadByte; -1 means invalid
lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}
My approaches:
package main
import (
"fmt"
"strings"
"mybufio/mybufio"
)
func main() {
rd := mybufio.NewMyBufio(strings.NewReader("In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content."), 16)
if _, err := rd.Peek(179); err != nil {
fmt.Printf("Got error in Peek: %s\n", err)
}
}
-- go.mod --
module mybufio
-- mybufio/mybufio.go --
package mybufio
import (
"bufio"
"io"
)
type MyReader interface {
Peek(n int) ([]byte, error)
}
type MyBufio struct {
*bufio.Reader
}
func NewMyBufio(rd io.Reader, size int) *MyBufio {
return &MyBufio{bufio.NewReaderSize(rd, size)}
}
func (b *MyBufio) Peek(n int) ([]byte, error) {
// inaccessible b.buf
// comment below to run program
fmt.Println(b.buf)
return []byte{}, nil
}
I am new to go and not sure how to achieve this. Any pointers would be helpful.