MCPcopy Create free account
hub / github.com/imroc/req / readContinuedLineSlice

Method readContinuedLineSlice

textproto_reader.go:124–176  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

122// error is returned from readContinuedLineSlice.
123// It reads up to lim bytes of data (or unlimited if lim is less than 0).
124func (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.
179func (r *textprotoReader) skipSpace() int {

Callers 1

readMIMEHeaderMethod · 0.95

Calls 5

readLineSliceMethod · 0.95
skipSpaceMethod · 0.95
isASCIILetterFunction · 0.85
trimFunction · 0.85
ErrorfMethod · 0.65

Tested by

no test coverage detected