github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/encoding/base64/base64.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package base64 implements base64 encoding as specified by RFC 4648.
     6  package base64
     7  
     8  import (
     9  	"io"
    10  	"strconv"
    11  )
    12  
    13  /*
    14   * Encodings
    15   */
    16  
    17  // An Encoding is a radix 64 encoding/decoding scheme, defined by a
    18  // 64-character alphabet.  The most common encoding is the "base64"
    19  // encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
    20  // (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
    21  // the standard encoding with - and _ substituted for + and /.
    22  type Encoding struct {
    23  	encode    [64]byte
    24  	decodeMap [256]byte
    25  	padChar   rune
    26  }
    27  
    28  const (
    29  	StdPadding rune = '=' // Standard padding character
    30  	NoPadding  rune = -1  // No padding
    31  )
    32  
    33  const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    34  const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
    35  
    36  // NewEncoding returns a new padded Encoding defined by the given alphabet,
    37  // which must be a 64-byte string.
    38  // The resulting Encoding uses the default padding character ('='),
    39  // which may be changed or disabled via WithPadding.
    40  func NewEncoding(encoder string) *Encoding {
    41  	if len(encoder) != 64 {
    42  		panic("encoding alphabet is not 64-bytes long")
    43  	}
    44  
    45  	e := new(Encoding)
    46  	e.padChar = StdPadding
    47  	copy(e.encode[:], encoder)
    48  
    49  	for i := 0; i < len(e.decodeMap); i++ {
    50  		e.decodeMap[i] = 0xFF
    51  	}
    52  	for i := 0; i < len(encoder); i++ {
    53  		e.decodeMap[encoder[i]] = byte(i)
    54  	}
    55  	return e
    56  }
    57  
    58  // WithPadding creates a new encoding identical to enc except
    59  // with a specified padding character, or NoPadding to disable padding.
    60  func (enc Encoding) WithPadding(padding rune) *Encoding {
    61  	enc.padChar = padding
    62  	return &enc
    63  }
    64  
    65  // StdEncoding is the standard base64 encoding, as defined in
    66  // RFC 4648.
    67  var StdEncoding = NewEncoding(encodeStd)
    68  
    69  // URLEncoding is the alternate base64 encoding defined in RFC 4648.
    70  // It is typically used in URLs and file names.
    71  var URLEncoding = NewEncoding(encodeURL)
    72  
    73  // RawStdEncoding is the standard raw, unpadded base64 encoding,
    74  // as defined in RFC 4648 section 3.2.
    75  // This is the same as StdEncoding but omits padding characters.
    76  var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
    77  
    78  // URLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
    79  // It is typically used in URLs and file names.
    80  // This is the same as URLEncoding but omits padding characters.
    81  var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
    82  
    83  /*
    84   * Encoder
    85   */
    86  
    87  // Encode encodes src using the encoding enc, writing
    88  // EncodedLen(len(src)) bytes to dst.
    89  //
    90  // The encoding pads the output to a multiple of 4 bytes,
    91  // so Encode is not appropriate for use on individual blocks
    92  // of a large data stream.  Use NewEncoder() instead.
    93  func (enc *Encoding) Encode(dst, src []byte) {
    94  	if len(src) == 0 {
    95  		return
    96  	}
    97  
    98  	di, si := 0, 0
    99  	n := (len(src) / 3) * 3
   100  	for si < n {
   101  		// Convert 3x 8bit source bytes into 4 bytes
   102  		val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2])
   103  
   104  		dst[di+0] = enc.encode[val>>18&0x3F]
   105  		dst[di+1] = enc.encode[val>>12&0x3F]
   106  		dst[di+2] = enc.encode[val>>6&0x3F]
   107  		dst[di+3] = enc.encode[val&0x3F]
   108  
   109  		si += 3
   110  		di += 4
   111  	}
   112  
   113  	remain := len(src) - si
   114  	if remain == 0 {
   115  		return
   116  	}
   117  	// Add the remaining small block
   118  	val := uint(src[si+0]) << 16
   119  	if remain == 2 {
   120  		val |= uint(src[si+1]) << 8
   121  	}
   122  
   123  	dst[di+0] = enc.encode[val>>18&0x3F]
   124  	dst[di+1] = enc.encode[val>>12&0x3F]
   125  
   126  	switch remain {
   127  	case 2:
   128  		dst[di+2] = enc.encode[val>>6&0x3F]
   129  		if enc.padChar != NoPadding {
   130  			dst[di+3] = byte(enc.padChar)
   131  		}
   132  	case 1:
   133  		if enc.padChar != NoPadding {
   134  			dst[di+2] = byte(enc.padChar)
   135  			dst[di+3] = byte(enc.padChar)
   136  		}
   137  	}
   138  }
   139  
   140  // EncodeToString returns the base64 encoding of src.
   141  func (enc *Encoding) EncodeToString(src []byte) string {
   142  	buf := make([]byte, enc.EncodedLen(len(src)))
   143  	enc.Encode(buf, src)
   144  	return string(buf)
   145  }
   146  
   147  type encoder struct {
   148  	err  error
   149  	enc  *Encoding
   150  	w    io.Writer
   151  	buf  [3]byte    // buffered data waiting to be encoded
   152  	nbuf int        // number of bytes in buf
   153  	out  [1024]byte // output buffer
   154  }
   155  
   156  func (e *encoder) Write(p []byte) (n int, err error) {
   157  	if e.err != nil {
   158  		return 0, e.err
   159  	}
   160  
   161  	// Leading fringe.
   162  	if e.nbuf > 0 {
   163  		var i int
   164  		for i = 0; i < len(p) && e.nbuf < 3; i++ {
   165  			e.buf[e.nbuf] = p[i]
   166  			e.nbuf++
   167  		}
   168  		n += i
   169  		p = p[i:]
   170  		if e.nbuf < 3 {
   171  			return
   172  		}
   173  		e.enc.Encode(e.out[:], e.buf[:])
   174  		if _, e.err = e.w.Write(e.out[:4]); e.err != nil {
   175  			return n, e.err
   176  		}
   177  		e.nbuf = 0
   178  	}
   179  
   180  	// Large interior chunks.
   181  	for len(p) >= 3 {
   182  		nn := len(e.out) / 4 * 3
   183  		if nn > len(p) {
   184  			nn = len(p)
   185  			nn -= nn % 3
   186  		}
   187  		e.enc.Encode(e.out[:], p[:nn])
   188  		if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
   189  			return n, e.err
   190  		}
   191  		n += nn
   192  		p = p[nn:]
   193  	}
   194  
   195  	// Trailing fringe.
   196  	for i := 0; i < len(p); i++ {
   197  		e.buf[i] = p[i]
   198  	}
   199  	e.nbuf = len(p)
   200  	n += len(p)
   201  	return
   202  }
   203  
   204  // Close flushes any pending output from the encoder.
   205  // It is an error to call Write after calling Close.
   206  func (e *encoder) Close() error {
   207  	// If there's anything left in the buffer, flush it out
   208  	if e.err == nil && e.nbuf > 0 {
   209  		e.enc.Encode(e.out[:], e.buf[:e.nbuf])
   210  		_, e.err = e.w.Write(e.out[:e.enc.EncodedLen(e.nbuf)])
   211  		e.nbuf = 0
   212  	}
   213  	return e.err
   214  }
   215  
   216  // NewEncoder returns a new base64 stream encoder.  Data written to
   217  // the returned writer will be encoded using enc and then written to w.
   218  // Base64 encodings operate in 4-byte blocks; when finished
   219  // writing, the caller must Close the returned encoder to flush any
   220  // partially written blocks.
   221  func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
   222  	return &encoder{enc: enc, w: w}
   223  }
   224  
   225  // EncodedLen returns the length in bytes of the base64 encoding
   226  // of an input buffer of length n.
   227  func (enc *Encoding) EncodedLen(n int) int {
   228  	if enc.padChar == NoPadding {
   229  		return (n*8 + 5) / 6 // minimum # chars at 6 bits per char
   230  	}
   231  	return (n + 2) / 3 * 4 // minimum # 4-char quanta, 3 bytes each
   232  }
   233  
   234  /*
   235   * Decoder
   236   */
   237  
   238  type CorruptInputError int64
   239  
   240  func (e CorruptInputError) Error() string {
   241  	return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
   242  }
   243  
   244  // decode is like Decode but returns an additional 'end' value, which
   245  // indicates if end-of-message padding or a partial quantum was encountered
   246  // and thus any additional data is an error.
   247  func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
   248  	si := 0
   249  
   250  	// skip over newlines
   251  	for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
   252  		si++
   253  	}
   254  
   255  	for si < len(src) && !end {
   256  		// Decode quantum using the base64 alphabet
   257  		var dbuf [4]byte
   258  		dinc, dlen := 3, 4
   259  
   260  		for j := range dbuf {
   261  			if len(src) == si {
   262  				if enc.padChar != NoPadding || j < 2 {
   263  					return n, false, CorruptInputError(si - j)
   264  				}
   265  				dinc, dlen, end = j-1, j, true
   266  				break
   267  			}
   268  			in := src[si]
   269  
   270  			si++
   271  			// skip over newlines
   272  			for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
   273  				si++
   274  			}
   275  
   276  			if rune(in) == enc.padChar {
   277  				// We've reached the end and there's padding
   278  				switch j {
   279  				case 0, 1:
   280  					// incorrect padding
   281  					return n, false, CorruptInputError(si - 1)
   282  				case 2:
   283  					// "==" is expected, the first "=" is already consumed.
   284  					if si == len(src) {
   285  						// not enough padding
   286  						return n, false, CorruptInputError(len(src))
   287  					}
   288  					if rune(src[si]) != enc.padChar {
   289  						// incorrect padding
   290  						return n, false, CorruptInputError(si - 1)
   291  					}
   292  
   293  					si++
   294  					// skip over newlines
   295  					for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
   296  						si++
   297  					}
   298  				}
   299  				if si < len(src) {
   300  					// trailing garbage
   301  					err = CorruptInputError(si)
   302  				}
   303  				dinc, dlen, end = 3, j, true
   304  				break
   305  			}
   306  			dbuf[j] = enc.decodeMap[in]
   307  			if dbuf[j] == 0xFF {
   308  				return n, false, CorruptInputError(si - 1)
   309  			}
   310  		}
   311  
   312  		// Convert 4x 6bit source bytes into 3 bytes
   313  		val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
   314  		switch dlen {
   315  		case 4:
   316  			dst[2] = byte(val >> 0)
   317  			fallthrough
   318  		case 3:
   319  			dst[1] = byte(val >> 8)
   320  			fallthrough
   321  		case 2:
   322  			dst[0] = byte(val >> 16)
   323  		}
   324  		dst = dst[dinc:]
   325  		n += dlen - 1
   326  	}
   327  
   328  	return n, end, err
   329  }
   330  
   331  // Decode decodes src using the encoding enc.  It writes at most
   332  // DecodedLen(len(src)) bytes to dst and returns the number of bytes
   333  // written.  If src contains invalid base64 data, it will return the
   334  // number of bytes successfully written and CorruptInputError.
   335  // New line characters (\r and \n) are ignored.
   336  func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
   337  	n, _, err = enc.decode(dst, src)
   338  	return
   339  }
   340  
   341  // DecodeString returns the bytes represented by the base64 string s.
   342  func (enc *Encoding) DecodeString(s string) ([]byte, error) {
   343  	dbuf := make([]byte, enc.DecodedLen(len(s)))
   344  	n, _, err := enc.decode(dbuf, []byte(s))
   345  	return dbuf[:n], err
   346  }
   347  
   348  type decoder struct {
   349  	err    error
   350  	enc    *Encoding
   351  	r      io.Reader
   352  	end    bool       // saw end of message
   353  	buf    [1024]byte // leftover input
   354  	nbuf   int
   355  	out    []byte // leftover decoded output
   356  	outbuf [1024 / 4 * 3]byte
   357  }
   358  
   359  func (d *decoder) Read(p []byte) (n int, err error) {
   360  	if d.err != nil {
   361  		return 0, d.err
   362  	}
   363  
   364  	// Use leftover decoded output from last read.
   365  	if len(d.out) > 0 {
   366  		n = copy(p, d.out)
   367  		d.out = d.out[n:]
   368  		return n, nil
   369  	}
   370  
   371  	// This code assumes that d.r strips supported whitespace ('\r' and '\n').
   372  
   373  	// Read a chunk.
   374  	nn := len(p) / 3 * 4
   375  	if nn < 4 {
   376  		nn = 4
   377  	}
   378  	if nn > len(d.buf) {
   379  		nn = len(d.buf)
   380  	}
   381  	nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf)
   382  	d.nbuf += nn
   383  	if d.err != nil || d.nbuf < 4 {
   384  		return 0, d.err
   385  	}
   386  
   387  	// Decode chunk into p, or d.out and then p if p is too small.
   388  	nr := d.nbuf / 4 * 4
   389  	nw := d.nbuf / 4 * 3
   390  	if nw > len(p) {
   391  		nw, d.end, d.err = d.enc.decode(d.outbuf[:], d.buf[:nr])
   392  		d.out = d.outbuf[:nw]
   393  		n = copy(p, d.out)
   394  		d.out = d.out[n:]
   395  	} else {
   396  		n, d.end, d.err = d.enc.decode(p, d.buf[:nr])
   397  	}
   398  	d.nbuf -= nr
   399  	for i := 0; i < d.nbuf; i++ {
   400  		d.buf[i] = d.buf[i+nr]
   401  	}
   402  
   403  	if d.err == nil {
   404  		d.err = err
   405  	}
   406  	return n, d.err
   407  }
   408  
   409  type newlineFilteringReader struct {
   410  	wrapped io.Reader
   411  }
   412  
   413  func (r *newlineFilteringReader) Read(p []byte) (int, error) {
   414  	n, err := r.wrapped.Read(p)
   415  	for n > 0 {
   416  		offset := 0
   417  		for i, b := range p[:n] {
   418  			if b != '\r' && b != '\n' {
   419  				if i != offset {
   420  					p[offset] = b
   421  				}
   422  				offset++
   423  			}
   424  		}
   425  		if offset > 0 {
   426  			return offset, err
   427  		}
   428  		// Previous buffer entirely whitespace, read again
   429  		n, err = r.wrapped.Read(p)
   430  	}
   431  	return n, err
   432  }
   433  
   434  // NewDecoder constructs a new base64 stream decoder.
   435  func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
   436  	return &decoder{enc: enc, r: &newlineFilteringReader{r}}
   437  }
   438  
   439  // DecodedLen returns the maximum length in bytes of the decoded data
   440  // corresponding to n bytes of base64-encoded data.
   441  func (enc *Encoding) DecodedLen(n int) int {
   442  	if enc.padChar == NoPadding {
   443  		// Unpadded data may end with partial block of 2-3 characters.
   444  		return (n*6 + 7) / 8
   445  	}
   446  	// Padded base64 should always be a multiple of 4 characters in length.
   447  	return n / 4 * 3
   448  }