// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.convert;

/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder.
///
/// It encodes using the default base64 alphabet,
/// decodes using both the base64 and base64url alphabets,
/// does not allow invalid characters and requires padding.
///
/// Examples:
/// ```dart
/// var encoded = base64.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
///                              0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
/// var decoded = base64.decode("YmzDpWLDpnJncsO4ZAo=");
/// ```
/// The top-level [base64Encode] and [base64Decode] functions may be used
/// instead if a local variable shadows the [base64] constant.
const Base64Codec base64 = Base64Codec();

/// A [base64url](https://tools.ietf.org/html/rfc4648) encoder and decoder.
///
/// It encodes and decodes using the base64url alphabet,
/// decodes using both the base64 and base64url alphabets,
/// does not allow invalid characters and requires padding.
///
/// Examples:
/// ```dart
/// var encoded = base64Url.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
///                                 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
/// var decoded = base64Url.decode("YmzDpWLDpnJncsO4ZAo=");
/// ```
const Base64Codec base64Url = Base64Codec.urlSafe();

/// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding.
///
/// Shorthand for `base64.encode(bytes)`. Useful if a local variable shadows the global
/// [base64] constant.
String base64Encode(List<int> bytes) => base64.encode(bytes);

/// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding.
///
/// Shorthand for `base64url.encode(bytes)`.
String base64UrlEncode(List<int> bytes) => base64Url.encode(bytes);

/// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes.
///
/// Shorthand for `base64.decode(bytes)`. Useful if a local variable shadows the
/// global [base64] constant.
Uint8List base64Decode(String source) => base64.decode(source);

// Constants used in more than one class.
const int _paddingChar = 0x3d; // '='.

/// A [base64](https://tools.ietf.org/html/rfc4648) encoder and decoder.
///
/// A [Base64Codec] allows base64 encoding bytes into ASCII strings and
/// decoding valid encodings back to bytes.
///
/// This implementation only handles the simplest RFC 4648 base64 and base64url
/// encodings.
/// It does not allow invalid characters when decoding and it requires,
/// and generates, padding so that the input is always a multiple of four
/// characters.
class Base64Codec extends Codec<List<int>, String> {
  final Base64Encoder _encoder;
  const Base64Codec() : _encoder = const Base64Encoder();
  const Base64Codec.urlSafe() : _encoder = const Base64Encoder.urlSafe();

  Base64Encoder get encoder => _encoder;

  Base64Decoder get decoder => const Base64Decoder();

  /// Decodes [encoded].
  ///
  /// The input is decoded as if by `decoder.convert`.
  ///
  /// The returned [Uint8List] contains exactly the decoded bytes,
  /// so the [Uint8List.length] is precisely the number of decoded bytes.
  /// The [Uint8List.buffer] may be larger than the decoded bytes.
  Uint8List decode(String encoded) => decoder.convert(encoded);

