URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [bytes/] [buffer.go] - Rev 752
Go to most recent revision | Compare with Previous | Blame | View Log
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package bytes// Simple byte buffer for marshaling data.import ("errors""io""unicode/utf8")// A Buffer is a variable-sized buffer of bytes with Read and Write methods.// The zero value for Buffer is an empty buffer ready to use.type Buffer struct {buf []byte // contents are the bytes buf[off : len(buf)]off int // read at &buf[off], write at &buf[len(buf)]runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Runebootstrap [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 intconst (opInvalid readOp = iota // Non-read operation.opReadRune // Read rune.opRead // Any other read operation.)// ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.var ErrTooLarge = errors.New("bytes.Buffer: too large")// 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// are no intervening method calls on the Buffer.func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }// String returns the contents of the unread portion of the buffer// as a string. If the Buffer is a nil pointer, it returns "<nil>".func (b *Buffer) String() string {if b == nil {// Special case, useful in debugging.return "<nil>"}return string(b.buf[b.off:])}// Len returns the number of bytes of the unread portion of the buffer;// b.Len() == len(b.Bytes()).func (b *Buffer) Len() int { return len(b.buf) - b.off }// Truncate discards all but the first n unread bytes from the buffer.// It panics if n is negative or greater than the length of the buffer.func (b *Buffer) Truncate(n int) {b.lastRead = opInvalidswitch {case n < 0 || n > b.Len():panic("bytes.Buffer: truncation out of range")case n == 0:// Reuse buffer space.b.off = 0}b.buf = b.buf[0 : b.off+n]}// Reset resets the buffer so it has no content.// b.Reset() is the same as b.Truncate(0).func (b *Buffer) Reset() { b.Truncate(0) }// grow grows the buffer to guarantee space for n more bytes.// It returns the index where bytes should be written.// If the buffer can't grow it will panic with ErrTooLarge.func (b *Buffer) grow(n int) int {m := b.Len()// If buffer is empty, reset to recover space.if m == 0 && b.off != 0 {b.Truncate(0)}if len(b.buf)+n > cap(b.buf) {var buf []byteif b.buf == nil && n <= len(b.bootstrap) {buf = b.bootstrap[0:]} else {// not enough space anywherebuf = makeSlice(2*cap(b.buf) + n)copy(buf, b.buf[b.off:])}b.buf = bufb.off = 0}b.buf = b.buf[0 : b.off+m+n]return b.off + m}// Write appends the contents of p to the buffer. The return// value n is the length of p; err is always nil.// If the buffer becomes too large, Write will panic with// ErrTooLarge.func (b *Buffer) Write(p []byte) (n int, err error) {b.lastRead = opInvalidm := b.grow(len(p))return copy(b.buf[m:], p), nil}// WriteString appends the contents of s to the buffer. The return// value n is the length of s; err is always nil.// If the buffer becomes too large, WriteString will panic with// ErrTooLarge.func (b *Buffer) WriteString(s string) (n int, err error) {b.lastRead = opInvalidm := b.grow(len(s))return copy(b.buf[m:], s), nil}// MinRead is the minimum slice size passed to a Read call by// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond// what is required to hold the contents of r, ReadFrom will not grow the// underlying buffer.const MinRead = 512// ReadFrom reads data from r until EOF and appends it to the buffer.// The return value n is the number of bytes read.// Any error except io.EOF encountered during the read// is also returned.// If the buffer becomes too large, ReadFrom will panic with// ErrTooLarge.func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {b.lastRead = opInvalid// If buffer is empty, reset to recover space.if b.off >= len(b.buf) {b.Truncate(0)}for {if free := cap(b.buf) - len(b.buf); free < MinRead {// not enough space at endnewBuf := b.bufif b.off+free < MinRead {// not enough space using beginning of buffer;// double buffer capacitynewBuf = makeSlice(2*cap(b.buf) + MinRead)}copy(newBuf, b.buf[b.off:])b.buf = newBuf[:len(b.buf)-b.off]b.off = 0}m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])b.buf = b.buf[0 : len(b.buf)+m]n += int64(m)if e == io.EOF {break}if e != nil {return n, e}}return n, nil // err is EOF, so return nil explicitly}// makeSlice allocates a slice of size n. If the allocation fails, it panics// with ErrTooLarge.func makeSlice(n int) []byte {// If the make fails, give a known error.defer func() {if recover() != nil {panic(ErrTooLarge)}}()return make([]byte, n)}// WriteTo writes data to w until the buffer is drained or an error// occurs. The return value n is the number of bytes written; it always// fits into an int, but it is int64 to match the io.WriterTo interface.// Any error encountered during the write is also returned.func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {b.lastRead = opInvalidif b.off < len(b.buf) {m, e := w.Write(b.buf[b.off:])b.off += mn = int64(m)if e != nil {return n, e}// otherwise all bytes were written, by definition of// Write method in io.Writer}// Buffer is now empty; reset.b.Truncate(0)return}// WriteByte appends the byte c to the buffer.// The returned error is always nil, but is included// to match bufio.Writer's WriteByte.// If the buffer becomes too large, WriteByte will panic with// ErrTooLarge.func (b *Buffer) WriteByte(c byte) error {b.lastRead = opInvalidm := b.grow(1)b.buf[m] = creturn nil}// WriteRune appends the UTF-8 encoding of Unicode// code point r to the buffer, returning its length and// an error, which is always nil but is included// to match bufio.Writer's WriteRune.// If the buffer becomes too large, WriteRune will panic with// ErrTooLarge.func (b *Buffer) WriteRune(r rune) (n int, err error) {if r < utf8.RuneSelf {b.WriteByte(byte(r))return 1, nil}n = utf8.EncodeRune(b.runeBytes[0:], r)b.Write(b.runeBytes[0:n])return n, nil}// Read reads the next len(p) bytes from the buffer or until the buffer// is drained. The return value n is the number of bytes read. If the// buffer has no data to return, err is io.EOF (unless len(p) is zero);// otherwise it is nil.func (b *Buffer) Read(p []byte) (n int, err error) {b.lastRead = opInvalidif b.off >= len(b.buf) {// Buffer is empty, reset to recover space.b.Truncate(0)if len(p) == 0 {return}return 0, io.EOF}n = copy(p, b.buf[b.off:])b.off += nif n > 0 {b.lastRead = opRead}return}// Next returns a slice containing the next n bytes from the buffer,// advancing the buffer as if the bytes had been returned by Read.// 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 = opInvalidm := b.Len()if n > m {n = m}data := b.buf[b.off : b.off+n]b.off += nif 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 io.EOF.func (b *Buffer) ReadByte() (c byte, err error) {b.lastRead = opInvalidif b.off >= len(b.buf) {// Buffer is empty, reset to recover space.b.Truncate(0)return 0, io.EOF}c = b.buf[b.off]b.off++b.lastRead = opReadreturn c, nil}// ReadRune reads and returns the next UTF-8-encoded// Unicode code point from the buffer.// If no bytes are available, the error returned is io.EOF.// If the bytes are an erroneous UTF-8 encoding, it// consumes one byte and returns U+FFFD, 1.func (b *Buffer) ReadRune() (r rune, size int, err error) {b.lastRead = opInvalidif b.off >= len(b.buf) {// Buffer is empty, reset to recover space.b.Truncate(0)return 0, 0, io.EOF}b.lastRead = opReadRunec := b.buf[b.off]if c < utf8.RuneSelf {b.off++return rune(c), 1, nil}r, n := utf8.DecodeRune(b.buf[b.off:])b.off += nreturn 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() error {if b.lastRead != opReadRune {return errors.New("bytes.Buffer: UnreadRune: previous operation was not ReadRune")}b.lastRead = opInvalidif 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() error {if b.lastRead != opReadRune && b.lastRead != opRead {return errors.New("bytes.Buffer: UnreadByte: previous operation was not a read")}b.lastRead = opInvalidif b.off > 0 {b.off--}return nil}// ReadBytes reads until the first occurrence of delim in the input,// returning a slice containing the data up to and including the delimiter.// If ReadBytes encounters an error before finding a delimiter,// it returns the data read before the error and the error itself (often io.EOF).// ReadBytes returns err != nil if and only if the returned data does not end in// delim.func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {i := IndexByte(b.buf[b.off:], delim)size := i + 1if i < 0 {size = len(b.buf) - b.offerr = io.EOF}line = make([]byte, size)copy(line, b.buf[b.off:])b.off += sizereturn}// ReadString reads until the first occurrence of delim in the input,// returning a string containing the data up to and including the delimiter.// If ReadString encounters an error before finding a delimiter,// it returns the data read before the error and the error itself (often io.EOF).// ReadString returns err != nil if and only if the returned data does not end// in delim.func (b *Buffer) ReadString(delim byte) (line string, err error) {bytes, err := b.ReadBytes(delim)return string(bytes), err}// 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 size the internal buffer for writing. To do that,// buf should have the desired capacity but a length of zero.//// In most cases, new(Buffer) (or just declaring a Buffer variable) is// sufficient to initialize a Buffer.func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }// NewBufferString creates and initializes a new Buffer using string s as its// initial contents. It is intended to prepare a buffer to read an existing// string.//// In most cases, new(Buffer) (or just declaring a Buffer variable) is// sufficient to initialize a Buffer.func NewBufferString(s string) *Buffer {return &Buffer{buf: []byte(s)}}
Go to most recent revision | Compare with Previous | Blame | View Log
