ReadAll reads from r until an error or EOF and returns the data it read. A successful call returns err == nil, not err == EOF. Because ReadAll is defined to read from src until EOF, it does not treat an EOF from Read as an error to be reported. Important: A failed call returns a non-nil error and m
(r io.Reader, pool BufferPool)
| 247 | // partially read buffers. It is the responsibility of the caller to free the |
| 248 | // BufferSlice returned, or its memory will not be reused. |
| 249 | func ReadAll(r io.Reader, pool BufferPool) (BufferSlice, error) { |
| 250 | var result BufferSlice |
| 251 | if wt, ok := r.(io.WriterTo); ok { |
| 252 | // This is more optimal since wt knows the size of chunks it wants to |
| 253 | // write and, hence, we can allocate buffers of an optimal size to fit |
| 254 | // them. E.g. might be a single big chunk, and we wouldn't chop it |
| 255 | // into pieces. |
| 256 | w := NewWriter(&result, pool) |
| 257 | _, err := wt.WriteTo(w) |
| 258 | return result, err |
| 259 | } |
| 260 | nextBuffer: |
| 261 | for { |
| 262 | buf := pool.Get(readAllBufSize) |
| 263 | // We asked for 32KiB but may have been given a bigger buffer. |
| 264 | // Use all of it if that's the case. |
| 265 | *buf = (*buf)[:cap(*buf)] |
| 266 | usedCap := 0 |
| 267 | for { |
| 268 | n, err := r.Read((*buf)[usedCap:]) |
| 269 | usedCap += n |
| 270 | if err != nil { |
| 271 | if usedCap == 0 { |
| 272 | // Nothing in this buf, put it back |
| 273 | pool.Put(buf) |
| 274 | } else { |
| 275 | *buf = (*buf)[:usedCap] |
| 276 | result = append(result, NewBuffer(buf, pool)) |
| 277 | } |
| 278 | if err == io.EOF { |
| 279 | err = nil |
| 280 | } |
| 281 | return result, err |
| 282 | } |
| 283 | if len(*buf) == usedCap { |
| 284 | result = append(result, NewBuffer(buf, pool)) |
| 285 | continue nextBuffer |
| 286 | } |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | // Discard skips the next n bytes, returning the number of bytes discarded. |
| 292 | // |