  /// Validates and normalizes the base64 encoded data in [source].
  ///
  /// Only acts on the substring from [start] to [end], with [end]
  /// defaulting to the end of the string.
  ///
  /// Normalization will:
  /// * Unescape any `%`-escapes.
  /// * Only allow valid characters (`A`-`Z`, `a`-`z`, `0`-`9`, `/` and `+`).
  /// * Normalize a `_` or `-` character to `/` or `+`.
  /// * Validate that existing padding (trailing `=` characters) is correct.
  /// * If no padding exists, add correct padding if necessary and possible.
  /// * Validate that the length is correct (a multiple of four).
  String normalize(String source, [int start = 0, int? end]) {
    end = RangeError.checkValidRange(start, end, source.length);
    const percent = 0x25;
    const equals = 0x3d;
    StringBuffer? buffer;
    var sliceStart = start;
    var alphabet = _Base64Encoder._base64Alphabet;
    var inverseAlphabet = _Base64Decoder._inverseAlphabet;
    var firstPadding = -1;
    var firstPaddingSourceIndex = -1;
    var paddingCount = 0;
    for (var i = start; i < end;) {
      var sliceEnd = i;
      var char = source.codeUnitAt(i++);
      var originalChar = char;
      // Normalize char, keep originalChar to see if it matches the source.
      if (char == percent) {
        if (i + 2 <= end) {
          char = parseHexByte(source, i); // May be negative.
          i += 2;
          // We know that %25 isn't valid, but our table considers it
          // a potential padding start, so skip the checks.
          if (char == percent) char = -1;
        } else {
          // An invalid HEX escape (too short).
          // Just skip past the handling and reach the throw below.
          char = -1;
        }
      }
      // If char is negative here, hex-decoding failed in some way.
      if (0 <= char && char <= 127) {
        var value = inverseAlphabet[char];
        if (value >= 0) {
          char = alphabet.codeUnitAt(value);
          if (char == originalChar) continue;
        } else if (value == _Base64Decoder._padding) {
          // We have ruled out percent, so char is '='.
          if (firstPadding < 0) {
            // Mark position in normalized output where padding occurs.
            firstPadding = (buffer?.length ?? 0) + (sliceEnd - sliceStart);
            firstPaddingSourceIndex = sliceEnd;
          }
          paddingCount++;
          // It could have been an escaped equals (%3D).
          if (originalChar == equals) continue;
        }
        if (value != _Base64Decoder._invalid) {
          (buffer ??= StringBuffer())
            ..write(source.substring(sliceStart, sliceEnd))
            ..writeCharCode(char);
          sliceStart = i;
          continue;
        }
      }
      throw FormatException("Invalid base64 data", source, sliceEnd);
    }
    if (buffer != null) {
      buffer.write(source.substring(sliceStart, end));
      if (firstPadding >= 0) {
        // There was padding in the source. Check that it is valid:
        // * result length a multiple of four
        // * one or two padding characters at the end.
        _checkPadding(source, firstPaddingSourceIndex, end, firstPadding,
            paddingCount, buffer.length);
      } else {
        // Length of last chunk (1-4 chars) in the encoding.
        var endLength = ((buffer.length - 1) % 4) + 1;
        if (endLength == 1) {
          // The data must have length 0, 2 or 3 modulo 4.
          throw FormatException("Invalid base64 encoding length ", source, end);
        }
        while (endLength < 4) {
          buffer.write("=");
          endLength++;
        }
      }
      return source.replaceRange(start, end, buffer.toString());
    }
    // Original was already normalized, only check padding.
    var length = end - start;
    if (firstPadding >= 0) {
      _checkPadding(source, firstPaddingSourceIndex, end, firstPadding,
          paddingCount, length);
    } else {
      // No padding given, so add some if needed it.
      var endLength = length % 4;
      if (endLength == 1) {
        // The data must have length 0, 2 or 3 modulo 4.
        throw FormatException("Invalid base64 encoding length ", source, end);
      }
      if (endLength > 1) {
        // There is no "insertAt" on String, but this works as well.
        source = source.replaceRange(end, end, (endLength == 2) ? "==" : "=");
      }
    }
    return source;
  }

  static void _checkPadding(String source, int sourceIndex, int sourceEnd,
      int firstPadding, int paddingCount, int length) {
    if (length % 4 != 0) {
      throw FormatException(
          "Invalid base64 padding, padded length must be multiple of four, "
          "is $length",
          source,
          sourceEnd);
    }
    if (firstPadding + paddingCount != length) {
      throw FormatException(
          "Invalid base64 padding, '=' not at the end", source, sourceIndex);
    }
    if (paddingCount > 2) {
      throw FormatException(
          "Invalid base64 padding, more than two '=' characters",
          source,
          sourceIndex);
    }
  }
}

// ------------------------------------------------------------------------
// Encoder
// ------------------------------------------------------------------------

