package bufio import ( "bytes" "io" "log" ) var ( ReadBufferSize = 1024 ) func DelimRemove(data, delim []byte) []byte { if bytes.HasSuffix(data, delim) { data = data[:len(data)-len(delim)+1] } return data } func NewReader(r io.Reader) *Reader { return &Reader{ r: r, } } type Reader struct { r io.Reader buf bytes.Buffer seek int } func (s *Reader) fromBuf(data []byte) (res []byte) { if s.buf.Len() > 0 { res = append(s.buf.Bytes(), data...) s.buf.Reset() s.seek = 0 } else { res = data } return } func (s *Reader) toBuf(data []byte) { s.seek = s.buf.Len() s.buf.Write(data) } func (s *Reader) scanBuf(delim []byte) (res []byte, check bool) { buf := s.buf.Bytes()[s.seek:] if index := bytes.Index(buf, delim); index >= 0 { rSize := s.seek + index + len(delim) check, res = true, make([]byte, rSize) s.buf.Read(res) s.seek = 0 } else { s.seek = s.buf.Len() } return } func (s *Reader) scanNeeded() bool { return s.seek < s.buf.Len() } func (s *Reader) readBufferSize(delim []byte) int { if ReadBufferSize >= len(delim) { return ReadBufferSize } return len(delim) } func (s *Reader) ReadBytes(delim []byte) (res []byte, err error) { var check bool // scan internal buffer if s.scanNeeded() { log.Println("NEEDED") if res, check = s.scanBuf(delim); check { return } } // read from external buffer buf, count := make([]byte, s.readBufferSize(delim)), 0 for { if count, err = s.r.Read(buf); count > 0 { s.buf.Write(buf[:count]) for s.scanNeeded() { if res, check = s.scanBuf(delim); check { return } } } if err != nil { if err == io.EOF && s.buf.Len() > 0 { res, check = s.buf.Bytes(), true s.buf.Reset() } return } } }