// 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.

// This package implements buffered I/O.  It wraps an io.Reader or io.Writer
// object, creating another object (Reader or Writer) that also implements
// the interface but provides buffering and some help for textual I/O.
package bufio

import (
	"io";
	"os";
	"strconv";
	"utf8";
)


const (
	defaultBufSize = 4096;
)

// Errors introduced by this package.
type Error struct {
	os.ErrorString;
}

var (
	ErrInvalidUnreadByte	os.Error	= &Error{"bufio: invalid use of UnreadByte"};
	ErrBufferFull		os.Error	= &Error{"bufio: buffer full"};
	errInternal		os.Error	= &Error{"bufio: internal error"};
)

// BufSizeError is the error representing an invalid buffer size.
type BufSizeError int

func (b BufSizeError) String() string {
	return "bufio: bad buffer size " + strconv.Itoa(int(b))
}

func copySlice(dst []byte, src []byte) {
	for i := 0; i < len(dst); i++ {
		dst[i] = src[i]
	}
}


// Buffered input.

// Reader implements buffering for an io.Reader object.
type Reader struct {
	buf		[]byte;
	rd		io.Reader;
	r, w		int;
	err		os.Error;
	lastbyte	int;
}

// NewReaderSize creates a new Reader whose buffer has the specified size,
// which must be greater than zero.  If the argument io.Reader is already a
// Reader with large enough size, it returns the underlying Reader.
// It returns the Reader and any error.
func NewReaderSize(rd io.Reader, size int) (*Reader, os.Error) {
	if size <= 0 {
		return nil, BufSizeError(size)
	}
	// Is it already a Reader?
	b, ok := rd.(*Reader);
	if ok && len(b.buf) >= size {
		return b, nil
	}
	b = new(Reader);
	b.buf = make([]byte, size);
	b.rd = rd;
	b.lastbyte = -1;
	return b, nil;
}

// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) *Reader {
	b, err := NewReaderSize(rd, defaultBufSize);
	if err != nil {
		// cannot happen - defaultBufSize is a valid size
		panic("bufio: NewReader: ", err.String())
	}
	return b;
}

// 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 -= b.r;
	} else {
		b.w = 0
	}
	b.r = 0;

	// Read new data.
	n, e := b.rd.Read(b.buf[b.w:len(b.buf)]);
	b.w += n;
	if e != nil {
		b.err = e
	}
}

// Read reads data into p.
// It returns the number of bytes read into p.
// If nn < len(p), also returns an error explaining
// why the read is short.  At EOF, the count will be
// zero and err will be os.EOF.
func (b *Reader) Read(p []byte) (nn int, err os.Error) {
	nn = 0;
	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.
				n, b.err = b.rd.Read(p);
				if n > 0 {
					b.lastbyte = int(p[n-1])
				}
				p = p[n:len(p)];
				nn += n;
				continue;
			}
			b.fill();
			continue;
		}
		if n > b.w-b.r {
			n = b.w - b.r
		}
		copySlice(p[0:n], b.buf[b.r:b.r+n]);
		p = p[n:len(p)];
		b.r += n;
		b.lastbyte = int(b.buf[b.r-1]);
		nn += n;
	}
	return nn, nil;
}

// ReadByte reads and returns a single byte.
// If no byte is available, returns an error.
func (b *Reader) ReadByte() (c byte, err os.Error) {
	for b.w == b.r {
		if b.err != nil {
			return 0, b.err
		}
		b.fill();
	}
	c = b.buf[b.r];
	b.r++;
	b.lastbyte = int(c);
	return c, nil;
}

// UnreadByte unreads the last byte.  Only the most recently read byte can be unread.
func (b *Reader) UnreadByte() os.Error {
	if b.r == b.w && b.lastbyte >= 0 {
		b.w = 1;
		b.r = 0;
		b.buf[0] = byte(b.lastbyte);
		b.lastbyte = -1;
		return nil;
	}
	if b.r <= 0 {
		return ErrInvalidUnreadByte
	}
	b.r--;
	b.lastbyte = -1;
	return nil;
}