/// Base64 and base64url encoding converter.
///
/// Encodes lists of bytes using base64 or base64url encoding.
///
/// The results are ASCII strings using a restricted alphabet.
///
/// Example:
/// ```dart
/// final base64Encoder = base64.encoder;
/// const sample = 'Dart is open source';
/// final encodedSample = base64Encoder.convert(sample.codeUnits);
/// print(encodedSample); // RGFydCBpcyBvcGVuIHNvdXJjZQ==
/// ```
class Base64Encoder extends Converter<List<int>, String> {
  final bool _urlSafe;

  const Base64Encoder() : _urlSafe = false;
  const Base64Encoder.urlSafe() : _urlSafe = true;

  String convert(List<int> input) {
    if (input.isEmpty) return "";
    var encoder = _Base64Encoder(_urlSafe);
    var buffer = encoder.encode(input, 0, input.length, true)!;
    return String.fromCharCodes(buffer);
  }

  ByteConversionSink startChunkedConversion(Sink<String> sink) {
    if (sink is StringConversionSink) {
      return _Utf8Base64EncoderSink(sink.asUtf8Sink(false), _urlSafe);
    }
    return _AsciiBase64EncoderSink(sink, _urlSafe);
  }
}

/// Helper class for encoding bytes to base64.
class _Base64Encoder {
  /// The RFC 4648 base64 encoding alphabet.
  static const String _base64Alphabet =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

  /// The RFC 4648 base64url encoding alphabet.
  static const String _base64UrlAlphabet =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

  /// Shift-count to extract the values stored in [_state].
  static const int _valueShift = 2;

  /// Mask to extract the count value stored in [_state].
  static const int _countMask = 3;

  static const int _sixBitMask = 0x3F;

  /// Intermediate state between chunks.
  ///
  /// Encoding handles three bytes at a time.
  /// If fewer than three bytes has been seen, this value encodes
  /// the number of bytes seen (0, 1 or 2) and their values.
  int _state = 0;

  /// Alphabet used for encoding.
  final String _alphabet;

  _Base64Encoder(bool urlSafe)
      : _alphabet = urlSafe ? _base64UrlAlphabet : _base64Alphabet;

  /// Encode count and bits into a value to be stored in [_state].
  static int _encodeState(int count, int bits) {
    assert(count <= _countMask);
    return bits << _valueShift | count;
  }

  /// Extract bits from encoded state.
  static int _stateBits(int state) => state >> _valueShift;

  /// Extract count from encoded state.
  static int _stateCount(int state) => state & _countMask;

  /// Create a [Uint8List] with the provided length.
  Uint8List createBuffer(int bufferLength) => Uint8List(bufferLength);

  /// Encode [bytes] from [start] to [end] and the bits in [_state].
  ///
  /// Returns a [Uint8List] of the ASCII codes of the encoded data.
  ///
  /// If the input, including left over [_state] from earlier encodings,
  /// is not a multiple of three bytes, then the partial state is stored
  /// back into [_state].
  /// If [isLast] is true, partial state is encoded in the output instead,
  /// with the necessary padding.
  ///
  /// Returns `null` if there is no output.
  Uint8List? encode(List<int> bytes, int start, int end, bool isLast) {
    assert(0 <= start);
    assert(start <= end);
    assert(end <= bytes.length);
    var length = end - start;

    var count = _stateCount(_state);
    var byteCount = (count + length);
    var fullChunks = byteCount ~/ 3;
    var partialChunkLength = byteCount - fullChunks * 3;
    var bufferLength = fullChunks * 4;
    if (isLast && partialChunkLength > 0) {
      bufferLength += 4; // Room for padding.
    }
    var output = createBuffer(bufferLength);
    _state =
        encodeChunk(_alphabet, bytes, start, end, isLast, output, 0, _state);
    if (bufferLength > 0) return output;
    // If the input plus the data in state is still less than three bytes,
    // there may not be any output.
    return null;
  }

