// ReadLine reads a single line from r,
// eliding the final \n or \r\n from the returned string.
func (r *Reader) ReadLine() (string, os.Error) {
- line, err := r.ReadLineBytes()
+ line, err := r.readLineSlice()
return string(line), err
}
// ReadLineBytes is like ReadLine but returns a []byte instead of a string.
func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
- r.closeDot()
- line, err := r.R.ReadBytes('\n')
- n := len(line)
- if n > 0 && line[n-1] == '\n' {
- n--
- if n > 0 && line[n-1] == '\r' {
- n--
- }
+ line, err := r.readLineSlice()
+ if line != nil {
+ buf := make([]byte, len(line))
+ copy(buf, line)
+ line = buf
}
- 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,
// A line consisting of only white space is never continued.
//
func (r *Reader) ReadContinuedLine() (string, os.Error) {
- line, err := r.ReadContinuedLineBytes()
+ line, err := r.readContinuedLineSlice()
return string(line), err
}
// ReadContinuedLineBytes is like ReadContinuedLine but
// returns a []byte instead of a string.
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.
- line, err := r.ReadLineBytes()
+ line, err := r.readLineSlice()
if err != nil {
return line, err
}
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
- cont, err = r.ReadLineBytes()
+ cont, err = r.readLineSlice()
cont = trim(cont)
line = append(line, ' ')
line = append(line, cont...)
func (r *Reader) ReadMIMEHeader() (MIMEHeader, os.Error) {
m := make(MIMEHeader)
for {
- kv, err := r.ReadContinuedLineBytes()
+ kv, err := r.readContinuedLineSlice()
if len(kv) == 0 {
return m, err
}