blob: 3b8791897988399a7c9a7ec7db0373ef105a59a2 [file] [log] [blame]
Russ Cox7c9e2c22008-09-12 16:42:53 -07001// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Rob Pike7bb335c2009-03-06 03:43:44 -08005// This package provides basic interfaces to I/O 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
Rob Pikeb0683bd2009-12-02 22:02:14 -08008// abstract the functionality, plus some other related primitives.
Russ Cox7c9e2c22008-09-12 16:42:53 -07009package io
Rob Pike6ee7fe52008-11-11 17:28:36 -080010
Russ Cox9750adb2010-02-25 16:01:29 -080011import "os"
Rob Pike6ee7fe52008-11-11 17:28:36 -080012
Russ Cox3b36acc2009-05-18 11:47:35 -070013// Error represents an unexpected I/O behavior.
Russ Cox1b301ba2009-05-08 14:40:20 -070014type Error struct {
Robert Griesemera3d10452009-12-15 15:35:38 -080015 os.ErrorString
Russ Cox1b301ba2009-05-08 14:40:20 -070016}
Russ Cox3b36acc2009-05-18 11:47:35 -070017
Russ Cox3b36acc2009-05-18 11:47:35 -070018// ErrShortWrite means that a write accepted fewer bytes than requested
19// but failed to return an explicit error.
20var ErrShortWrite os.Error = &Error{"short write"}
21
Andrew Gerrand46427082010-08-23 12:04:15 +100022// ErrShortBuffer means that a read required a longer buffer than was provided.
23var ErrShortBuffer os.Error = &Error{"short buffer"}
24
Russ Cox64684cc2009-06-22 13:26:13 -070025// ErrUnexpectedEOF means that os.EOF was encountered in the
26// middle of reading a fixed-size block or data structure.
27var ErrUnexpectedEOF os.Error = &Error{"unexpected EOF"}
Russ Cox3b36acc2009-05-18 11:47:35 -070028
Rob Pikec8b47c62009-05-08 11:22:57 -070029// Reader is the interface that wraps the basic Read method.
Russ Cox64684cc2009-06-22 13:26:13 -070030//
31// Read reads up to len(p) bytes into p. It returns the number of bytes
Russ Cox71f19d62009-06-22 14:44:07 -070032// read (0 <= n <= len(p)) and any error encountered.
33// Even if Read returns n < len(p),
Russ Cox64684cc2009-06-22 13:26:13 -070034// it may use all of p as scratch space during the call.
35// If some data is available but not len(p) bytes, Read conventionally
36// returns what is available rather than block waiting for more.
37//
38// At the end of the input stream, Read returns 0, os.EOF.
39// Read may return a non-zero number of bytes with a non-nil err.
40// In particular, a Read that exhausts the input may return n > 0, os.EOF.
Rob Pikec8b47c62009-05-08 11:22:57 -070041type Reader interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080042 Read(p []byte) (n int, err os.Error)
Russ Cox7c9e2c22008-09-12 16:42:53 -070043}
44
Rob Pikec8b47c62009-05-08 11:22:57 -070045// Writer is the interface that wraps the basic Write method.
Russ Cox71f19d62009-06-22 14:44:07 -070046//
47// Write writes len(p) bytes from p to the underlying data stream.
48// It returns the number of bytes written from p (0 <= n <= len(p))
49// and any error encountered that caused the write to stop early.
50// Write must return a non-nil error if it returns n < len(p).
Rob Pikec8b47c62009-05-08 11:22:57 -070051type Writer interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080052 Write(p []byte) (n int, err os.Error)
Russ Cox7c9e2c22008-09-12 16:42:53 -070053}
54
Rob Pikec8b47c62009-05-08 11:22:57 -070055// Closer is the interface that wraps the basic Close method.
56type Closer interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080057 Close() os.Error
Russ Cox78906c32009-02-16 16:32:30 -080058}
59
Austin Clementsb3062f12009-08-18 17:47:03 -070060// Seeker is the interface that wraps the basic Seek method.
61//
62// Seek sets the offset for the next Read or Write to offset,
63// interpreted according to whence: 0 means relative to the origin of
64// the file, 1 means relative to the current offset, and 2 means
65// relative to the end. Seek returns the new offset and an Error, if
66// any.
67type Seeker interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080068 Seek(offset int64, whence int) (ret int64, err os.Error)
Austin Clementsb3062f12009-08-18 17:47:03 -070069}
70
Russ Coxb90f6732009-11-23 14:22:56 -080071// ReadWriter is the interface that groups the basic Read and Write methods.
Rob Pikec8b47c62009-05-08 11:22:57 -070072type ReadWriter interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080073 Reader
74 Writer
Russ Cox9350ef42008-09-17 13:49:23 -070075}
76
Rob Pikec8b47c62009-05-08 11:22:57 -070077// ReadCloser is the interface that groups the basic Read and Close methods.
78type ReadCloser interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080079 Reader
80 Closer
Russ Cox78906c32009-02-16 16:32:30 -080081}
82
Rob Pikec8b47c62009-05-08 11:22:57 -070083// WriteCloser is the interface that groups the basic Write and Close methods.
84type WriteCloser interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080085 Writer
86 Closer
Russ Cox7c7a5252008-10-20 12:37:07 -070087}
88
Rob Pikec8b47c62009-05-08 11:22:57 -070089// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
90type ReadWriteCloser interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080091 Reader
92 Writer
93 Closer
Russ Cox9aa28f92009-02-03 14:16:22 -080094}
95
Austin Clementsb3062f12009-08-18 17:47:03 -070096// ReadSeeker is the interface that groups the basic Read and Seek methods.
97type ReadSeeker interface {
Robert Griesemera3d10452009-12-15 15:35:38 -080098 Reader
99 Seeker
Austin Clementsb3062f12009-08-18 17:47:03 -0700100}
101
102// WriteSeeker is the interface that groups the basic Write and Seek methods.
103type WriteSeeker interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800104 Writer
105 Seeker
Austin Clementsb3062f12009-08-18 17:47:03 -0700106}
107
108// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
109type ReadWriteSeeker interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800110 Reader
111 Writer
112 Seeker
Austin Clementsb3062f12009-08-18 17:47:03 -0700113}
114
Rob Pikebc3e3472009-12-03 12:56:16 -0800115// ReaderFrom is the interface that wraps the ReadFrom method.
116type ReaderFrom interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800117 ReadFrom(r Reader) (n int64, err os.Error)
Rob Pikebc3e3472009-12-03 12:56:16 -0800118}
119
120// WriterTo is the interface that wraps the WriteTo method.
121type WriterTo interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800122 WriteTo(w Writer) (n int64, err os.Error)
Rob Pikebc3e3472009-12-03 12:56:16 -0800123}
124
Russ Coxe5962972009-08-31 16:34:43 -0700125// ReaderAt is the interface that wraps the basic ReadAt method.
126//
127// ReadAt reads len(p) bytes into p starting at offset off in the
128// underlying data stream. It returns the number of bytes
129// read (0 <= n <= len(p)) and any error encountered.
130//
131// Even if ReadAt returns n < len(p),
132// it may use all of p as scratch space during the call.
133// If some data is available but not len(p) bytes, ReadAt blocks
134// until either all the data is available or an error occurs.
135//
136// At the end of the input stream, ReadAt returns 0, os.EOF.
137// ReadAt may return a non-zero number of bytes with a non-nil err.
138// In particular, a ReadAt that exhausts the input may return n > 0, os.EOF.
139type ReaderAt interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800140 ReadAt(p []byte, off int64) (n int, err os.Error)
Russ Coxe5962972009-08-31 16:34:43 -0700141}
142
143// WriterAt is the interface that wraps the basic WriteAt method.
144//
145// WriteAt writes len(p) bytes from p to the underlying data stream
146// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
147// and any error encountered that caused the write to stop early.
148// WriteAt must return a non-nil error if it returns n < len(p).
149type WriterAt interface {
Robert Griesemera3d10452009-12-15 15:35:38 -0800150 WriteAt(p []byte, off int64) (n int, err os.Error)
Russ Coxe5962972009-08-31 16:34:43 -0700151}
152
Robert Griesemer827e98d2011-02-02 13:42:15 -0800153// ByteReader is the interface that wraps the ReadByte method.
Rob Pikefce5d602010-01-07 13:29:43 +1100154//
155// ReadByte reads and returns the next byte from the input.
156// If no byte is available, err will be set.
Robert Griesemer827e98d2011-02-02 13:42:15 -0800157type ByteReader interface {
Rob Pikefce5d602010-01-07 13:29:43 +1100158 ReadByte() (c byte, err os.Error)
159}
160
Robert Griesemer827e98d2011-02-02 13:42:15 -0800161// RuneReader is the interface that wraps the ReadRune method.
Rob Pike622d7292011-02-01 21:09:33 -0800162//
163// ReadRune reads a single UTF-8 encoded Unicode character
164// and returns the rune and its size in bytes. If no character is
165// available, err will be set.
Robert Griesemer827e98d2011-02-02 13:42:15 -0800166type RuneReader interface {
Rob Pike622d7292011-02-01 21:09:33 -0800167 ReadRune() (rune int, size int, err os.Error)
168}
169
Rob Pike7bb335c2009-03-06 03:43:44 -0800170// WriteString writes the contents of the string s to w, which accepts an array of bytes.
Rob Pikec8b47c62009-05-08 11:22:57 -0700171func WriteString(w Writer, s string) (n int, err os.Error) {
Russ Cox9750adb2010-02-25 16:01:29 -0800172 return w.Write([]byte(s))
Russ Cox7c9e2c22008-09-12 16:42:53 -0700173}
Rob Pike6ee7fe52008-11-11 17:28:36 -0800174
Russ Cox64684cc2009-06-22 13:26:13 -0700175// ReadAtLeast reads from r into buf until it has read at least min bytes.
176// It returns the number of bytes copied and an error if fewer bytes were read.
177// The error is os.EOF only if no bytes were read.
178// If an EOF happens after reading fewer than min bytes,
179// ReadAtLeast returns ErrUnexpectedEOF.
Andrew Gerrand46427082010-08-23 12:04:15 +1000180// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
Russ Coxb0608c132009-05-19 14:01:03 -0700181func ReadAtLeast(r Reader, buf []byte, min int) (n int, err os.Error) {
Andrew Gerrand46427082010-08-23 12:04:15 +1000182 if len(buf) < min {
183 return 0, ErrShortBuffer
184 }
Russ Coxb0608c132009-05-19 14:01:03 -0700185 for n < min {
Robert Griesemera3d10452009-12-15 15:35:38 -0800186 nn, e := r.Read(buf[n:])
Rob Pike6ee7fe52008-11-11 17:28:36 -0800187 if nn > 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -0800188 n += nn
Rob Pike6ee7fe52008-11-11 17:28:36 -0800189 }
190 if e != nil {
Russ Cox64684cc2009-06-22 13:26:13 -0700191 if e == os.EOF && n > 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -0800192 e = ErrUnexpectedEOF
Russ Cox64684cc2009-06-22 13:26:13 -0700193 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800194 return n, e
Rob Pike6ee7fe52008-11-11 17:28:36 -0800195 }
Rob Pike6ee7fe52008-11-11 17:28:36 -0800196 }
Andrew Gerrand46427082010-08-23 12:04:15 +1000197 return
Rob Pike6ee7fe52008-11-11 17:28:36 -0800198}
199
Russ Cox64684cc2009-06-22 13:26:13 -0700200// ReadFull reads exactly len(buf) bytes from r into buf.
201// It returns the number of bytes copied and an error if fewer bytes were read.
202// The error is os.EOF only if no bytes were read.
203// If an EOF happens after reading some but not all the bytes,
204// ReadFull returns ErrUnexpectedEOF.
205func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
Robert Griesemer40621d52009-11-09 12:07:39 -0800206 return ReadAtLeast(r, buf, len(buf))
Russ Coxb0608c132009-05-19 14:01:03 -0700207}
208
Russ Cox64684cc2009-06-22 13:26:13 -0700209// Copyn copies n bytes (or until an error) from src to dst.
Rob Pike7bb335c2009-03-06 03:43:44 -0800210// It returns the number of bytes copied and the error, if any.
Rob Pikebc3e3472009-12-03 12:56:16 -0800211//
212// If dst implements the ReaderFrom interface,
213// the copy is implemented by calling dst.ReadFrom(src).
Rob Pike4d310f22009-11-01 20:59:49 -0800214func Copyn(dst Writer, src Reader, n int64) (written int64, err os.Error) {
Anschel Schaffer-Cohen84fc1e22010-12-31 10:37:55 +1100215 // If the writer has a ReadFrom method, use it to do the copy.
Rob Pikebc3e3472009-12-03 12:56:16 -0800216 // Avoids a buffer allocation and a copy.
217 if rt, ok := dst.(ReaderFrom); ok {
Russ Cox0f266082011-01-05 14:35:13 -0500218 written, err = rt.ReadFrom(LimitReader(src, n))
219 if written < n && err == nil {
220 // rt stopped early; must have been EOF.
221 err = os.EOF
222 }
223 return
Rob Pikebc3e3472009-12-03 12:56:16 -0800224 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800225 buf := make([]byte, 32*1024)
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800226 for written < n {
Robert Griesemera3d10452009-12-15 15:35:38 -0800227 l := len(buf)
Robert Griesemer3bb00322009-11-09 21:23:52 -0800228 if d := n - written; d < int64(l) {
Robert Griesemer40621d52009-11-09 12:07:39 -0800229 l = int(d)
Robert Griesemer79d94d52008-11-18 18:08:05 -0800230 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800231 nr, er := src.Read(buf[0:l])
Robert Griesemer79d94d52008-11-18 18:08:05 -0800232 if nr > 0 {
Robert Griesemera3d10452009-12-15 15:35:38 -0800233 nw, ew := dst.Write(buf[0:nr])
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800234 if nw > 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -0800235 written += int64(nw)
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800236 }
237 if ew != nil {
Robert Griesemera3d10452009-12-15 15:35:38 -0800238 err = ew
239 break
Robert Griesemer79d94d52008-11-18 18:08:05 -0800240 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800241 if nr != nw {
Robert Griesemera3d10452009-12-15 15:35:38 -0800242 err = ErrShortWrite
243 break
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800244 }
245 }
246 if er != nil {
Robert Griesemera3d10452009-12-15 15:35:38 -0800247 err = er
248 break
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800249 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800250 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800251 return written, err
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800252}
253
Russ Cox64684cc2009-06-22 13:26:13 -0700254// Copy copies from src to dst until either EOF is reached
255// on src or an error occurs. It returns the number of bytes
256// copied and the error, if any.
Rob Pikebc3e3472009-12-03 12:56:16 -0800257//
258// If dst implements the ReaderFrom interface,
259// the copy is implemented by calling dst.ReadFrom(src).
260// Otherwise, if src implements the WriterTo interface,
261// the copy is implemented by calling src.WriteTo(dst).
Rob Pike4d310f22009-11-01 20:59:49 -0800262func Copy(dst Writer, src Reader) (written int64, err os.Error) {
Anschel Schaffer-Cohen84fc1e22010-12-31 10:37:55 +1100263 // If the writer has a ReadFrom method, use it to do the copy.
Rob Pikebc3e3472009-12-03 12:56:16 -0800264 // Avoids an allocation and a copy.
265 if rt, ok := dst.(ReaderFrom); ok {
266 return rt.ReadFrom(src)
267 }
Anschel Schaffer-Cohen84fc1e22010-12-31 10:37:55 +1100268 // Similarly, if the reader has a WriteTo method, use it to do the copy.
Rob Pikebc3e3472009-12-03 12:56:16 -0800269 if wt, ok := src.(WriterTo); ok {
270 return wt.WriteTo(dst)
271 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800272 buf := make([]byte, 32*1024)
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800273 for {
Robert Griesemera3d10452009-12-15 15:35:38 -0800274 nr, er := src.Read(buf)
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800275 if nr > 0 {
Robert Griesemera3d10452009-12-15 15:35:38 -0800276 nw, ew := dst.Write(buf[0:nr])
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800277 if nw > 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -0800278 written += int64(nw)
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800279 }
280 if ew != nil {
Robert Griesemera3d10452009-12-15 15:35:38 -0800281 err = ew
282 break
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800283 }
284 if nr != nw {
Robert Griesemera3d10452009-12-15 15:35:38 -0800285 err = ErrShortWrite
286 break
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800287 }
Robert Griesemer79d94d52008-11-18 18:08:05 -0800288 }
Russ Cox64684cc2009-06-22 13:26:13 -0700289 if er == os.EOF {
Robert Griesemer40621d52009-11-09 12:07:39 -0800290 break
Robert Griesemer79d94d52008-11-18 18:08:05 -0800291 }
Russ Cox64684cc2009-06-22 13:26:13 -0700292 if er != nil {
Robert Griesemera3d10452009-12-15 15:35:38 -0800293 err = er
294 break
Robert Griesemer79d94d52008-11-18 18:08:05 -0800295 }
296 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800297 return written, err
Robert Griesemer79d94d52008-11-18 18:08:05 -0800298}
Russ Coxbe869ba2009-05-18 13:31:56 -0700299
Russ Cox90dcd5f2009-08-26 16:23:54 -0700300// LimitReader returns a Reader that reads from r
301// but stops with os.EOF after n bytes.
Robert Griesemera3d10452009-12-15 15:35:38 -0800302func LimitReader(r Reader, n int64) Reader { return &limitedReader{r, n} }
Russ Coxbe869ba2009-05-18 13:31:56 -0700303
Russ Cox90dcd5f2009-08-26 16:23:54 -0700304type limitedReader struct {
Robert Griesemera3d10452009-12-15 15:35:38 -0800305 r Reader
306 n int64
Russ Cox90dcd5f2009-08-26 16:23:54 -0700307}
308
309func (l *limitedReader) Read(p []byte) (n int, err os.Error) {
310 if l.n <= 0 {
Robert Griesemer40621d52009-11-09 12:07:39 -0800311 return 0, os.EOF
Russ Cox64684cc2009-06-22 13:26:13 -0700312 }
Russ Cox90dcd5f2009-08-26 16:23:54 -0700313 if int64(len(p)) > l.n {
Robert Griesemer3bb00322009-11-09 21:23:52 -0800314 p = p[0:l.n]
Russ Coxbe869ba2009-05-18 13:31:56 -0700315 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800316 n, err = l.r.Read(p)
317 l.n -= int64(n)
318 return
Russ Coxbe869ba2009-05-18 13:31:56 -0700319}
Russ Coxe5962972009-08-31 16:34:43 -0700320
321// NewSectionReader returns a SectionReader that reads from r
322// starting at offset off and stops with os.EOF after n bytes.
323func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
Robert Griesemer3bb00322009-11-09 21:23:52 -0800324 return &SectionReader{r, off, off, off + n}
Russ Coxe5962972009-08-31 16:34:43 -0700325}
326
327// SectionReader implements Read, Seek, and ReadAt on a section
328// of an underlying ReaderAt.
329type SectionReader struct {
Robert Griesemera3d10452009-12-15 15:35:38 -0800330 r ReaderAt
331 base int64
332 off int64
333 limit int64
Russ Coxe5962972009-08-31 16:34:43 -0700334}
335
336func (s *SectionReader) Read(p []byte) (n int, err os.Error) {
337 if s.off >= s.limit {
Robert Griesemer40621d52009-11-09 12:07:39 -0800338 return 0, os.EOF
Russ Coxe5962972009-08-31 16:34:43 -0700339 }
340 if max := s.limit - s.off; int64(len(p)) > max {
Robert Griesemer40621d52009-11-09 12:07:39 -0800341 p = p[0:max]
Russ Coxe5962972009-08-31 16:34:43 -0700342 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800343 n, err = s.r.ReadAt(p, s.off)
344 s.off += int64(n)
345 return
Russ Coxe5962972009-08-31 16:34:43 -0700346}
347
348func (s *SectionReader) Seek(offset int64, whence int) (ret int64, err os.Error) {
349 switch whence {
350 default:
Robert Griesemer40621d52009-11-09 12:07:39 -0800351 return 0, os.EINVAL
Russ Coxe5962972009-08-31 16:34:43 -0700352 case 0:
Robert Griesemer40621d52009-11-09 12:07:39 -0800353 offset += s.base
Russ Coxe5962972009-08-31 16:34:43 -0700354 case 1:
Robert Griesemer40621d52009-11-09 12:07:39 -0800355 offset += s.off
Russ Coxe5962972009-08-31 16:34:43 -0700356 case 2:
Robert Griesemer40621d52009-11-09 12:07:39 -0800357 offset += s.limit
Russ Coxe5962972009-08-31 16:34:43 -0700358 }
Peter Mundy56b3e5d2010-07-08 16:57:07 +1000359 if offset < s.base || offset > s.limit {
Robert Griesemer40621d52009-11-09 12:07:39 -0800360 return 0, os.EINVAL
Russ Coxe5962972009-08-31 16:34:43 -0700361 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800362 s.off = offset
363 return offset - s.base, nil
Russ Coxe5962972009-08-31 16:34:43 -0700364}
365
366func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err os.Error) {
Robert Griesemer3bb00322009-11-09 21:23:52 -0800367 if off < 0 || off >= s.limit-s.base {
Robert Griesemer40621d52009-11-09 12:07:39 -0800368 return 0, os.EOF
Russ Coxe5962972009-08-31 16:34:43 -0700369 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800370 off += s.base
Russ Coxe5962972009-08-31 16:34:43 -0700371 if max := s.limit - off; int64(len(p)) > max {
Robert Griesemer40621d52009-11-09 12:07:39 -0800372 p = p[0:max]
Russ Coxe5962972009-08-31 16:34:43 -0700373 }
Robert Griesemera3d10452009-12-15 15:35:38 -0800374 return s.r.ReadAt(p, off)
Russ Coxe5962972009-08-31 16:34:43 -0700375}
376
Russ Coxf277ebf2009-09-01 16:11:17 -0700377// Size returns the size of the section in bytes.
Robert Griesemera3d10452009-12-15 15:35:38 -0800378func (s *SectionReader) Size() int64 { return s.limit - s.base }