// 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";
)


// TODO:
//	- maybe define an interface
//	- Reader: ReadRune, UnreadRune ?
//		could make ReadRune generic if we dropped UnreadRune
//	- buffered output

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};
}