  static int encodeChunk(String alphabet, List<int> bytes, int start, int end,
      bool isLast, Uint8List output, int outputIndex, int state) {
    var bits = _stateBits(state);
    // Count number of missing bytes in three-byte chunk.
    var expectedChars = 3 - _stateCount(state);

    // The input must be a list of bytes (integers in the range 0..255).
    // The value of `byteOr` will be the bitwise or of all the values in
    // `bytes` and a later check will validate that they were all valid bytes.
    var byteOr = 0;
    for (var i = start; i < end; i++) {
      var byte = bytes[i];
      byteOr |= byte;
      bits = ((bits << 8) | byte) & 0xFFFFFF; // Never store more than 24 bits.
      expectedChars--;
      if (expectedChars == 0) {
        output[outputIndex++] = alphabet.codeUnitAt((bits >> 18) & _sixBitMask);
        output[outputIndex++] = alphabet.codeUnitAt((bits >> 12) & _sixBitMask);
        output[outputIndex++] = alphabet.codeUnitAt((bits >> 6) & _sixBitMask);
        output[outputIndex++] = alphabet.codeUnitAt(bits & _sixBitMask);
        expectedChars = 3;
        bits = 0;
      }
    }
    if (byteOr >= 0 && byteOr <= 255) {
      if (isLast && expectedChars < 3) {
        writeFinalChunk(alphabet, output, outputIndex, 3 - expectedChars, bits);
        return 0;
      }
      return _encodeState(3 - expectedChars, bits);
    }

    // There was an invalid byte value somewhere in the input - find it!
    var i = start;
    while (i < end) {
      var byte = bytes[i];
      if (byte < 0 || byte > 255) break;
      i++;
    }
    throw ArgumentError.value(
        bytes, "Not a byte value at index $i: 0x${bytes[i].toRadixString(16)}");
  }

  /// Writes a final encoded four-character chunk.
  ///
  /// Only used when the [_state] contains a partial (1 or 2 byte)
  /// input.
  static void writeFinalChunk(
      String alphabet, Uint8List output, int outputIndex, int count, int bits) {
    assert(count > 0);
    if (count == 1) {
      output[outputIndex++] = alphabet.codeUnitAt((bits >> 2) & _sixBitMask);
      output[outputIndex++] = alphabet.codeUnitAt((bits << 4) & _sixBitMask);
      output[outputIndex++] = _paddingChar;
      output[outputIndex++] = _paddingChar;
    } else {
      assert(count == 2);
      output[outputIndex++] = alphabet.codeUnitAt((bits >> 10) & _sixBitMask);
      output[outputIndex++] = alphabet.codeUnitAt((bits >> 4) & _sixBitMask);
      output[outputIndex++] = alphabet.codeUnitAt((bits << 2) & _sixBitMask);
      output[outputIndex++] = _paddingChar;
    }
  }
}

class _BufferCachingBase64Encoder extends _Base64Encoder {
  /// Reused buffer.
  ///
  /// When the buffer isn't released to the sink, only used to create another
  /// value (a string), the buffer can be reused between chunks.
  Uint8List? bufferCache;

  _BufferCachingBase64Encoder(bool urlSafe) : super(urlSafe);

  Uint8List createBuffer(int bufferLength) {
    Uint8List? buffer = bufferCache;
    if (buffer == null || buffer.length < bufferLength) {
      bufferCache = buffer = Uint8List(bufferLength);
    }
    // Return a view of the buffer, so it has the requested length.
    return Uint8List.view(buffer.buffer, buffer.offsetInBytes, bufferLength);
  }
}

abstract class _Base64EncoderSink extends ByteConversionSinkBase {
  void add(List<int> source) {
    _add(source, 0, source.length, false);
  }

  void close() {
    _add(const [], 0, 0, true);
  }

  void addSlice(List<int> source, int start, int end, bool isLast) {
    if (end == null) throw ArgumentError.notNull("end");
    RangeError.checkValidRange(start, end, source.length);
    _add(source, start, end, isLast);
  }

