// 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.
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,
  /// are 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.
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 since 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 expects 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();
    }
  }
}