// 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]) && b.err == nil {
		b.fill()
	}
	if b.r == b.w {
		return 0, 0, b.err
	}
	rune, size = int(b.buf[b.r]), 1;
	if rune >= 0x80 {
		rune, size = utf8.DecodeRune(b.buf[b.r:b.w])
	}
	b.r += size;
	b.lastbyte = int(b.buf[b.r-1]);
	return rune, size, nil;
}

// Helper function: look for byte c in array p,
// returning its index or -1.
func findByte(p []byte, c byte) int {
	for i := 0; i < len(p); i++ {
		if p[i] == c {
			return i
		}
	}
	return -1;
}

// Buffered returns the number of bytes that can be read from the current buffer.
func (b *Reader) Buffered() int	{ return b.w - b.r }

// ReadSlice reads until the first occurrence of delim in the input,
// returning a slice pointing at the bytes in the buffer.
// The bytes stop being valid at the next read call.
// If ReadSlice encounters an error before finding a delimiter,
// it returns all the data in the buffer and the error itself (often os.EOF).
// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
// Because the data returned from ReadSlice will be overwritten
// by the next I/O operation, most clients should use
// ReadBytes or ReadString instead.
// ReadSlice returns err != nil if and only if line does not end in delim.
func (b *Reader) ReadSlice(delim byte) (line []byte, err os.Error) {
	// Look in buffer.
	if i := findByte(b.buf[b.r:b.w], delim); i >= 0 {
		line1 := b.buf[b.r : b.r+i+1];
		b.r += i + 1;
		return line1, nil;
	}

	// Read more into buffer, until buffer fills or we find delim.
	for {
		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];
			b.r = n + i + 1;
			return line, nil;
		}

		// Buffer is full?
		if b.Buffered() >= len(b.buf) {
			return nil, ErrBufferFull
		}
	}
	panic("not reached");
}

// ReadBytes reads until the first occurrence of delim in the input,
// returning a string 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 os.EOF).
// ReadBytes returns err != nil if and only if line does not end in delim.
func (b *Reader) ReadBytes(delim byte) (line []byte, err os.Error) {
	// Use ReadSlice to look for array,
	// accumulating full buffers.
	var frag []byte;
	var full [][]byte;
	nfull := 0;
	err = nil;

	for {
		var e os.Error;
		frag, e = b.ReadSlice(delim);
		if e == nil {	// got final fragment
			break
		}
		if e != ErrBufferFull {	// unexpected error
			err = e;
			break;
		}

		// Read bytes out of buffer.
		buf := make([]byte, b.Buffered());
		var n int;
		n, e = b.Read(buf);
		if e != nil {
			frag = buf[0:n];
			err = e;
			break;
		}
		if n != len(buf) {
			frag = buf[0:n];
			err = errInternal;
			break;
		}

		// Grow list if needed.
		if full == nil {
			full = make([][]byte, 16)
		} else if nfull >= len(full) {
			newfull := make([][]byte, len(full)*2);
			for i := 0; i < len(full); i++ {
				newfull[i] = full[i]
			}
			full = newfull;
		}

		// Save buffer
		full[nfull] = buf;
		nfull++;
	}

	// Allocate new buffer to hold the full pieces and the fragment.
	n := 0;
	for i := 0; i < nfull; i++ {
		n += len(full[i])
	}
	n += len(frag);

	// Copy full pieces and fragment in.
	buf := make([]byte, n);
	n = 0;
	for i := 0; i < nfull; i++ {
		copySlice(buf[n:n+len(full[i])], full[i]);
		n += len(full[i]);
	}
	copySlice(buf[n:n+len(frag)], frag);
	return buf, err;
}

// 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 os.EOF).
// ReadString returns err != nil if and only if line does not end in delim.
func (b *Reader) ReadString(delim byte) (line string, err os.Error) {
	bytes, e := b.ReadBytes(delim);
	return string(bytes), e;
}


// buffered output

