// 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 base64 implements base64 encoding as specified by RFC 4648.
package base64

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

/*
 * Encodings
 */

// Encoding is a radix 64 encoding/decoding scheme, defined by a
// 64-character alphabet.  The most common encoding is the "base64"
// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
// (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
// the standard encoding with - and _ substituted for + and /.
type Encoding struct {
	encode string;
	decodeMap [256]byte;
}

const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

// NewEncoding returns a new Encoding defined by the given alphabet,
// which must be a 64-byte string.
func NewEncoding(encoder string) *Encoding {
	e := new(Encoding);
	e.encode = encoder;
	for i := 0; i < len(e.decodeMap); i++ {
		e.decodeMap[i] = 0xFF;
	}
	for i := 0; i < len(encoder); i++ {
		e.decodeMap[encoder[i]] = byte(i);
	}
	return e;
}

// StdEncoding is the standard base64 encoding, as defined in
// RFC 4648.
var StdEncoding = NewEncoding(encodeStd);

// URLEncoding is the alternate base64 encoding defined in RFC 4648.
// It is typically used in URLs and file names.
var URLEncoding = NewEncoding(encodeURL);

/*
 * Encoder
 */

// Encode encodes src using the encoding enc, writing
// EncodedLen(len(input)) bytes to dst.
//
// The encoding pads the output to a multiple of 4 bytes,
// so Encode is not appropriate for use on individual blocks
// of a large data stream.  Use NewEncoder() instead.
func (enc *Encoding) Encode(src, dst []byte) {
	if len(src) == 0 {
		return;
	}

	for len(src) > 0 {
		dst[0] = 0;
		dst[1] = 0;
		dst[2] = 0;
		dst[3] = 0;

		// Unpack 4x 6-bit source blocks into a 4 byte
		// destination quantum
		switch len(src) {
		default:
			dst[3] |= src[2]&0x3F;
			dst[2] |= src[2]>>6;
			fallthrough;
		case 2:
			dst[2] |= (src[1]<<2)&0x3F;
			dst[1] |= src[1]>>4;
			fallthrough;
		case 1:
			dst[1] |= (src[0]<<4)&0x3F;
			dst[0] |= src[0]>>2;
		}

		// Encode 6-bit blocks using the base64 alphabet
		for j := 0; j < 4; j++ {
			dst[j] = enc.encode[dst[j]];
		}

		// Pad the final quantum
		if len(src) < 3 {
			dst[3] = '=';
			if len(src) < 2 {
				dst[2] = '=';
			}
			break;
		}

		src = src[3:len(src)];
		dst = dst[4:len(dst)];
	}
}

type encoder struct {
	err os.Error;
	enc *Encoding;
	w io.Writer;
	buf [3]byte;		// buffered data waiting to be encoded
	nbuf int;			// number of bytes in buf
	out [1024]byte;		// output buffer
}

func (e *encoder) Write(p []byte) (n int, err os.Error) {
	if e.err != nil {
		return 0, e.err;
	}

	// Leading fringe.
	if e.nbuf > 0 {
		var i int;
		for i = 0; i < len(p) && e.nbuf < 3; i++ {
			e.buf[e.nbuf] = p[i];
			e.nbuf++;
		}
		n += i;
		p = p[i:len(p)];
		if e.nbuf < 3 {
			return;
		}
		e.enc.Encode(&e.buf, &e.out);
		var _ int;
		if _, e.err = e.w.Write(e.out[0:4]); e.err != nil {
			return n, e.err;
		}
		e.nbuf = 0;
	}

	// Large interior chunks.
	for len(p) > 3 {
		nn := len(e.out)/4 * 3;
		if nn > len(p) {
			nn = len(p);
		}
		nn -= nn % 3;
		if nn > 0 {
			e.enc.Encode(p[0:nn], &e.out);
			var _ int;
			if _, e.err = e.w.Write(e.out[0:nn/3*4]); e.err != nil {
				return n, e.err;
			}
		}
		n += nn;
		p = p[nn:len(p)];
	}

	// Trailing fringe.
	for i := 0; i < len(p); i++ {
		e.buf[i] = p[i];
	}
	e.nbuf = len(p);
	n += len(p);
	return;
}

// Close flushes any pending output from the encoder.
// It is an error to call Write after calling Close.
func (e *encoder) Close() os.Error {
	// If there's anything left in the buffer, flush it out
	if e.err == nil && e.nbuf > 0 {
		e.enc.Encode(e.buf[0:e.nbuf], &e.out);
		e.nbuf = 0;
		var _ int;
		_, e.err = e.w.Write(e.out[0:4]);
	}
	return e.err;
}

