return b;
}
-//.fill reads a new chunk into the buffer.
-func (b *Reader) fill() os.Error {
- if b.err != nil {
- return b.err
- }
-
+// fill reads a new chunk into the buffer.
+func (b *Reader) fill() {
// Slide existing data to beginning.
if b.w > b.r {
copySlice(b.buf[0:b.w-b.r], b.buf[b.r:b.w]);
b.w += n;
if e != nil {
b.err = e;
- return e
}
- return nil
}
// Read reads data into p.
for len(p) > 0 {
n := len(p);
if b.w == b.r {
+ if b.err != nil {
+ return nn, b.err
+ }
if len(p) >= len(b.buf) {
// Large read, empty buffer.
// Read directly into p to avoid copy.
}
p = p[n:len(p)];
nn += n;
- if b.err != nil {
- return nn, b.err
- }
continue;
}
b.fill();
- if b.err != nil {
- return nn, b.err
- }
+ continue;
}
if n > b.w - b.r {
n = b.w - b.r
// ReadByte reads and returns a single byte.
// If no byte is available, returns an error.
func (b *Reader) ReadByte() (c byte, err os.Error) {
- if b.w == b.r {
- b.fill();
+ for b.w == b.r {
if b.err != nil {
return 0, b.err
}
+ b.fill();
}
c = b.buf[b.r];
b.r++;
// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
func (b *Reader) UnreadByte() os.Error {
- if b.err != nil {
- return b.err
- }
if b.r == b.w && b.lastbyte >= 0 {
b.w = 1;
b.r = 0;
// ReadRune reads a single UTF-8 encoded Unicode character and returns the
// rune and its size in bytes.
func (b *Reader) ReadRune() (rune int, size int, err os.Error) {
- for b.r + utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) {
+ for b.r + utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil {
b.fill();
- if b.err != nil {
- if b.r == b.w {
- return 0, 0, b.err;
- }
- break;
- }
+ }
+ if b.r == b.w {
+ return 0, 0, b.err;
}
rune, size = int(b.buf[b.r]), 1;
if rune >= 0x80 {
// For internal or advanced use only; most uses should
// call ReadLineString or ReadLineBytes instead.
func (b *Reader) ReadLineSlice(delim byte) (line []byte, err os.Error) {
- if b.err != nil {
- return nil, b.err
- }
-
// Look in buffer.
if i := findByte(b.buf[b.r:b.w], delim); i >= 0 {
line1 := b.buf[b.r:b.r+i+1];
// Read more into buffer, until buffer fills or we find delim.
for {
- n := b.Buffered();
- b.fill();
if b.err != nil {
line := b.buf[b.r:b.w];
b.r = b.w;
return line, b.err
}
+ n := b.Buffered();
+ b.fill();
+
// Search new part of buffer
if i := findByte(b.buf[n:b.w], delim); i >= 0 {
line := b.buf[0:n+i+1];
// and the error. (It can't leave the data in the buffer because
// it might have read more than the buffer size.)
func (b *Reader) ReadLineBytes(delim byte) (line []byte, err os.Error) {
- if b.err != nil {
- return nil, b.err
- }
-
// Use ReadLineSlice to look for array,
// accumulating full buffers.
var frag []byte;
// If savedelim, keep delim in the result; otherwise drop it.
func (b *Reader) ReadLineString(delim byte, savedelim bool) (line string, err os.Error) {
bytes, e := b.ReadLineBytes(delim);
- if e != nil {
- return string(bytes), e
- }
- if !savedelim {
- bytes = bytes[0:len(bytes)-1]
+ if n := len(bytes); !savedelim && n > 0 && bytes[n-1] == delim {
+ bytes = bytes[0:n-1]
}
- return string(bytes), nil
+ return string(bytes), e;
}
import (
"io";
"os";
+ "bytes";
)
+// OneByteReader returns a Reader that implements
+// each non-empty Read by reading one byte from r.
+func OneByteReader(r io.Reader) io.Reader {
+ return &oneByteReader{r};
+}
+
type oneByteReader struct {
r io.Reader;
}
return r.r.Read(p[0:1]);
}
-// OneByteReader returns a Reader that implements
-// each non-empty Read by reading one byte from r.
-func OneByteReader(r io.Reader) io.Reader {
- return &oneByteReader{r};
+// HalfReader returns a Reader that implements Read
+// by reading half as many requested bytes from r.
+func HalfReader(r io.Reader) io.Reader {
+ return &halfReader{r};
}
type halfReader struct {
return r.r.Read(p[0:(len(p)+1)/2]);
}
-// HalfReader returns a Reader that implements Read
-// by reading half as many requested bytes from r.
-func HalfReader(r io.Reader) io.Reader {
- return &halfReader{r};
+
+// DataErrReader returns a Reader that returns the final
+// error with the last data read, instead of by itself with
+// zero bytes of data.
+func DataErrReader(r io.Reader) io.Reader {
+ return &dataErrReader{r, nil, make([]byte, 1024)};
+}
+
+type dataErrReader struct {
+ r io.Reader;
+ unread []byte;
+ data []byte;
+}
+
+func (r *dataErrReader) Read(p []byte) (n int, err os.Error) {
+ // loop because first call needs two reads:
+ // one to get data and a second to look for an error.
+ for {
+ if len(r.unread) == 0 {
+ n1, err1 := r.r.Read(r.data);
+ r.unread = r.data[0:n1];
+ err = err1;
+ }
+ if n > 0 {
+ break;
+ }
+ n = bytes.Copy(p, r.unread);
+ r.unread = r.unread[n:len(r.unread)];
+ }
+ return;
}