  void _add(List<int> source, int start, int end, bool isLast);
}

class _AsciiBase64EncoderSink extends _Base64EncoderSink {
  final Sink<String> _sink;
  final _Base64Encoder _encoder;

  _AsciiBase64EncoderSink(this._sink, bool urlSafe)
      : _encoder = _BufferCachingBase64Encoder(urlSafe);

  void _add(List<int> source, int start, int end, bool isLast) {
    var buffer = _encoder.encode(source, start, end, isLast);
    if (buffer != null) {
      var string = String.fromCharCodes(buffer);
      _sink.add(string);
    }
    if (isLast) {
      _sink.close();
    }
  }
}

class _Utf8Base64EncoderSink extends _Base64EncoderSink {
  final ByteConversionSink _sink;
  final _Base64Encoder _encoder;

  _Utf8Base64EncoderSink(this._sink, bool urlSafe)
      : _encoder = _Base64Encoder(urlSafe);

  void _add(List<int> source, int start, int end, bool isLast) {
    var buffer = _encoder.encode(source, start, end, isLast);
    if (buffer != null) {
      _sink.addSlice(buffer, 0, buffer.length, isLast);
    }
  }
}

// ------------------------------------------------------------------------
// Decoder
// ------------------------------------------------------------------------

/// Decoder for base64 encoded data.
///
/// This decoder accepts both base64 and base64url ("url-safe") encodings.
///
/// The encoding is required to be properly padded.
///
/// Throws a [FormatException] if the input is not valid base64 data.
///
/// Example:
/// ```dart
/// final base64Decoder = base64.decoder;
/// const base64Bytes = 'RGFydCBpcyBvcGVuIHNvdXJjZQ==';
/// final decodedBytes = base64Decoder.convert(base64Bytes);
/// // decodedBytes: [68, 97, 114, 116, 32, 105, 115, 32, 111, 112, 101, 110,
/// // 32, 115, 111, 117, 114, 99, 101]
///
/// // Print as string using UTF-8 decoder
/// print(utf8.decode(decodedBytes)); // Dart is open source
/// ```
class Base64Decoder extends Converter<String, List<int>> {
  const Base64Decoder();

  /// Decodes the characters of [input] from [start] to [end] as base64.
  ///
  /// If [start] is omitted, it defaults to the start of [input].
  /// If [end] is omitted, it defaults to the end of [input].
  ///
  /// The returned [Uint8List] contains exactly the decoded bytes,
  /// so the [Uint8List.length] is precisely the number of decoded bytes.
  /// The [Uint8List.buffer] may be larger than the decoded bytes.
  Uint8List convert(String input, [int start = 0, int? end]) {
    end = RangeError.checkValidRange(start, end, input.length);
    if (start == end) return Uint8List(0);
    var decoder = _Base64Decoder();
    var buffer = decoder.decode(input, start, end)!;
    decoder.close(input, end);
    return buffer;
  }

  StringConversionSink startChunkedConversion(Sink<List<int>> sink) {
    return _Base64DecoderSink(sink);
  }
}

/// Helper class implementing base64 decoding with intermediate state.
class _Base64Decoder {
  /// Shift-count to extract the values stored in [_state].
  static const int _valueShift = 2;

  /// Mask to extract the count value stored in [_state].
  static const int _countMask = 3;

  /// Invalid character in decoding table.
  static const int _invalid = -2;

  /// Padding character in decoding table.
  static const int _padding = -1;

  // Shorthands to make the table more readable.
  static const int __ = _invalid;
  static const int _p = _padding;

