package proxy import ( "bytes" "io" ) func min(a int, b int) int { if a < b { return a } return b } type UReader struct { io io.Reader buf []byte r, w int err error } func NewReader(io io.Reader) *UReader { return &UReader{ io: io, buf: make([]byte, 4096), r: 0, w: 0, } } func (b *UReader) Read(data []byte, s int, e int) (int, error) { n := e - s rn := 0 for rn < n { d := min(b.w-b.r, n-rn) if d > 0 { copy(data[s+rn:s+rn+d], b.buf[b.r:b.r+d]) b.r += d rn += d if rn >= n { break } } err := b.fill() if err != nil { return rn, err } } return rn, nil } func (b *UReader) ReadLine() ([]byte, error) { line, err := b.ReadSlice('\n') return line, err } func (b *UReader) ReadSlice(delim byte) ([]byte, error) { s := 0 // search start index for { // Search buffer. if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 { i += s + 1 b.r += i return b.buf[b.r-i : b.r], nil } err := b.fill() if err != nil { return b.buf[b.r:], err } } } func (b *UReader) fill() error { d := b.w - b.r if d >= len(b.buf) { b.r = 0 b.w = 0 return ErrBufferFull } // Slide existing data to beginning. if b.r > 0 { copy(b.buf, b.buf[b.r:b.w]) b.w -= b.r b.r = 0 } // Read new data: try a limited number of times. n, err := b.io.Read(b.buf[b.w:]) b.w += n return err } func (b *UReader) Clear() { b.r = 0 b.w = 0 }