// NewEncoder returns a new base64 stream encoder.  Data written to
// the returned writer will be encoded using enc and then written to w.
// Base64 encodings operate in 4-byte blocks; when finished
// writing, the caller must Close the returned encoder to flush any
// partially written blocks.
func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
	return &encoder{enc: enc, w: w};
}

// EncodedLen returns the length in bytes of the base64 encoding
// of an input buffer of length n.
func (enc *Encoding) EncodedLen(n int) int {
	return (n+2)/3*4;
}

/*
 * Decoder
 */

type CorruptInputError int64;

func (e CorruptInputError) String() string {
	return "illegal base64 data at input byte" + strconv.Itoa64(int64(e));
}

// decode is like Decode, but returns an additional 'end' value, which
// indicates if end-of-message padding was encountered and thus any
// additional data is an error.  decode also assumes len(src)%4==0,
// since it is meant for internal use.
func (enc *Encoding) decode(src, dst []byte) (n int, end bool, err os.Error) {
	for i := 0; i < len(src)/4 && !end; i++ {
		// Decode quantum using the base64 alphabet
		var dbuf [4]byte;
		dlen := 4;

	dbufloop:
		for j := 0; j < 4; j++ {
			in := src[i*4+j];
			if in == '=' && j >= 2 && i == len(src)/4 - 1 {
				// We've reached the end and there's
				// padding
				if src[i*4+3] != '=' {
					return n, false, CorruptInputError(i*4+2);
				}
				dlen = j;
				end = true;
				break dbufloop;
			}
			dbuf[j] = enc.decodeMap[in];
			if dbuf[j] == 0xFF {
				return n, false, CorruptInputError(i*4+j);
			}
		}

		// Pack 4x 6-bit source blocks into 3 byte destination
		// quantum
		switch dlen {
		case 4:
			dst[i*3+2] = dbuf[2]<<6 | dbuf[3];
			fallthrough;
		case 3:
			dst[i*3+1] = dbuf[1]<<4 | dbuf[2]>>2;
			fallthrough;
		case 2:
			dst[i*3+0] = dbuf[0]<<2 | dbuf[1]>>4;
		}
		n += dlen - 1;
	}

	return n, end, nil;
}

// Decode decodes src using the encoding enc.  It writes at most
// DecodedLen(len(src)) bytes to dst and returns the number of bytes
// written.  If src contains invalid base64 data, it will return the
// number of bytes successfully written and CorruptInputError.
func (enc *Encoding) Decode(src, dst []byte) (n int, err os.Error) {
	if len(src)%4 != 0 {
		return 0, CorruptInputError(len(src)/4*4);
	}

	var _ bool;
	n, _, err = enc.decode(src, dst);
	return;
}

type decoder struct {
	err os.Error;
	enc *Encoding;
	r io.Reader;
	end bool;		// saw end of message
	buf [1024]byte;	// leftover input
	nbuf int;
	out []byte;		// leftover decoded output
	outbuf [1024/4*3]byte;
}

func (d *decoder) Read(p []byte) (n int, err os.Error) {
	if d.err != nil {
		return 0, d.err;
	}

	// Use leftover decoded output from last read.
	if len(d.out) > 0 {
		n = bytes.Copy(p, d.out);
		d.out = d.out[n:len(d.out)];
		return n, nil;
	}

	// Read a chunk.
	nn := len(p)/3*4;
	if nn < 4 {
		nn = 4;
	}
	if nn > len(d.buf) {
		nn = len(d.buf);
	}
	nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf);
	d.nbuf += nn;
	if d.nbuf < 4 {
		return 0, d.err;
	}

	// Decode chunk into p, or d.out and then p if p is too small.
	nr := d.nbuf/4 * 4;
	nw := d.nbuf/4 * 3;
	if nw > len(p) {
		nw, d.end, d.err = d.enc.decode(d.buf[0:nr], &d.outbuf);
		d.out = d.outbuf[0:nw];
		n = bytes.Copy(p, d.out);
		d.out = d.out[n:len(d.out)];
	} else {
		n, d.end, d.err = d.enc.decode(d.buf[0:nr], p);
	}
	d.nbuf -= nr;
	for i := 0; i < d.nbuf; i++ {
		d.buf[i] = d.buf[i+nr];
	}

	if d.err == nil {
		d.err = err;
	}
	return n, d.err;
}

// NewDecoder constructs a new base64 stream decoder.
func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
	return &decoder{enc: enc, r: r};
}

// DecodeLen returns the maximum length in bytes of the decoded data
// corresponding to n bytes of base64-encoded data.
func (enc *Encoding) DecodedLen(n int) int {
	return n/4*3;
}