  /// Mapping from ASCII characters to their index in the base64 alphabet.
  ///
  /// Uses [_invalid] for invalid indices and [_padding] for the padding
  /// character.
  ///
  /// Accepts the "URL-safe" alphabet as well (`-` and `_` are the
  /// 62nd and 63rd alphabet characters), and considers `%` a padding
  /// character, which must then be followed by `3D`, the percent-escape
  /// for `=`.
  static final List<int> _inverseAlphabet = Int8List.fromList([
    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, //
    __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, //
    __, __, __, __, __, _p, __, __, __, __, __, 62, __, 62, __, 63, //
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, __, __, __, _p, __, __, //
    __, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, //
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, __, __, __, __, 63, //
    __, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, __, __, __, __, __, //
  ]);

  // Character constants.
  static const int _char_percent = 0x25; // '%'.
  static const int _char_3 = 0x33; // '3'.
  static const int _char_d = 0x64; // 'd'.

  /// Maintains the intermediate state of a partly-decoded input.
  ///
  /// Base64 is decoded in chunks of four characters. If a chunk does not
  /// contain a full block, the decoded bits (six per character) of the
  /// available characters are stored in [_state] until the next call to
  /// [_decode] or [_close].
  ///
  /// If no padding has been seen, the value is
  ///   `numberOfCharactersSeen | (decodedBits << 2)`
  /// where `numberOfCharactersSeen` is between 0 and 3 and decoded bits
  /// contains six bits per seen character.
  ///
  /// If padding has been seen the value is negative. It's the bitwise negation
  /// of the number of remaining allowed padding characters (always ~0 or ~1).
  ///
  /// A state of `0` or `~0` are valid places to end decoding, all other values
  /// mean that a four-character block has not been completed.
  int _state = 0;

  /// Encodes [count] and [bits] as a value to be stored in [_state].
  static int _encodeCharacterState(int count, int bits) {
    assert(count == (count & _countMask));
    return (bits << _valueShift | count);
  }

  /// Extracts count from a [_state] value.
  static int _stateCount(int state) {
    assert(state >= 0);
    return state & _countMask;
  }

  /// Extracts value bits from a [_state] value.
  static int _stateBits(int state) {
    assert(state >= 0);
    return state >> _valueShift;
  }

  /// Encodes a number of expected padding characters to be stored in [_state].
  static int _encodePaddingState(int expectedPadding) {
    assert(expectedPadding >= 0);
    assert(expectedPadding <= 5);
    return -expectedPadding - 1; // ~expectedPadding adapted to dart2js.
  }

  /// Extracts expected padding character count from a [_state] value.
  static int _statePadding(int state) {
    assert(state < 0);
    return -state - 1; // ~state adapted to dart2js.
  }

  static bool _hasSeenPadding(int state) => state < 0;

  /// Decodes [input] from [start] to [end].
  ///
  /// Returns a [Uint8List] with the decoded bytes.
  /// If a previous call had an incomplete four-character block, the bits from
  /// those are included in decoding
  Uint8List? decode(String input, int start, int end) {
    assert(0 <= start);
    assert(start <= end);
    assert(end <= input.length);
    if (_hasSeenPadding(_state)) {
      _state = _checkPadding(input, start, end, _state);
      return null;
    }
    if (start == end) return Uint8List(0);
    var buffer = _allocateBuffer(input, start, end, _state);
    _state = decodeChunk(input, start, end, buffer, 0, _state);
    return buffer;
  }

  /// Checks that [_state] represents a valid decoding.
  void close(String? input, int? end) {
    if (_state < _encodePaddingState(0)) {
      throw FormatException("Missing padding character", input, end);
    }
    if (_state > 0) {
      throw FormatException(
          "Invalid length, must be multiple of four", input, end);
    }
    _state = _encodePaddingState(0);
  }

  /// Decodes [input] from [start] to [end].
  ///
  /// Includes the state returned by a previous call in the decoding.
  /// Writes the decoding to [output] at [outIndex], and there must
  /// be room in the output.
  static int decodeChunk(String input, int start, int end, Uint8List output,
      int outIndex, int state) {
    assert(!_hasSeenPadding(state));
    const asciiMask = 127;
    const asciiMax = 127;
    const eightBitMask = 0xFF;
    const bitsPerCharacter = 6;

    var bits = _stateBits(state);
    var count = _stateCount(state);
    // String contents should be all ASCII.
    // Instead of checking for each character, we collect the bitwise-or of
    // all the characters in `charOr` and later validate that all characters
    // were ASCII.
    var charOr = 0;
    final inverseAlphabet = _Base64Decoder._inverseAlphabet;
    for (var i = start; i < end; i++) {
      var char = input.codeUnitAt(i);
      charOr |= char;
      var code = inverseAlphabet[char & asciiMask];
      if (code >= 0) {
        bits = ((bits << bitsPerCharacter) | code) & 0xFFFFFF;
        count = (count + 1) & 3;
        if (count == 0) {
          assert(outIndex + 3 <= output.length);
          output[outIndex++] = (bits >> 16) & eightBitMask;
          output[outIndex++] = (bits >> 8) & eightBitMask;
          output[outIndex++] = bits & eightBitMask;
          bits = 0;
        }
        continue;
      } else if (code == _padding && count > 1) {
        if (charOr < 0 || charOr > asciiMax) break;
        if (count == 3) {
          if ((bits & 0x03) != 0) {
            throw FormatException("Invalid encoding before padding", input, i);
          }
          output[outIndex++] = bits >> 10;
          output[outIndex++] = bits >> 2;
        } else {
          if ((bits & 0x0F) != 0) {
            throw FormatException("Invalid encoding before padding", input, i);
          }
          output[outIndex++] = bits >> 4;
        }
        // Expected padding is the number of expected padding characters,
        // where `=` counts as three and `%3D` counts as one per character.
        //
        // Expect either zero or one padding depending on count (2 or 3),
        // plus two more characters if the code was `%` (a partial padding).
        var expectedPadding = (3 - count) * 3;
        if (char == _char_percent) expectedPadding += 2;
        state = _encodePaddingState(expectedPadding);
        return _checkPadding(input, i + 1, end, state);
      }
      throw FormatException("Invalid character", input, i);
    }
    if (charOr >= 0 && charOr <= asciiMax) {
      return _encodeCharacterState(count, bits);
    }
    // There is an invalid (non-ASCII) character in the input.
    int i;
    for (i = start; i < end; i++) {
      var char = input.codeUnitAt(i);
      if (char < 0 || char > asciiMax) break;
    }
    throw FormatException("Invalid character", input, i);
  }

  static Uint8List _emptyBuffer = Uint8List(0);

  /// Allocates a buffer with room for the decoding of a substring of [input].
  ///
  /// Includes room for the characters in [state], and handles padding correctly.
  static Uint8List _allocateBuffer(
      String input, int start, int end, int state) {
    assert(state >= 0);
    var paddingStart = _trimPaddingChars(input, start, end);
    var length = _stateCount(state) + (paddingStart - start);
    // Three bytes per full four bytes in the input.
    var bufferLength = (length >> 2) * 3;
    // If padding was seen, then this is the last chunk, and the final partial
    // chunk should be decoded too.
    var remainderLength = length & 3;
    if (remainderLength != 0 && paddingStart < end) {
      bufferLength += remainderLength - 1;
    }
    if (bufferLength > 0) return Uint8List(bufferLength);
    // If the input plus state is less than four characters, and it's not
    // at the end of input, no buffer is needed.
    return _emptyBuffer;
  }

