aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/bytes/buffer.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2011-01-21 18:19:03 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-01-21 18:19:03 +0000
commitff5f50c52c421d75940ef9392211e3ab24d71332 (patch)
tree27d8768fb1d25696d3c40b42535eb5e073c278da /libgo/go/bytes/buffer.go
parentd6ed1c8903e728f4233122554bab5910853338bd (diff)
downloadgcc-ff5f50c52c421d75940ef9392211e3ab24d71332.zip
gcc-ff5f50c52c421d75940ef9392211e3ab24d71332.tar.gz
gcc-ff5f50c52c421d75940ef9392211e3ab24d71332.tar.bz2
Remove the types float and complex.
Update to current version of Go library. Update testsuite for removed types. * go-lang.c (go_langhook_init): Omit float_type_size when calling go_create_gogo. * go-c.h: Update declaration of go_create_gogo. From-SVN: r169098
Diffstat (limited to 'libgo/go/bytes/buffer.go')
-rw-r--r--libgo/go/bytes/buffer.go65
1 files changed, 63 insertions, 2 deletions
diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go
index 6f93869..62cf828 100644
--- a/libgo/go/bytes/buffer.go
+++ b/libgo/go/bytes/buffer.go
@@ -19,8 +19,20 @@ type Buffer struct {
off int // read at &buf[off], write at &buf[len(buf)]
runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
bootstrap [64]byte // memory to hold first slice; helps small buffers (Printf) avoid allocation.
+ lastRead readOp // last read operation, so that Unread* can work correctly.
}
+// The readOp constants describe the last action performed on
+// the buffer, so that UnreadRune and UnreadByte can
+// check for invalid usage.
+type readOp int
+
+const (
+ opInvalid readOp = iota // Non-read operation.
+ opReadRune // Read rune.
+ opRead // Any other read operation.
+)
+
// Bytes returns a slice of the contents of the unread portion of the buffer;
// len(b.Bytes()) == b.Len(). If the caller changes the contents of the
// returned slice, the contents of the buffer will change provided there
@@ -44,6 +56,7 @@ func (b *Buffer) Len() int { return len(b.buf) - b.off }
// Truncate discards all but the first n unread bytes from the buffer.
// It is an error to call b.Truncate(n) with n > b.Len().
func (b *Buffer) Truncate(n int) {
+ b.lastRead = opInvalid
if n == 0 {
// Reuse buffer space.
b.off = 0
@@ -82,6 +95,7 @@ func (b *Buffer) grow(n int) int {
// Write appends the contents of p to the buffer. The return
// value n is the length of p; err is always nil.
func (b *Buffer) Write(p []byte) (n int, err os.Error) {
+ b.lastRead = opInvalid
m := b.grow(len(p))
copy(b.buf[m:], p)
return len(p), nil
@@ -90,6 +104,7 @@ func (b *Buffer) Write(p []byte) (n int, err os.Error) {
// WriteString appends the contents of s to the buffer. The return
// value n is the length of s; err is always nil.
func (b *Buffer) WriteString(s string) (n int, err os.Error) {
+ b.lastRead = opInvalid
m := b.grow(len(s))
return copy(b.buf[m:], s), nil
}
@@ -105,6 +120,7 @@ const MinRead = 512
// Any error except os.EOF encountered during the read
// is also returned.
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err os.Error) {
+ b.lastRead = opInvalid
// If buffer is empty, reset to recover space.
if b.off >= len(b.buf) {
b.Truncate(0)
@@ -141,6 +157,7 @@ func (b *Buffer) ReadFrom(r io.Reader) (n int64, err os.Error) {
// occurs. The return value n is the number of bytes written.
// Any error encountered during the write is also returned.
func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) {
+ b.lastRead = opInvalid
for b.off < len(b.buf) {
m, e := w.Write(b.buf[b.off:])
n += int64(m)
@@ -158,6 +175,7 @@ func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) {
// The returned error is always nil, but is included
// to match bufio.Writer's WriteByte.
func (b *Buffer) WriteByte(c byte) os.Error {
+ b.lastRead = opInvalid
m := b.grow(1)
b.buf[m] = c
return nil
@@ -172,7 +190,7 @@ func (b *Buffer) WriteRune(r int) (n int, err os.Error) {
b.WriteByte(byte(r))
return 1, nil
}
- n = utf8.EncodeRune(r, b.runeBytes[0:])
+ n = utf8.EncodeRune(b.runeBytes[0:], r)
b.Write(b.runeBytes[0:n])
return n, nil
}
@@ -182,6 +200,7 @@ func (b *Buffer) WriteRune(r int) (n int, err os.Error) {
// buffer has no data to return, err is os.EOF even if len(p) is zero;
// otherwise it is nil.
func (b *Buffer) Read(p []byte) (n int, err os.Error) {
+ b.lastRead = opInvalid
if b.off >= len(b.buf) {
// Buffer is empty, reset to recover space.
b.Truncate(0)
@@ -189,6 +208,9 @@ func (b *Buffer) Read(p []byte) (n int, err os.Error) {
}
n = copy(p, b.buf[b.off:])
b.off += n
+ if n > 0 {
+ b.lastRead = opRead
+ }
return
}
@@ -197,18 +219,23 @@ func (b *Buffer) Read(p []byte) (n int, err os.Error) {
// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
// The slice is only valid until the next call to a read or write method.
func (b *Buffer) Next(n int) []byte {
+ b.lastRead = opInvalid
m := b.Len()
if n > m {
n = m
}
data := b.buf[b.off : b.off+n]
b.off += n
+ if n > 0 {
+ b.lastRead = opRead
+ }
return data
}
// ReadByte reads and returns the next byte from the buffer.
// If no byte is available, it returns error os.EOF.
func (b *Buffer) ReadByte() (c byte, err os.Error) {
+ b.lastRead = opInvalid
if b.off >= len(b.buf) {
// Buffer is empty, reset to recover space.
b.Truncate(0)
@@ -216,6 +243,7 @@ func (b *Buffer) ReadByte() (c byte, err os.Error) {
}
c = b.buf[b.off]
b.off++
+ b.lastRead = opRead
return c, nil
}
@@ -225,11 +253,13 @@ func (b *Buffer) ReadByte() (c byte, err os.Error) {
// If the bytes are an erroneous UTF-8 encoding, it
// consumes one byte and returns U+FFFD, 1.
func (b *Buffer) ReadRune() (r int, size int, err os.Error) {
+ b.lastRead = opInvalid
if b.off >= len(b.buf) {
// Buffer is empty, reset to recover space.
b.Truncate(0)
return 0, 0, os.EOF
}
+ b.lastRead = opReadRune
c := b.buf[b.off]
if c < utf8.RuneSelf {
b.off++
@@ -240,9 +270,40 @@ func (b *Buffer) ReadRune() (r int, size int, err os.Error) {
return r, n, nil
}
+// UnreadRune unreads the last rune returned by ReadRune.
+// If the most recent read or write operation on the buffer was
+// not a ReadRune, UnreadRune returns an error. (In this regard
+// it is stricter than UnreadByte, which will unread the last byte
+// from any read operation.)
+func (b *Buffer) UnreadRune() os.Error {
+ if b.lastRead != opReadRune {
+ return os.ErrorString("bytes.Buffer: UnreadRune: previous operation was not ReadRune")
+ }
+ b.lastRead = opInvalid
+ if b.off > 0 {
+ _, n := utf8.DecodeLastRune(b.buf[0:b.off])
+ b.off -= n
+ }
+ return nil
+}
+
+// UnreadByte unreads the last byte returned by the most recent
+// read operation. If write has happened since the last read, UnreadByte
+// returns an error.
+func (b *Buffer) UnreadByte() os.Error {
+ if b.lastRead != opReadRune && b.lastRead != opRead {
+ return os.ErrorString("bytes.Buffer: UnreadByte: previous operation was not a read")
+ }
+ b.lastRead = opInvalid
+ if b.off > 0 {
+ b.off--
+ }
+ return nil
+}
+
// NewBuffer creates and initializes a new Buffer using buf as its initial
// contents. It is intended to prepare a Buffer to read existing data. It
-// can also be used to to size the internal buffer for writing. To do that,
+// can also be used to size the internal buffer for writing. To do that,
// buf should have the desired capacity but a length of zero.
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }