57 lines
934 B
Go

package utf8reader
import (
"bytes"
"errors"
"io"
"unicode/utf8"
)
var SmallBufferError = errors.New("Buffer size must be larger than utf8.UTFMax.")
type UTF8Reader struct {
reader io.Reader
buffer *bytes.Buffer
}
func New(reader io.Reader) *UTF8Reader {
return &UTF8Reader{
reader: reader,
buffer: bytes.NewBuffer(make([]byte, 0)),
}
}
func (r *UTF8Reader) Read(p []byte) (n int, err error) {
size := 0
if cap(p) < utf8.UTFMax {
return size, SmallBufferError
}
if r.buffer.Len() > 0 {
n, err = r.buffer.Read(p)
size += n
if err != nil {
return size, err
}
}
n, err = r.reader.Read(p[size:])
size += n
if err != nil {
return size, err
}
leftOver := 0
for ; leftOver < utf8.UTFMax && size-leftOver > 0; leftOver++ {
rune, _ := utf8.DecodeLastRune(p[:size-leftOver])
if rune != utf8.RuneError {
break
}
}
r.buffer.Write(p[size-leftOver : size])
return size - leftOver, nil
}