readContinuedLineSlice reads continued lines from the reader buffer, returning a byte slice with all lines. The validateFirstLine function is run on the first read line, and if it returns an error then this error is returned from readContinuedLineSlice. It reads up to lim bytes of data (or unlimited
(lim int64, validateFirstLine func([]byte) error)
| 122 | // error is returned from readContinuedLineSlice. |
| 123 | // It reads up to lim bytes of data (or unlimited if lim is less than 0). |
| 124 | func (r *textprotoReader) readContinuedLineSlice(lim int64, validateFirstLine func([]byte) error) ([]byte, error) { |
| 125 | if validateFirstLine == nil { |
| 126 | return nil, fmt.Errorf("missing validateFirstLine func") |
| 127 | } |
| 128 | |
| 129 | // Read the first line. |
| 130 | line, err := r.readLineSlice(lim) |
| 131 | if err != nil { |
| 132 | return nil, err |
| 133 | } |
| 134 | if len(line) == 0 { // blank line - no continuation |
| 135 | return line, nil |
| 136 | } |
| 137 | |
| 138 | if err := validateFirstLine(line); err != nil { |
| 139 | return nil, err |
| 140 | } |
| 141 | |
| 142 | // Optimistically assume that we have started to buffer the next line |
| 143 | // and it starts with an ASCII letter (the next header key), or a blank |
| 144 | // line, so we can avoid copying that buffered data around in memory |
| 145 | // and skipping over non-existent whitespace. |
| 146 | if r.R.Buffered() > 1 { |
| 147 | peek, _ := r.R.Peek(2) |
| 148 | if len(peek) > 0 && (isASCIILetter(peek[0]) || peek[0] == '\n') || |
| 149 | len(peek) == 2 && peek[0] == '\r' && peek[1] == '\n' { |
| 150 | return trim(line), nil |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | // ReadByte or the next readLineSlice will flush the read buffer; |
| 155 | // copy the slice into buf. |
| 156 | r.buf = append(r.buf[:0], trim(line)...) |
| 157 | |
| 158 | if lim < 0 { |
| 159 | lim = math.MaxInt64 |
| 160 | } |
| 161 | lim -= int64(len(r.buf)) |
| 162 | |
| 163 | // Read continuation lines. |
| 164 | for r.skipSpace() > 0 { |
| 165 | r.buf = append(r.buf, ' ') |
| 166 | if int64(len(r.buf)) >= lim { |
| 167 | return nil, errMessageTooLarge |
| 168 | } |
| 169 | line, err := r.readLineSlice(lim - int64(len(r.buf))) |
| 170 | if err != nil { |
| 171 | break |
| 172 | } |
| 173 | r.buf = append(r.buf, trim(line)...) |
| 174 | } |
| 175 | return r.buf, nil |
| 176 | } |
| 177 | |
| 178 | // skipSpace skips R over all spaces and returns the number of bytes skipped. |
| 179 | func (r *textprotoReader) skipSpace() int { |
no test coverage detected