  /// Returns the position of the start of padding at the end of the input.
  ///
  /// Returns the end of input if there is no padding.
  ///
  /// This is used to ensure that the decoding buffer has the exact size
  /// it needs when input is valid, and at least enough bytes to reach the error
  /// when input is invalid.
  ///
  /// Never count more than two padding sequences as any more than that
  /// will raise an error anyway, and we only care about being precise for
  /// successful conversions.
  static int _trimPaddingChars(String input, int start, int end) {
    // This may count '%=' as two paddings. That's ok, it will err later,
    // but the buffer will be large enough to reach the error.
    var padding = 0;
    var index = end;
    var newEnd = end;
    while (index > start && padding < 2) {
      index--;
      var char = input.codeUnitAt(index);
      if (char == _paddingChar) {
        padding++;
        newEnd = index;
        continue;
      }
      if ((char | 0x20) == _char_d) {
        if (index == start) break;
        index--;
        char = input.codeUnitAt(index);
      }
      if (char == _char_3) {
        if (index == start) break;
        index--;
        char = input.codeUnitAt(index);
      }
      if (char == _char_percent) {
        padding++;
        newEnd = index;
        continue;
      }
      break;
    }
    return newEnd;
  }

  /// Check that the remainder of the string is valid padding.
  ///
  /// Valid padding is a correct number (0, 1 or 2) of `=` characters
  /// or `%3D` sequences depending on the number of preceding base64 characters.
  /// The [state] parameter encodes which padding continuations are allowed
  /// as the number of expected characters. That number is the number of
  /// expected padding characters times 3 minus the number of padding characters
  /// seen so far, where `=` counts as 3 counts as three characters,
  /// and the padding sequence `%3D` counts as one character per character.
  ///
  /// The number of missing characters is always between 0 and 5 because we
  /// only call this function after having seen at least one `=` or `%`
  /// character.
  /// If the number of missing characters is not 3 or 0, we have seen (at least)
  /// a `%` character and expect the rest of the `%3D` sequence, and a `=` is
  /// not allowed. When missing 3 characters, either `=` or `%` is allowed.
  ///
  /// When the value is 0, no more padding (or any other character) is allowed.
  static int _checkPadding(String input, int start, int end, int state) {
    assert(_hasSeenPadding(state));
    if (start == end) return state;
    var expectedPadding = _statePadding(state);
    assert(expectedPadding >= 0);
    assert(expectedPadding < 6);
    while (expectedPadding > 0) {
      var char = input.codeUnitAt(start);
      if (expectedPadding == 3) {
        if (char == _paddingChar) {
          expectedPadding -= 3;
          start++;
          break;
        }
        if (char == _char_percent) {
          expectedPadding--;
          start++;
          if (start == end) break;
          char = input.codeUnitAt(start);
        } else {
          break;
        }
      }
      // Partial padding means we have seen part of a "%3D" escape.
      var expectedPartialPadding = expectedPadding;
      if (expectedPartialPadding > 3) expectedPartialPadding -= 3;
      if (expectedPartialPadding == 2) {
        // Expects '3'
        if (char != _char_3) break;
        start++;
        expectedPadding--;
        if (start == end) break;
        char = input.codeUnitAt(start);
      }
      // Expects 'D' or 'd'.
      if ((char | 0x20) != _char_d) break;
      start++;
      expectedPadding--;
      if (start == end) break;
    }
    if (start != end) {
      throw FormatException("Invalid padding character", input, start);
    }
    return _encodePaddingState(expectedPadding);
  }
}

class _Base64DecoderSink extends StringConversionSinkBase {
  /// Output sink
  final Sink<List<int>> _sink;
  final _Base64Decoder _decoder = _Base64Decoder();

  _Base64DecoderSink(this._sink);

  void add(String string) {
    if (string.isEmpty) return;
    var buffer = _decoder.decode(string, 0, string.length);
    if (buffer != null) _sink.add(buffer);
  }

  void close() {
    _decoder.close(null, null);
    _sink.close();
  }

  void addSlice(String string, int start, int end, bool isLast) {
    RangeError.checkValidRange(start, end, string.length);
    if (start == end) return;
    var buffer = _decoder.decode(string, start, end);
    if (buffer != null) _sink.add(buffer);
    if (isLast) {
      _decoder.close(string, end);
      _sink.close();
    }
  }
}