// Writer implements buffering for an io.Writer object.
type Writer struct {
	err	os.Error;
	buf	[]byte;
	n	int;
	wr	io.Writer;
}

// NewWriterSize creates a new Writer whose buffer has the specified size,
// which must be greater than zero. If the argument io.Writer is already a
// Writer with large enough size, it returns the underlying Writer.
// It returns the Writer and any error.
func NewWriterSize(wr io.Writer, size int) (*Writer, os.Error) {
	if size <= 0 {
		return nil, BufSizeError(size)
	}
	// Is it already a Writer?
	b, ok := wr.(*Writer);
	if ok && len(b.buf) >= size {
		return b, nil
	}
	b = new(Writer);
	b.buf = make([]byte, size);
	b.wr = wr;
	return b, nil;
}

// NewWriter returns a new Writer whose buffer has the default size.
func NewWriter(wr io.Writer) *Writer {
	b, err := NewWriterSize(wr, defaultBufSize);
	if err != nil {
		// cannot happen - defaultBufSize is valid size
		panic("bufio: NewWriter: ", err.String())
	}
	return b;
}

// Flush writes any buffered data to the underlying io.Writer.
func (b *Writer) Flush() os.Error {
	if b.err != nil {
		return b.err
	}
	n, e := b.wr.Write(b.buf[0:b.n]);
	if n < b.n && e == nil {
		e = io.ErrShortWrite
	}
	if e != nil {
		if n > 0 && n < b.n {
			copySlice(b.buf[0:b.n-n], b.buf[n:b.n])
		}
		b.n -= n;
		b.err = e;
		return e;
	}
	b.n = 0;
	return nil;
}

// Available returns how many bytes are unused in the buffer.
func (b *Writer) Available() int	{ return len(b.buf) - b.n }

// Buffered returns the number of bytes that have been written into the current buffer.
func (b *Writer) Buffered() int	{ return b.n }

// Write writes the contents of p into the buffer.
// It returns the number of bytes written.
// If nn < len(p), also returns an error explaining
// why the write is short.
func (b *Writer) Write(p []byte) (nn int, err os.Error) {
	if b.err != nil {
		return 0, b.err
	}
	nn = 0;
	for len(p) > 0 {
		n := b.Available();
		if n <= 0 {
			if b.Flush(); b.err != nil {
				break
			}
			n = b.Available();
		}
		if b.Available() == 0 && len(p) >= len(b.buf) {
			// Large write, empty buffer.
			// Write directly from p to avoid copy.
			n, b.err = b.wr.Write(p);
			nn += n;
			p = p[n:len(p)];
			if b.err != nil {
				break
			}
			continue;
		}
		if n > len(p) {
			n = len(p)
		}
		copySlice(b.buf[b.n:b.n+n], p[0:n]);
		b.n += n;
		nn += n;
		p = p[n:len(p)];
	}
	return nn, b.err;
}

// WriteByte writes a single byte.
func (b *Writer) WriteByte(c byte) os.Error {
	if b.err != nil {
		return b.err
	}
	if b.Available() <= 0 && b.Flush() != nil {
		return b.err
	}
	b.buf[b.n] = c;
	b.n++;
	return nil;
}

// WriteString writes a string.
func (b *Writer) WriteString(s string) os.Error {
	if b.err != nil {
		return b.err
	}
	// Common case, worth making fast.
	if b.Available() >= len(s) || len(b.buf) >= len(s) && b.Flush() == nil {
		for i := 0; i < len(s); i++ {	// loop over bytes, not runes.
			b.buf[b.n] = s[i];
			b.n++;
		}
		return nil;
	}
	for i := 0; i < len(s); i++ {	// loop over bytes, not runes.
		b.WriteByte(s[i])
	}
	return b.err;
}

// buffered input and output

// ReadWriter stores pointers to a Reader and a Writer.
// It implements io.ReadWriter.
type ReadWriter struct {
	*Reader;
	*Writer;
}

// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
	return &ReadWriter{r, w}
}
