1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5'use strict';
6
7/* This is a Base64 Polyfill adapted from
8 * https://github.com/davidchambers/Base64.js/blob/0.3.0/,
9 * which has a "do whatever you want" license,
10 * https://github.com/davidchambers/Base64.js/blob/0.3.0/LICENSE.
11 */
12(function(global) {
13  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +
14      '0123456789+/=';
15
16  function InvalidCharacterError(message) {
17    this.message = message;
18  }
19  InvalidCharacterError.prototype = new Error;
20  InvalidCharacterError.prototype.name = 'InvalidCharacterError';
21
22  // encoder
23  // [https://gist.github.com/999166] by [https://github.com/nignag]
24  global.btoa = function(input) {
25    var str = String(input);
26    for (
27        // Initialize result and counter.
28        var block, charCode, idx = 0, map = chars, output = '';
29        // If the next str index does not exist:
30        //   change the mapping table to "="
31        //   check if d has no fractional digits
32        str.charAt(idx | 0) || (map = '=', idx % 1);
33        // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8.
34        output += map.charAt(63 & block >> 8 - idx % 1 * 8)) {
35      charCode = str.charCodeAt(idx += 3 / 4);
36      if (charCode > 0xFF) {
37        throw new InvalidCharacterError(
38            '\'btoa\' failed: The string to be encoded contains characters ' +
39            'outside of the Latin1 range.');
40      }
41      block = block << 8 | charCode;
42    }
43    return output;
44  };
45
46  // decoder
47  // [https://gist.github.com/1020396] by [https://github.com/atk]
48  global.atob = function(input) {
49    var str = String(input).replace(/=+$/, '');
50    if (str.length % 4 == 1) {
51      throw new InvalidCharacterError(
52          '\'atob\' failed: The string to be decoded is not ' +
53          'correctly encoded.');
54    }
55    for (
56        // Initialize result and counters.
57        var bc = 0, bs, buffer, idx = 0, output = '';
58        // Get next character.
59        buffer = str.charAt(idx++);
60        // Character found in table? initialize bit storage and add its
61        // ascii value;
62        ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
63            // And if not first of each 4 characters,
64            // convert the first 8 bits to one ascii character.
65            bc++ % 4) ? output += String.fromCharCode(
66                  255 & bs >> (-2 * bc & 6)) : 0) {
67      // Try to find character in table (0-63, not found => -1).
68      buffer = chars.indexOf(buffer);
69    }
70    return output;
71  };
72
73})(this);
74