blob: 37acab4c71821eb068207c6014a16230af96216c [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 (
13 "os";
14 "syscall";
15)
16
Rob Pike7bb335c2009-03-06 03:43:44 -080017// ErrEOF is the error returned by Readn and Copyn when they encounter EOF.
Russ Cox839a6842009-01-20 14:40:40 -080018var ErrEOF = os.NewError("EOF")
Russ Cox7c9e2c22008-09-12 16:42:53 -070019
Rob Pike7bb335c2009-03-06 03:43:44 -080020// Read is the interface that wraps the basic Read method.
Russ Cox839a6842009-01-20 14:40:40 -080021type Read interface {
Russ Coxd47d8882008-12-18 22:37:22 -080022 Read(p []byte) (n int, err *os.Error);
Russ Cox7c9e2c22008-09-12 16:42:53 -070023}
24
Rob Pike7bb335c2009-03-06 03:43:44 -080025// Write is the interface that wraps the basic Write method.
Russ Cox839a6842009-01-20 14:40:40 -080026type Write interface {
Russ Coxd47d8882008-12-18 22:37:22 -080027 Write(p []byte) (n int, err *os.Error);
Russ Cox7c9e2c22008-09-12 16:42:53 -070028}
29
Rob Pike7bb335c2009-03-06 03:43:44 -080030// Close is the interface that wraps the basic Close method.
Russ Cox78906c32009-02-16 16:32:30 -080031type Close interface {
32 Close() *os.Error;
33}
34
Rob Pike7bb335c2009-03-06 03:43:44 -080035// ReadWrite is the interface that groups the basic Read and Write methods.
Russ Cox839a6842009-01-20 14:40:40 -080036type ReadWrite interface {
Russ Coxdfad8ea2009-02-16 16:37:49 -080037 Read;
38 Write;
Russ Cox9350ef42008-09-17 13:49:23 -070039}
40
Rob Pike7bb335c2009-03-06 03:43:44 -080041// ReadClose is the interface that groups the basic Read and Close methods.
Russ Cox78906c32009-02-16 16:32:30 -080042type ReadClose interface {
Russ Coxdfad8ea2009-02-16 16:37:49 -080043 Read;
44 Close;
Russ Cox78906c32009-02-16 16:32:30 -080045}
46
Rob Pike7bb335c2009-03-06 03:43:44 -080047// WriteClose is the interface that groups the basic Write and Close methods.
Russ Cox78906c32009-02-16 16:32:30 -080048type WriteClose interface {
Russ Coxdfad8ea2009-02-16 16:37:49 -080049 Write;
50 Close;
Russ Cox7c7a5252008-10-20 12:37:07 -070051}
52
Rob Pike7bb335c2009-03-06 03:43:44 -080053// ReadWriteClose is the interface that groups the basic Read, Write and Close methods.
Russ Cox78906c32009-02-16 16:32:30 -080054type ReadWriteClose interface {
Russ Coxdfad8ea2009-02-16 16:37:49 -080055 Read;
56 Write;
57 Close;
Russ Cox9aa28f92009-02-03 14:16:22 -080058}
59
Rob Pike704bc9d2009-02-06 17:54:26 -080060// Convert a string to an array of bytes for easy marshaling.
Rob Pike704bc9d2009-02-06 17:54:26 -080061func StringBytes(s string) []byte {
62 b := make([]byte, len(s));
63 for i := 0; i < len(s); i++ {
64 b[i] = s[i];
Russ Cox7c9e2c22008-09-12 16:42:53 -070065 }
Rob Pike704bc9d2009-02-06 17:54:26 -080066 return b;
67}
68
Rob Pike7bb335c2009-03-06 03:43:44 -080069// WriteString writes the contents of the string s to w, which accepts an array of bytes.
Rob Pike704bc9d2009-02-06 17:54:26 -080070func WriteString(w Write, s string) (n int, err *os.Error) {
71 return w.Write(StringBytes(s))
Russ Cox7c9e2c22008-09-12 16:42:53 -070072}
Rob Pike6ee7fe52008-11-11 17:28:36 -080073
Rob Pike7bb335c2009-03-06 03:43:44 -080074// Readn reads r until the buffer buf is full, or until EOF or error.
Russ Coxe9b40582009-03-02 16:12:04 -080075func Readn(r Read, buf []byte) (n int, err *os.Error) {
Rob Pike6ee7fe52008-11-11 17:28:36 -080076 n = 0;
77 for n < len(buf) {
Russ Coxe9b40582009-03-02 16:12:04 -080078 nn, e := r.Read(buf[n:len(buf)]);
Rob Pike6ee7fe52008-11-11 17:28:36 -080079 if nn > 0 {
80 n += nn
81 }
82 if e != nil {
83 return n, e
84 }
85 if nn <= 0 {
86 return n, ErrEOF // no error but insufficient data
87 }
88 }
89 return n, nil
90}
91
92// Convert something that implements Read into something
93// whose Reads are always Readn
Russ Cox78906c32009-02-16 16:32:30 -080094type fullRead struct {
Russ Coxe9b40582009-03-02 16:12:04 -080095 r Read;
Rob Pike6ee7fe52008-11-11 17:28:36 -080096}
97
Russ Coxe9b40582009-03-02 16:12:04 -080098func (fr *fullRead) Read(p []byte) (n int, err *os.Error) {
99 n, err = Readn(fr.r, p);
Rob Pike6ee7fe52008-11-11 17:28:36 -0800100 return n, err
101}
102
Rob Pike7bb335c2009-03-06 03:43:44 -0800103// MakeFullReader takes r, an implementation of Read, and returns an object
104// that still implements Read but always calls Readn underneath.
Russ Coxe9b40582009-03-02 16:12:04 -0800105func MakeFullReader(r Read) Read {
106 if fr, ok := r.(*fullRead); ok {
Russ Cox78906c32009-02-16 16:32:30 -0800107 // already a fullRead
Russ Coxe9b40582009-03-02 16:12:04 -0800108 return r
Rob Pike6ee7fe52008-11-11 17:28:36 -0800109 }
Russ Coxbe2edb52009-03-03 08:39:12 -0800110 return &fullRead{r}
Rob Pike6ee7fe52008-11-11 17:28:36 -0800111}
Robert Griesemer79d94d52008-11-18 18:08:05 -0800112
Rob Pike7bb335c2009-03-06 03:43:44 -0800113// Copy n copies n bytes (or until EOF is reached) from src to dst.
114// It returns the number of bytes copied and the error, if any.
Russ Cox839a6842009-01-20 14:40:40 -0800115func Copyn(src Read, dst Write, n int64) (written int64, err *os.Error) {
Russ Cox55645042009-01-06 15:19:02 -0800116 buf := make([]byte, 32*1024);
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800117 for written < n {
Robert Griesemer60ee27d2008-11-19 10:20:52 -0800118 l := len(buf);
119 if d := n - written; d < int64(l) {
120 l = int(d);
Robert Griesemer79d94d52008-11-18 18:08:05 -0800121 }
122 nr, er := src.Read(buf[0 : l]);
123 if nr > 0 {
124 nw, ew := dst.Write(buf[0 : nr]);
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800125 if nw > 0 {
126 written += int64(nw);
127 }
128 if ew != nil {
Robert Griesemer79d94d52008-11-18 18:08:05 -0800129 err = ew;
130 break;
131 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800132 if nr != nw {
133 err = os.EIO;
134 break;
135 }
136 }
137 if er != nil {
138 err = er;
139 break;
140 }
141 if nr == 0 {
142 err = ErrEOF;
143 break;
144 }
145 }
146 return written, err
147}
148
Rob Pike7bb335c2009-03-06 03:43:44 -0800149// Copy copies from src to dst until EOF is reached.
150// It returns the number of bytes copied and the error, if any.
Russ Cox839a6842009-01-20 14:40:40 -0800151func Copy(src Read, dst Write) (written int64, err *os.Error) {
Russ Cox55645042009-01-06 15:19:02 -0800152 buf := make([]byte, 32*1024);
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800153 for {
154 nr, er := src.Read(buf);
155 if nr > 0 {
156 nw, ew := dst.Write(buf[0:nr]);
157 if nw > 0 {
158 written += int64(nw);
159 }
160 if ew != nil {
161 err = ew;
162 break;
163 }
164 if nr != nw {
165 err = os.EIO;
166 break;
167 }
Robert Griesemer79d94d52008-11-18 18:08:05 -0800168 }
169 if er != nil {
170 err = er;
171 break;
172 }
173 if nr == 0 {
174 break;
175 }
176 }
Russ Cox9dc4b1c2008-11-18 18:45:51 -0800177 return written, err
Robert Griesemer79d94d52008-11-18 18:08:05 -0800178}