Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(20)

Delta Between Two Patch Sets: src/pkg/io/io.go

Issue 5311068: code review 5311068: io: use error, add EOF, avoid os (Closed)
Left Patch Set: Created 13 years, 4 months ago
Right Patch Set: diff -r 8f0f154fb94d https://go.googlecode.com/hg/ Created 13 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/io/io_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package io provides basic interfaces to I/O primitives. 5 // Package io provides basic interfaces to I/O primitives.
6 // Its primary job is to wrap existing implementations of such primitives, 6 // Its primary job is to wrap existing implementations of such primitives,
7 // such as those in package os, into shared public interfaces that 7 // such as those in package os, into shared public interfaces that
8 // abstract the functionality, plus some other related primitives. 8 // abstract the functionality, plus some other related primitives.
9 package io 9 package io
10 10
11 import "os"
12
13 // Error represents an unexpected I/O behavior. 11 // Error represents an unexpected I/O behavior.
14 type Error struct { 12 type Error struct {
15 ErrorString string 13 ErrorString string
16 } 14 }
17 15
18 func (err *Error) String() string { return err.ErrorString } 16 func (err *Error) Error() string { return err.ErrorString }
19 17
20 // ErrShortWrite means that a write accepted fewer bytes than requested 18 // ErrShortWrite means that a write accepted fewer bytes than requested
21 // but failed to return an explicit error. 19 // but failed to return an explicit error.
22 var ErrShortWrite os.Error = &Error{"short write"} 20 var ErrShortWrite error = &Error{"short write"}
23 21
24 // ErrShortBuffer means that a read required a longer buffer than was provided. 22 // ErrShortBuffer means that a read required a longer buffer than was provided.
25 var ErrShortBuffer os.Error = &Error{"short buffer"} 23 var ErrShortBuffer error = &Error{"short buffer"}
26 24
27 // ErrUnexpectedEOF means that os.EOF was encountered in the 25 // EOF is the error returned by Read when no more input is available.
26 // Functions should return EOF only to signal a graceful end of input.
27 // If the EOF occurs unexpectedly in a structured data stream,
28 // the appropriate error is either ErrUnexpectedEOF or some other error
29 // giving more detail.
30 var EOF error = &Error{"EOF"}
31
32 // ErrUnexpectedEOF means that EOF was encountered in the
28 // middle of reading a fixed-size block or data structure. 33 // middle of reading a fixed-size block or data structure.
29 var ErrUnexpectedEOF os.Error = &Error{"unexpected EOF"} 34 var ErrUnexpectedEOF error = &Error{"unexpected EOF"}
30 35
31 // Reader is the interface that wraps the basic Read method. 36 // Reader is the interface that wraps the basic Read method.
32 // 37 //
33 // Read reads up to len(p) bytes into p. It returns the number of bytes 38 // Read reads up to len(p) bytes into p. It returns the number of bytes
34 // read (0 <= n <= len(p)) and any error encountered. Even if Read 39 // read (0 <= n <= len(p)) and any error encountered. Even if Read
35 // returns n < len(p), it may use all of p as scratch space during the call. 40 // returns n < len(p), it may use all of p as scratch space during the call.
36 // If some data is available but not len(p) bytes, Read conventionally 41 // If some data is available but not len(p) bytes, Read conventionally
37 // returns what is available instead of waiting for more. 42 // returns what is available instead of waiting for more.
38 // 43 //
39 // When Read encounters an error or end-of-file condition after 44 // When Read encounters an error or end-of-file condition after
40 // successfully reading n > 0 bytes, it returns the number of 45 // successfully reading n > 0 bytes, it returns the number of
41 // bytes read. It may return the (non-nil) error from the same call 46 // bytes read. It may return the (non-nil) error from the same call
42 // or return the error (and n == 0) from a subsequent call. 47 // or return the error (and n == 0) from a subsequent call.
43 // An instance of this general case is that a Reader returning 48 // An instance of this general case is that a Reader returning
44 // a non-zero number of bytes at the end of the input stream may 49 // a non-zero number of bytes at the end of the input stream may
45 // return either err == os.EOF or err == nil. The next Read should 50 // return either err == EOF or err == nil. The next Read should
46 // return 0, os.EOF regardless. 51 // return 0, EOF regardless.
47 // 52 //
48 // Callers should always process the n > 0 bytes returned before 53 // Callers should always process the n > 0 bytes returned before
49 // considering the error err. Doing so correctly handles I/O errors 54 // considering the error err. Doing so correctly handles I/O errors
50 // that happen after reading some bytes and also both of the 55 // that happen after reading some bytes and also both of the
51 // allowed EOF behaviors. 56 // allowed EOF behaviors.
52 type Reader interface { 57 type Reader interface {
53 » Read(p []byte) (n int, err os.Error) 58 » Read(p []byte) (n int, err error)
54 } 59 }
55 60
56 // Writer is the interface that wraps the basic Write method. 61 // Writer is the interface that wraps the basic Write method.
57 // 62 //
58 // Write writes len(p) bytes from p to the underlying data stream. 63 // Write writes len(p) bytes from p to the underlying data stream.
59 // It returns the number of bytes written from p (0 <= n <= len(p)) 64 // It returns the number of bytes written from p (0 <= n <= len(p))
60 // and any error encountered that caused the write to stop early. 65 // and any error encountered that caused the write to stop early.
61 // Write must return a non-nil error if it returns n < len(p). 66 // Write must return a non-nil error if it returns n < len(p).
62 type Writer interface { 67 type Writer interface {
63 » Write(p []byte) (n int, err os.Error) 68 » Write(p []byte) (n int, err error)
64 } 69 }
65 70
66 // Closer is the interface that wraps the basic Close method. 71 // Closer is the interface that wraps the basic Close method.
67 type Closer interface { 72 type Closer interface {
68 » Close() os.Error 73 » Close() error
69 } 74 }
70 75
71 // Seeker is the interface that wraps the basic Seek method. 76 // Seeker is the interface that wraps the basic Seek method.
72 // 77 //
73 // Seek sets the offset for the next Read or Write to offset, 78 // Seek sets the offset for the next Read or Write to offset,
74 // interpreted according to whence: 0 means relative to the origin of 79 // interpreted according to whence: 0 means relative to the origin of
75 // the file, 1 means relative to the current offset, and 2 means 80 // the file, 1 means relative to the current offset, and 2 means
76 // relative to the end. Seek returns the new offset and an Error, if 81 // relative to the end. Seek returns the new offset and an Error, if
77 // any. 82 // any.
78 type Seeker interface { 83 type Seeker interface {
79 » Seek(offset int64, whence int) (ret int64, err os.Error) 84 » Seek(offset int64, whence int) (ret int64, err error)
80 } 85 }
81 86
82 // ReadWriter is the interface that groups the basic Read and Write methods. 87 // ReadWriter is the interface that groups the basic Read and Write methods.
83 type ReadWriter interface { 88 type ReadWriter interface {
84 Reader 89 Reader
85 Writer 90 Writer
86 } 91 }
87 92
88 // ReadCloser is the interface that groups the basic Read and Close methods. 93 // ReadCloser is the interface that groups the basic Read and Close methods.
89 type ReadCloser interface { 94 type ReadCloser interface {
(...skipping 28 matching lines...) Expand all
118 123
119 // ReadWriteSeeker is the interface that groups the basic Read, Write and Seek m ethods. 124 // ReadWriteSeeker is the interface that groups the basic Read, Write and Seek m ethods.
120 type ReadWriteSeeker interface { 125 type ReadWriteSeeker interface {
121 Reader 126 Reader
122 Writer 127 Writer
123 Seeker 128 Seeker
124 } 129 }
125 130
126 // ReaderFrom is the interface that wraps the ReadFrom method. 131 // ReaderFrom is the interface that wraps the ReadFrom method.
127 type ReaderFrom interface { 132 type ReaderFrom interface {
128 » ReadFrom(r Reader) (n int64, err os.Error) 133 » ReadFrom(r Reader) (n int64, err error)
129 } 134 }
130 135
131 // WriterTo is the interface that wraps the WriteTo method. 136 // WriterTo is the interface that wraps the WriteTo method.
132 type WriterTo interface { 137 type WriterTo interface {
133 » WriteTo(w Writer) (n int64, err os.Error) 138 » WriteTo(w Writer) (n int64, err error)
134 } 139 }
135 140
136 // ReaderAt is the interface that wraps the basic ReadAt method. 141 // ReaderAt is the interface that wraps the basic ReadAt method.
137 // 142 //
138 // ReadAt reads len(p) bytes into p starting at offset off in the 143 // ReadAt reads len(p) bytes into p starting at offset off in the
139 // underlying input source. It returns the number of bytes 144 // underlying input source. It returns the number of bytes
140 // read (0 <= n <= len(p)) and any error encountered. 145 // read (0 <= n <= len(p)) and any error encountered.
141 // 146 //
142 // When ReadAt returns n < len(p), it returns a non-nil error 147 // When ReadAt returns n < len(p), it returns a non-nil error
143 // explaining why more bytes were not returned. In this respect, 148 // explaining why more bytes were not returned. In this respect,
144 // ReadAt is stricter than Read. 149 // ReadAt is stricter than Read.
145 // 150 //
146 // Even if ReadAt returns n < len(p), it may use all of p as scratch 151 // Even if ReadAt returns n < len(p), it may use all of p as scratch
147 // space during the call. If some data is available but not len(p) bytes, 152 // space during the call. If some data is available but not len(p) bytes,
148 // ReadAt blocks until either all the data is available or an error occurs. 153 // ReadAt blocks until either all the data is available or an error occurs.
149 // In this respect ReadAt is different from Read. 154 // In this respect ReadAt is different from Read.
150 // 155 //
151 // If the n = len(p) bytes returned by ReadAt are at the end of the 156 // If the n = len(p) bytes returned by ReadAt are at the end of the
152 // input source, ReadAt may return either err == os.EOF or err == nil. 157 // input source, ReadAt may return either err == EOF or err == nil.
153 // 158 //
154 // If ReadAt is reading from an input source with a seek offset, 159 // If ReadAt is reading from an input source with a seek offset,
155 // ReadAt should not affect nor be affected by the underlying 160 // ReadAt should not affect nor be affected by the underlying
156 // seek offset. 161 // seek offset.
157 type ReaderAt interface { 162 type ReaderAt interface {
158 » ReadAt(p []byte, off int64) (n int, err os.Error) 163 » ReadAt(p []byte, off int64) (n int, err error)
159 } 164 }
160 165
161 // WriterAt is the interface that wraps the basic WriteAt method. 166 // WriterAt is the interface that wraps the basic WriteAt method.
162 // 167 //
163 // WriteAt writes len(p) bytes from p to the underlying data stream 168 // WriteAt writes len(p) bytes from p to the underlying data stream
164 // at offset off. It returns the number of bytes written from p (0 <= n <= len( p)) 169 // at offset off. It returns the number of bytes written from p (0 <= n <= len( p))
165 // and any error encountered that caused the write to stop early. 170 // and any error encountered that caused the write to stop early.
166 // WriteAt must return a non-nil error if it returns n < len(p). 171 // WriteAt must return a non-nil error if it returns n < len(p).
167 type WriterAt interface { 172 type WriterAt interface {
168 » WriteAt(p []byte, off int64) (n int, err os.Error) 173 » WriteAt(p []byte, off int64) (n int, err error)
169 } 174 }
170 175
171 // ByteReader is the interface that wraps the ReadByte method. 176 // ByteReader is the interface that wraps the ReadByte method.
172 // 177 //
173 // ReadByte reads and returns the next byte from the input. 178 // ReadByte reads and returns the next byte from the input.
174 // If no byte is available, err will be set. 179 // If no byte is available, err will be set.
175 type ByteReader interface { 180 type ByteReader interface {
176 » ReadByte() (c byte, err os.Error) 181 » ReadByte() (c byte, err error)
177 } 182 }
178 183
179 // ByteScanner is the interface that adds the UnreadByte method to the 184 // ByteScanner is the interface that adds the UnreadByte method to the
180 // basic ReadByte method. 185 // basic ReadByte method.
181 // 186 //
182 // UnreadByte causes the next call to ReadByte to return the same byte 187 // UnreadByte causes the next call to ReadByte to return the same byte
183 // as the previous call to ReadByte. 188 // as the previous call to ReadByte.
184 // It may be an error to call UnreadByte twice without an intervening 189 // It may be an error to call UnreadByte twice without an intervening
185 // call to ReadByte. 190 // call to ReadByte.
186 type ByteScanner interface { 191 type ByteScanner interface {
187 ByteReader 192 ByteReader
188 » UnreadByte() os.Error 193 » UnreadByte() error
189 } 194 }
190 195
191 // RuneReader is the interface that wraps the ReadRune method. 196 // RuneReader is the interface that wraps the ReadRune method.
192 // 197 //
193 // ReadRune reads a single UTF-8 encoded Unicode character 198 // ReadRune reads a single UTF-8 encoded Unicode character
194 // and returns the rune and its size in bytes. If no character is 199 // and returns the rune and its size in bytes. If no character is
195 // available, err will be set. 200 // available, err will be set.
196 type RuneReader interface { 201 type RuneReader interface {
197 » ReadRune() (r rune, size int, err os.Error) 202 » ReadRune() (r rune, size int, err error)
198 } 203 }
199 204
200 // RuneScanner is the interface that adds the UnreadRune method to the 205 // RuneScanner is the interface that adds the UnreadRune method to the
201 // basic ReadRune method. 206 // basic ReadRune method.
202 // 207 //
203 // UnreadRune causes the next call to ReadRune to return the same rune 208 // UnreadRune causes the next call to ReadRune to return the same rune
204 // as the previous call to ReadRune. 209 // as the previous call to ReadRune.
205 // It may be an error to call UnreadRune twice without an intervening 210 // It may be an error to call UnreadRune twice without an intervening
206 // call to ReadRune. 211 // call to ReadRune.
207 type RuneScanner interface { 212 type RuneScanner interface {
208 RuneReader 213 RuneReader
209 » UnreadRune() os.Error 214 » UnreadRune() error
210 } 215 }
211 216
212 // stringWriter is the interface that wraps the WriteString method. 217 // stringWriter is the interface that wraps the WriteString method.
213 type stringWriter interface { 218 type stringWriter interface {
214 » WriteString(s string) (n int, err os.Error) 219 » WriteString(s string) (n int, err error)
215 } 220 }
216 221
217 // WriteString writes the contents of the string s to w, which accepts an array of bytes. 222 // WriteString writes the contents of the string s to w, which accepts an array of bytes.
218 func WriteString(w Writer, s string) (n int, err os.Error) { 223 func WriteString(w Writer, s string) (n int, err error) {
219 if sw, ok := w.(stringWriter); ok { 224 if sw, ok := w.(stringWriter); ok {
220 return sw.WriteString(s) 225 return sw.WriteString(s)
221 } 226 }
222 return w.Write([]byte(s)) 227 return w.Write([]byte(s))
223 } 228 }
224 229
225 // ReadAtLeast reads from r into buf until it has read at least min bytes. 230 // ReadAtLeast reads from r into buf until it has read at least min bytes.
226 // It returns the number of bytes copied and an error if fewer bytes were read. 231 // It returns the number of bytes copied and an error if fewer bytes were read.
227 // The error is os.EOF only if no bytes were read. 232 // The error is EOF only if no bytes were read.
228 // If an EOF happens after reading fewer than min bytes, 233 // If an EOF happens after reading fewer than min bytes,
229 // ReadAtLeast returns ErrUnexpectedEOF. 234 // ReadAtLeast returns ErrUnexpectedEOF.
230 // If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer. 235 // If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
231 func ReadAtLeast(r Reader, buf []byte, min int) (n int, err os.Error) { 236 func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
232 if len(buf) < min { 237 if len(buf) < min {
233 return 0, ErrShortBuffer 238 return 0, ErrShortBuffer
234 } 239 }
235 for n < min && err == nil { 240 for n < min && err == nil {
236 var nn int 241 var nn int
237 nn, err = r.Read(buf[n:]) 242 nn, err = r.Read(buf[n:])
238 n += nn 243 n += nn
239 } 244 }
240 » if err == os.EOF { 245 » if err == EOF {
241 if n >= min { 246 if n >= min {
242 err = nil 247 err = nil
243 } else if n > 0 { 248 } else if n > 0 {
244 err = ErrUnexpectedEOF 249 err = ErrUnexpectedEOF
245 } 250 }
246 } 251 }
247 return 252 return
248 } 253 }
249 254
250 // ReadFull reads exactly len(buf) bytes from r into buf. 255 // ReadFull reads exactly len(buf) bytes from r into buf.
251 // It returns the number of bytes copied and an error if fewer bytes were read. 256 // It returns the number of bytes copied and an error if fewer bytes were read.
252 // The error is os.EOF only if no bytes were read. 257 // The error is EOF only if no bytes were read.
253 // If an EOF happens after reading some but not all the bytes, 258 // If an EOF happens after reading some but not all the bytes,
254 // ReadFull returns ErrUnexpectedEOF. 259 // ReadFull returns ErrUnexpectedEOF.
255 func ReadFull(r Reader, buf []byte) (n int, err os.Error) { 260 func ReadFull(r Reader, buf []byte) (n int, err error) {
256 return ReadAtLeast(r, buf, len(buf)) 261 return ReadAtLeast(r, buf, len(buf))
257 } 262 }
258 263
259 // CopyN copies n bytes (or until an error) from src to dst. 264 // CopyN copies n bytes (or until an error) from src to dst.
260 // It returns the number of bytes copied and the earliest 265 // It returns the number of bytes copied and the earliest
261 // error encountered while copying. Because Read can 266 // error encountered while copying. Because Read can
262 // return the full amount requested as well as an error 267 // return the full amount requested as well as an error
263 // (including os.EOF), so can CopyN. 268 // (including EOF), so can CopyN.
264 // 269 //
265 // If dst implements the ReaderFrom interface, 270 // If dst implements the ReaderFrom interface,
266 // the copy is implemented by calling dst.ReadFrom(src). 271 // the copy is implemented by calling dst.ReadFrom(src).
267 func CopyN(dst Writer, src Reader, n int64) (written int64, err os.Error) { 272 func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
268 // If the writer has a ReadFrom method, use it to do the copy. 273 // If the writer has a ReadFrom method, use it to do the copy.
269 // Avoids a buffer allocation and a copy. 274 // Avoids a buffer allocation and a copy.
270 if rt, ok := dst.(ReaderFrom); ok { 275 if rt, ok := dst.(ReaderFrom); ok {
271 written, err = rt.ReadFrom(LimitReader(src, n)) 276 written, err = rt.ReadFrom(LimitReader(src, n))
272 if written < n && err == nil { 277 if written < n && err == nil {
273 // rt stopped early; must have been EOF. 278 // rt stopped early; must have been EOF.
274 » » » err = os.EOF 279 » » » err = EOF
275 } 280 }
276 return 281 return
277 } 282 }
278 buf := make([]byte, 32*1024) 283 buf := make([]byte, 32*1024)
279 for written < n { 284 for written < n {
280 l := len(buf) 285 l := len(buf)
281 if d := n - written; d < int64(l) { 286 if d := n - written; d < int64(l) {
282 l = int(d) 287 l = int(d)
283 } 288 }
284 nr, er := src.Read(buf[0:l]) 289 nr, er := src.Read(buf[0:l])
(...skipping 16 matching lines...) Expand all
301 break 306 break
302 } 307 }
303 } 308 }
304 return written, err 309 return written, err
305 } 310 }
306 311
307 // Copy copies from src to dst until either EOF is reached 312 // Copy copies from src to dst until either EOF is reached
308 // on src or an error occurs. It returns the number of bytes 313 // on src or an error occurs. It returns the number of bytes
309 // copied and the first error encountered while copying, if any. 314 // copied and the first error encountered while copying, if any.
310 // 315 //
311 // A successful Copy returns err == nil, not err == os.EOF. 316 // A successful Copy returns err == nil, not err == EOF.
312 // Because Copy is defined to read from src until EOF, it does 317 // Because Copy is defined to read from src until EOF, it does
313 // not treat an EOF from Read as an error to be reported. 318 // not treat an EOF from Read as an error to be reported.
314 // 319 //
315 // If dst implements the ReaderFrom interface, 320 // If dst implements the ReaderFrom interface,
316 // the copy is implemented by calling dst.ReadFrom(src). 321 // the copy is implemented by calling dst.ReadFrom(src).
317 // Otherwise, if src implements the WriterTo interface, 322 // Otherwise, if src implements the WriterTo interface,
318 // the copy is implemented by calling src.WriteTo(dst). 323 // the copy is implemented by calling src.WriteTo(dst).
319 func Copy(dst Writer, src Reader) (written int64, err os.Error) { 324 func Copy(dst Writer, src Reader) (written int64, err error) {
320 // If the writer has a ReadFrom method, use it to do the copy. 325 // If the writer has a ReadFrom method, use it to do the copy.
321 // Avoids an allocation and a copy. 326 // Avoids an allocation and a copy.
322 if rt, ok := dst.(ReaderFrom); ok { 327 if rt, ok := dst.(ReaderFrom); ok {
323 return rt.ReadFrom(src) 328 return rt.ReadFrom(src)
324 } 329 }
325 // Similarly, if the reader has a WriteTo method, use it to do the copy. 330 // Similarly, if the reader has a WriteTo method, use it to do the copy.
326 if wt, ok := src.(WriterTo); ok { 331 if wt, ok := src.(WriterTo); ok {
327 return wt.WriteTo(dst) 332 return wt.WriteTo(dst)
328 } 333 }
329 buf := make([]byte, 32*1024) 334 buf := make([]byte, 32*1024)
330 for { 335 for {
331 nr, er := src.Read(buf) 336 nr, er := src.Read(buf)
332 if nr > 0 { 337 if nr > 0 {
333 nw, ew := dst.Write(buf[0:nr]) 338 nw, ew := dst.Write(buf[0:nr])
334 if nw > 0 { 339 if nw > 0 {
335 written += int64(nw) 340 written += int64(nw)
336 } 341 }
337 if ew != nil { 342 if ew != nil {
338 err = ew 343 err = ew
339 break 344 break
340 } 345 }
341 if nr != nw { 346 if nr != nw {
342 err = ErrShortWrite 347 err = ErrShortWrite
343 break 348 break
344 } 349 }
345 } 350 }
346 » » if er == os.EOF { 351 » » if er == EOF {
347 break 352 break
348 } 353 }
349 if er != nil { 354 if er != nil {
350 err = er 355 err = er
351 break 356 break
352 } 357 }
353 } 358 }
354 return written, err 359 return written, err
355 } 360 }
356 361
357 // LimitReader returns a Reader that reads from r 362 // LimitReader returns a Reader that reads from r
358 // but stops with os.EOF after n bytes. 363 // but stops with EOF after n bytes.
359 // The underlying implementation is a *LimitedReader. 364 // The underlying implementation is a *LimitedReader.
360 func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} } 365 func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
361 366
362 // A LimitedReader reads from R but limits the amount of 367 // A LimitedReader reads from R but limits the amount of
363 // data returned to just N bytes. Each call to Read 368 // data returned to just N bytes. Each call to Read
364 // updates N to reflect the new amount remaining. 369 // updates N to reflect the new amount remaining.
365 type LimitedReader struct { 370 type LimitedReader struct {
366 R Reader // underlying reader 371 R Reader // underlying reader
367 N int64 // max bytes remaining 372 N int64 // max bytes remaining
368 } 373 }
369 374
370 func (l *LimitedReader) Read(p []byte) (n int, err os.Error) { 375 func (l *LimitedReader) Read(p []byte) (n int, err error) {
371 if l.N <= 0 { 376 if l.N <= 0 {
372 » » return 0, os.EOF 377 » » return 0, EOF
373 } 378 }
374 if int64(len(p)) > l.N { 379 if int64(len(p)) > l.N {
375 p = p[0:l.N] 380 p = p[0:l.N]
376 } 381 }
377 n, err = l.R.Read(p) 382 n, err = l.R.Read(p)
378 l.N -= int64(n) 383 l.N -= int64(n)
379 return 384 return
380 } 385 }
381 386
382 // NewSectionReader returns a SectionReader that reads from r 387 // NewSectionReader returns a SectionReader that reads from r
383 // starting at offset off and stops with os.EOF after n bytes. 388 // starting at offset off and stops with EOF after n bytes.
384 func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader { 389 func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
385 return &SectionReader{r, off, off, off + n} 390 return &SectionReader{r, off, off, off + n}
386 } 391 }
387 392
388 // SectionReader implements Read, Seek, and ReadAt on a section 393 // SectionReader implements Read, Seek, and ReadAt on a section
389 // of an underlying ReaderAt. 394 // of an underlying ReaderAt.
390 type SectionReader struct { 395 type SectionReader struct {
391 r ReaderAt 396 r ReaderAt
392 base int64 397 base int64
393 off int64 398 off int64
394 limit int64 399 limit int64
395 } 400 }
396 401
397 func (s *SectionReader) Read(p []byte) (n int, err os.Error) { 402 func (s *SectionReader) Read(p []byte) (n int, err error) {
398 if s.off >= s.limit { 403 if s.off >= s.limit {
399 » » return 0, os.EOF 404 » » return 0, EOF
400 } 405 }
401 if max := s.limit - s.off; int64(len(p)) > max { 406 if max := s.limit - s.off; int64(len(p)) > max {
402 p = p[0:max] 407 p = p[0:max]
403 } 408 }
404 n, err = s.r.ReadAt(p, s.off) 409 n, err = s.r.ReadAt(p, s.off)
405 s.off += int64(n) 410 s.off += int64(n)
406 return 411 return
407 } 412 }
408 413
409 func (s *SectionReader) Seek(offset int64, whence int) (ret int64, err os.Error) { 414 var errWhence = &Error{"Seek: invalid whence"}
415 var errOffset = &Error{"Seek: invalid offset"}
416
417 func (s *SectionReader) Seek(offset int64, whence int) (ret int64, err error) {
410 switch whence { 418 switch whence {
411 default: 419 default:
412 » » return 0, os.EINVAL 420 » » return 0, errWhence
413 case 0: 421 case 0:
414 offset += s.base 422 offset += s.base
415 case 1: 423 case 1:
416 offset += s.off 424 offset += s.off
417 case 2: 425 case 2:
418 offset += s.limit 426 offset += s.limit
419 } 427 }
420 if offset < s.base || offset > s.limit { 428 if offset < s.base || offset > s.limit {
421 » » return 0, os.EINVAL 429 » » return 0, errOffset
422 } 430 }
423 s.off = offset 431 s.off = offset
424 return offset - s.base, nil 432 return offset - s.base, nil
425 } 433 }
426 434
427 func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err os.Error) { 435 func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
428 if off < 0 || off >= s.limit-s.base { 436 if off < 0 || off >= s.limit-s.base {
429 » » return 0, os.EOF 437 » » return 0, EOF
430 } 438 }
431 off += s.base 439 off += s.base
432 if max := s.limit - off; int64(len(p)) > max { 440 if max := s.limit - off; int64(len(p)) > max {
433 p = p[0:max] 441 p = p[0:max]
434 } 442 }
435 return s.r.ReadAt(p, off) 443 return s.r.ReadAt(p, off)
436 } 444 }
437 445
438 // Size returns the size of the section in bytes. 446 // Size returns the size of the section in bytes.
439 func (s *SectionReader) Size() int64 { return s.limit - s.base } 447 func (s *SectionReader) Size() int64 { return s.limit - s.base }
440 448
441 // TeeReader returns a Reader that writes to w what it reads from r. 449 // TeeReader returns a Reader that writes to w what it reads from r.
442 // All reads from r performed through it are matched with 450 // All reads from r performed through it are matched with
443 // corresponding writes to w. There is no internal buffering - 451 // corresponding writes to w. There is no internal buffering -
444 // the write must complete before the read completes. 452 // the write must complete before the read completes.
445 // Any error encountered while writing is reported as a read error. 453 // Any error encountered while writing is reported as a read error.
446 func TeeReader(r Reader, w Writer) Reader { 454 func TeeReader(r Reader, w Writer) Reader {
447 return &teeReader{r, w} 455 return &teeReader{r, w}
448 } 456 }
449 457
450 type teeReader struct { 458 type teeReader struct {
451 r Reader 459 r Reader
452 w Writer 460 w Writer
453 } 461 }
454 462
455 func (t *teeReader) Read(p []byte) (n int, err os.Error) { 463 func (t *teeReader) Read(p []byte) (n int, err error) {
456 n, err = t.r.Read(p) 464 n, err = t.r.Read(p)
457 if n > 0 { 465 if n > 0 {
458 if n, err := t.w.Write(p[:n]); err != nil { 466 if n, err := t.w.Write(p[:n]); err != nil {
459 return n, err 467 return n, err
460 } 468 }
461 } 469 }
462 return 470 return
463 } 471 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b