92 lines
1.4 KiB
Go
92 lines
1.4 KiB
Go
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
|
|
}
|