blob: be6614b643d1110751d8275f41396e87069610d7 [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
8// abstract the functionality.
9// It also provides buffering primitives and some other basic operations.
Russ Cox7c9e2c22008-09-12 16:42:53 -070010package io
Rob Pike6ee7fe52008-11-11 17:28:36 -080011
12import (
Rob Pike424f4f02009-06-04 15:28:09 -070013 "bytes";
Rob Pike6ee7fe52008-11-11 17:28:36 -080014 "os";
Russ Coxd3a412a2009-06-29 15:24:23 -070015 "strings";
Rob Pike6ee7fe52008-11-11 17:28:36 -080016)
17
Russ Cox3b36acc2009-05-18 11:47:35 -070018// Error represents an unexpected I/O behavior.
Russ Cox1b301ba2009-05-08 14:40:20 -070019type Error struct {
20 os.ErrorString
21}
Russ Cox3b36acc2009-05-18 11:47:35 -070022
Russ Cox3b36acc2009-05-18 11:47:35 -070023// ErrShortWrite means that a write accepted fewer bytes than requested
24// but failed to return an explicit error.
25var ErrShortWrite os.Error = &Error{"short write"}
26
Russ Cox64684cc2009-06-22 13:26:13 -070027// ErrUnexpectedEOF means that os.EOF was encountered in the
28// middle of reading a fixed-size block or data structure.
29var ErrUnexpectedEOF os.Error = &Error{"unexpected EOF"}
Russ Cox3b36acc2009-05-18 11:47:35 -070030
Rob Pikec8b47c62009-05-08 11:22:57 -070031// Reader is the interface that wraps the basic Read method.
Russ Cox64684cc2009-06-22 13:26:13 -070032//
33// Read reads up to len(p) bytes into p. It returns the number of bytes
Russ Cox71f19d62009-06-22 14:44:07 -070034// read (0 <= n <= len(p)) and any error encountered.
35// Even if Read returns n < len(p),
Russ Cox64684cc2009-06-22 13:26:13 -070036// it may use all of p as scratch space during the call.
37// If some data is available but not len(p) bytes, Read conventionally
38// returns what is available rather than block waiting for more.
39//
40// At the end of the input stream, Read returns 0, os.EOF.
41// Read may return a non-zero number of bytes with a non-nil err.
42// In particular, a Read that exhausts the input may return n > 0, os.EOF.
Rob Pikec8b47c62009-05-08 11:22:57 -070043type Reader interface {
Rob Pikeaaf63f82009-04-17 00:08:24 -070044 Read(p []byte) (n int, err os.Error);
Russ Cox7c9e2c22008-09-12 16:42:53 -070045}
46
Rob Pikec8b47c62009-05-08 11:22:57 -070047// Writer is the interface that wraps the basic Write method.
Russ Cox71f19d62009-06-22 14:44:07 -070048//
49// Write writes len(p) bytes from p to the underlying data stream.
50// It returns the number of bytes written from p (0 <= n <= len(p))
51// and any error encountered that caused the write to stop early.
52// Write must return a non-nil error if it returns n < len(p).
Rob Pikec8b47c62009-05-08 11:22:57 -070053type Writer interface {
Rob Pikeaaf63f82009-04-17 00:08:24 -070054 Write(p []byte) (n int, err os.Error);
Russ Cox7c9e2c22008-09-12 16:42:53 -070055}
56
Rob Pikec8b47c62009-05-08 11:22:57 -070057// Closer is the interface that wraps the basic Close method.
58type Closer interface {
Rob Pikeaaf63f82009-04-17 00:08:24 -070059 Close() os.Error;
Russ Cox78906c32009-02-16 16:32:30 -080060}
61
Austin Clementsb3062f12009-08-18 17:47:03 -070062// Seeker is the interface that wraps the basic Seek method.
63//
64// Seek sets the offset for the next Read or Write to offset,
65// interpreted according to whence: 0 means relative to the origin of
66// the file, 1 means relative to the current offset, and 2 means
67// relative to the end. Seek returns the new offset and an Error, if
68// any.
69type Seeker interface {
70 Seek(offset int64, whence int) (ret int64, err os.Error);
71}
72
Rob Pike7bb335c2009-03-06 03:43:44 -080073// ReadWrite is the interface that groups the basic Read and Write methods.
Rob Pikec8b47c62009-05-08 11:22:57 -070074type ReadWriter interface {
75 Reader;
76 Writer;
Russ Cox9350ef42008-09-17 13:49:23 -070077}
78
Rob Pikec8b47c62009-05-08 11:22:57 -070079// ReadCloser is the interface that groups the basic Read and Close methods.
80type ReadCloser interface {
81 Reader;
82 Closer;
Russ Cox78906c32009-02-16 16:32:30 -080083}
84
Rob Pikec8b47c62009-05-08 11:22:57 -070085// WriteCloser is the interface that groups the basic Write and Close methods.
86type WriteCloser interface {
87 Writer;
88 Closer;
Russ Cox7c7a5252008-10-20 12:37:07 -070089}
90
Rob Pikec8b47c62009-05-08 11:22:57 -070091// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
92type ReadWriteCloser interface {
93 Reader;
94 Writer;
95 Closer;
Russ Cox9aa28f92009-02-03 14:16:22 -080096}
97
Austin Clementsb3062f12009-08-18 17:47:03 -070098// ReadSeeker is the interface that groups the basic Read and Seek methods.
99type ReadSeeker interface {
100 Reader;
101 Seeker;
102}
103
104// WriteSeeker is the interface that groups the basic Write and Seek methods.
105type WriteSeeker interface {
106 Writer;
107 Seeker;
108}
109
110// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
111type ReadWriteSeeker interface {
112 Reader;
113 Writer;
114 Seeker;
115}
116
Russ Coxe5962972009-08-31 16:34:43 -0700117// ReaderAt is the interface that wraps the basic ReadAt method.
118//
119// ReadAt reads len(p) bytes into p starting at offset off in the
120// underlying data stream. It returns the number of bytes
121// read (0 <= n <= len(p)) and any error encountered.
122//
123// Even if ReadAt returns n < len(p),
124// it may use all of p as scratch space during the call.
125// If some data is available but not len(p) bytes, ReadAt blocks
126// until either all the data is available or an error occurs.
127//
128// At the end of the input stream, ReadAt returns 0, os.EOF.
129// ReadAt may return a non-zero number of bytes with a non-nil err.
130// In particular, a ReadAt that exhausts the input may return n > 0, os.EOF.
131type ReaderAt interface {
132 ReadAt(p []byte, off int64) (n int, err os.Error);
133}
134
135// WriterAt is the interface that wraps the basic WriteAt method.
136//
137// WriteAt writes len(p) bytes from p to the underlying data stream
138// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
139// and any error encountered that caused the write to stop early.
140// WriteAt must return a non-nil error if it returns n < len(p).
141type WriterAt interface {
142 WriteAt(p []byte, off int64) (n int, err os.Error);
143}
144
Rob Pike7bb335c2009-03-06 03:43:44 -0800145// WriteString writes the contents of the string s to w, which accepts an array of bytes.
Rob Pikec8b47c62009-05-08 11:22:57 -0700146func WriteString(w Writer, s string) (n int, err os.Error) {
Russ Coxd3a412a2009-06-29 15:24:23 -0700147 return w.Write(strings.Bytes(s))
Russ Cox7c9e2c22008-09-12 16:42:53 -0700148}
Rob Pike6ee7fe52008-11-11 17:28:36 -0800149
Russ Cox64684cc2009-06-22 13:26:13 -0700150// ReadAtLeast reads from r into buf until it has read at least min bytes.
151// It returns the number of bytes copied and an error if fewer bytes were read.
152// The error is os.EOF only if no bytes were read.
153// If an EOF happens after reading fewer than min bytes,
154// ReadAtLeast returns ErrUnexpectedEOF.
Russ Coxb0608c132009-05-19 14:01:03 -0700155func ReadAtLeast(r Reader, buf []byte, min int) (n int, err os.Error) {
Rob Pike6ee7fe52008-11-11 17:28:36 -0800156 n = 0;
Russ Coxb0608c132009-05-19 14:01:03 -0700157 for n < min {
Russ Coxe9b40582009-03-02 16:12:04 -0800158 nn, e := r.Read(buf[n:len(buf)]);
Rob Pike6ee7fe52008-11-11 17:28:36 -0800159 if nn > 0 {
160 n += nn
161 }
162 if e != nil {
Russ Cox64684cc2009-06-22 13:26:13 -0700163 if e == os.EOF && n > 0 {
164 e = ErrUnexpectedEOF;
165 }
Rob Pike6ee7fe52008-11-11 17:28:36 -0800166 return n, e
167 }
Rob Pike6ee7fe52008-11-11 17:28:36 -0800168 }
169 return n, nil
170}
171
Russ Cox64684cc2009-06-22 13:26:13 -0700172// ReadFull reads exactly len(buf) bytes from r into buf.
173// It returns the number of bytes copied and an error if fewer bytes were read.
174// The error is os.EOF only if no bytes were read.
175// If an EOF happens after reading some but not all the bytes,
176// ReadFull returns ErrUnexpectedEOF.
177func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
Russ Cox55e790a2009-07-01 07:32:04 -0700178 return ReadAtLeast(r, buf, len(buf));
Russ Coxb0608c132009-05-19 14:01:03 -0700179}
180
Russ Cox64684cc2009-06-22 13:26:13 -0700181// Copyn copies n bytes (or until an error) from src to dst.
Rob Pike7bb335c2009-03-06 03:43:44 -0800182// It returns the number of bytes copied and the error, if any.
Rob Pikec8b47c62009-05-08 11:22:57 -0700183func Copyn(src Reader, dst Writer, n int64) (written int64, err os.Error) {
Russ Cox55645042009-01-06 15:19:02 -0800184 buf := make([]byte, 32*1024);
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800185 for written < n {
Robert Griesemer60ee27d2008-11-19 10:20:52 -0800186 l := len(buf);
187 if d := n - written; d < int64(l) {
188 l = int(d);
Robert Griesemer79d94d52008-11-18 18:08:05 -0800189 }
190 nr, er := src.Read(buf[0 : l]);
191 if nr > 0 {
192 nw, ew := dst.Write(buf[0 : nr]);
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800193 if nw > 0 {
194 written += int64(nw);
195 }
196 if ew != nil {
Robert Griesemer79d94d52008-11-18 18:08:05 -0800197 err = ew;
198 break;
199 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800200 if nr != nw {
Russ Cox64684cc2009-06-22 13:26:13 -0700201 err = ErrShortWrite;
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800202 break;
203 }
204 }
205 if er != nil {
206 err = er;
207 break;
208 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800209 }
210 return written, err
211}
212
Russ Cox64684cc2009-06-22 13:26:13 -0700213// Copy copies from src to dst until either EOF is reached
214// on src or an error occurs. It returns the number of bytes
215// copied and the error, if any.
Rob Pikec8b47c62009-05-08 11:22:57 -0700216func Copy(src Reader, dst Writer) (written int64, err os.Error) {
Russ Cox55645042009-01-06 15:19:02 -0800217 buf := make([]byte, 32*1024);
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800218 for {
219 nr, er := src.Read(buf);
220 if nr > 0 {
221 nw, ew := dst.Write(buf[0:nr]);
222 if nw > 0 {
223 written += int64(nw);
224 }
225 if ew != nil {
226 err = ew;
227 break;
228 }
229 if nr != nw {
Russ Cox64684cc2009-06-22 13:26:13 -0700230 err = ErrShortWrite;
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800231 break;
232 }
Robert Griesemer79d94d52008-11-18 18:08:05 -0800233 }
Russ Cox64684cc2009-06-22 13:26:13 -0700234 if er == os.EOF {
Robert Griesemer79d94d52008-11-18 18:08:05 -0800235 break;
236 }
Russ Cox64684cc2009-06-22 13:26:13 -0700237 if er != nil {
238 err = er;
Robert Griesemer79d94d52008-11-18 18:08:05 -0800239 break;
240 }
241 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800242 return written, err
Robert Griesemer79d94d52008-11-18 18:08:05 -0800243}
Russ Coxbe869ba2009-05-18 13:31:56 -0700244
Russ Cox90dcd5f2009-08-26 16:23:54 -0700245// LimitReader returns a Reader that reads from r
246// but stops with os.EOF after n bytes.
247func LimitReader(r Reader, n int64) Reader {
248 return &limitedReader{r, n};
Russ Coxbe869ba2009-05-18 13:31:56 -0700249}
250
Russ Cox90dcd5f2009-08-26 16:23:54 -0700251type limitedReader struct {
252 r Reader;
253 n int64;
254}
255
256func (l *limitedReader) Read(p []byte) (n int, err os.Error) {
257 if l.n <= 0 {
Russ Cox64684cc2009-06-22 13:26:13 -0700258 return 0, os.EOF;
259 }
Russ Cox90dcd5f2009-08-26 16:23:54 -0700260 if int64(len(p)) > l.n {
261 p = p[0:l.n];
Russ Coxbe869ba2009-05-18 13:31:56 -0700262 }
Russ Cox90dcd5f2009-08-26 16:23:54 -0700263 n, err = l.r.Read(p);
264 l.n -= int64(n);
265 return;
Russ Coxbe869ba2009-05-18 13:31:56 -0700266}
Russ Coxe5962972009-08-31 16:34:43 -0700267
268// NewSectionReader returns a SectionReader that reads from r
269// starting at offset off and stops with os.EOF after n bytes.
270func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
271 return &SectionReader{r, off, off, off+n};
272}
273
274// SectionReader implements Read, Seek, and ReadAt on a section
275// of an underlying ReaderAt.
276type SectionReader struct {
277 r ReaderAt;
278 base int64;
279 off int64;
280 limit int64;
281}
282
283func (s *SectionReader) Read(p []byte) (n int, err os.Error) {
284 if s.off >= s.limit {
285 return 0, os.EOF;
286 }
287 if max := s.limit - s.off; int64(len(p)) > max {
288 p = p[0:max];
289 }
290 n, err = s.r.ReadAt(p, s.off);
291 s.off += int64(n);
292 return;
293}
294
295func (s *SectionReader) Seek(offset int64, whence int) (ret int64, err os.Error) {
296 switch whence {
297 default:
298 return 0, os.EINVAL
299 case 0:
300 offset += s.base
301 case 1:
302 offset += s.off
303 case 2:
304 offset += s.limit
305 }
306 if offset < s.off || offset > s.limit {
307 return 0, os.EINVAL
308 }
309 s.off = offset;
310 return offset - s.base, nil
311}
312
313func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err os.Error) {
314 if off < 0 || off >= s.limit - s.base {
315 return 0, os.EOF;
316 }
317 off += s.base;
318 if max := s.limit - off; int64(len(p)) > max {
319 p = p[0:max];
320 }
321 return s.r.ReadAt(p, off);
322}
323
Russ Coxf277ebf2009-09-01 16:11:17 -0700324// Size returns the size of the section in bytes.
325func (s *SectionReader) Size() int64 {
326 return s.limit - s.base
327}