mirror of
https://github.com/golang/go
synced 2024-11-25 06:57:58 -07:00
net/textproto: avoid 1 copy in ReadLine, ReadContinuedLine
Fixes #2083. R=msolo, bradfitz CC=golang-dev https://golang.org/cl/4812042
This commit is contained in:
parent
df07b6d14a
commit
27a3dcd0d2
@ -33,22 +33,25 @@ func NewReader(r *bufio.Reader) *Reader {
|
|||||||
// ReadLine reads a single line from r,
|
// ReadLine reads a single line from r,
|
||||||
// eliding the final \n or \r\n from the returned string.
|
// eliding the final \n or \r\n from the returned string.
|
||||||
func (r *Reader) ReadLine() (string, os.Error) {
|
func (r *Reader) ReadLine() (string, os.Error) {
|
||||||
line, err := r.ReadLineBytes()
|
line, err := r.readLineSlice()
|
||||||
return string(line), err
|
return string(line), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadLineBytes is like ReadLine but returns a []byte instead of a string.
|
// ReadLineBytes is like ReadLine but returns a []byte instead of a string.
|
||||||
func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
|
func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
|
||||||
r.closeDot()
|
line, err := r.readLineSlice()
|
||||||
line, err := r.R.ReadBytes('\n')
|
if line != nil {
|
||||||
n := len(line)
|
buf := make([]byte, len(line))
|
||||||
if n > 0 && line[n-1] == '\n' {
|
copy(buf, line)
|
||||||
n--
|
line = buf
|
||||||
if n > 0 && line[n-1] == '\r' {
|
|
||||||
n--
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return line[0:n], err
|
return line, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) readLineSlice() ([]byte, os.Error) {
|
||||||
|
r.closeDot()
|
||||||
|
line, _, err := r.R.ReadLine()
|
||||||
|
return line, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadContinuedLine reads a possibly continued line from r,
|
// ReadContinuedLine reads a possibly continued line from r,
|
||||||
@ -71,7 +74,7 @@ func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
|
|||||||
// A line consisting of only white space is never continued.
|
// A line consisting of only white space is never continued.
|
||||||
//
|
//
|
||||||
func (r *Reader) ReadContinuedLine() (string, os.Error) {
|
func (r *Reader) ReadContinuedLine() (string, os.Error) {
|
||||||
line, err := r.ReadContinuedLineBytes()
|
line, err := r.readContinuedLineSlice()
|
||||||
return string(line), err
|
return string(line), err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,8 +95,18 @@ func trim(s []byte) []byte {
|
|||||||
// ReadContinuedLineBytes is like ReadContinuedLine but
|
// ReadContinuedLineBytes is like ReadContinuedLine but
|
||||||
// returns a []byte instead of a string.
|
// returns a []byte instead of a string.
|
||||||
func (r *Reader) ReadContinuedLineBytes() ([]byte, os.Error) {
|
func (r *Reader) ReadContinuedLineBytes() ([]byte, os.Error) {
|
||||||
|
line, err := r.readContinuedLineSlice()
|
||||||
|
if line != nil {
|
||||||
|
buf := make([]byte, len(line))
|
||||||
|
copy(buf, line)
|
||||||
|
line = buf
|
||||||
|
}
|
||||||
|
return line, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reader) readContinuedLineSlice() ([]byte, os.Error) {
|
||||||
// Read the first line.
|
// Read the first line.
|
||||||
line, err := r.ReadLineBytes()
|
line, err := r.readLineSlice()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return line, err
|
return line, err
|
||||||
}
|
}
|
||||||
@ -127,8 +140,11 @@ func (r *Reader) ReadContinuedLineBytes() ([]byte, os.Error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// copy now since the next call to read a slice invalidates line
|
||||||
|
line = append(make([]byte, 0, len(line)*2), line...)
|
||||||
|
|
||||||
var cont []byte
|
var cont []byte
|
||||||
cont, err = r.ReadLineBytes()
|
cont, err = r.readLineSlice()
|
||||||
cont = trim(cont)
|
cont = trim(cont)
|
||||||
line = append(line, ' ')
|
line = append(line, ' ')
|
||||||
line = append(line, cont...)
|
line = append(line, cont...)
|
||||||
@ -422,7 +438,7 @@ func (r *Reader) ReadDotLines() ([]string, os.Error) {
|
|||||||
func (r *Reader) ReadMIMEHeader() (MIMEHeader, os.Error) {
|
func (r *Reader) ReadMIMEHeader() (MIMEHeader, os.Error) {
|
||||||
m := make(MIMEHeader)
|
m := make(MIMEHeader)
|
||||||
for {
|
for {
|
||||||
kv, err := r.ReadContinuedLineBytes()
|
kv, err := r.readContinuedLineSlice()
|
||||||
if len(kv) == 0 {
|
if len(kv) == 0 {
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user