// Copyright (c) 2013, 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;

/**
 * An instance of the default implementation of the [AsciiCodec].
 *
 * This instance provides a convenient access to the most common ASCII
 * use cases.
 *
 * Examples:
 *
 *     var encoded = ascii.encode("This is ASCII!");
 *     var decoded = ascii.decode([0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
 *                                 0x20, 0x41, 0x53, 0x43, 0x49, 0x49, 0x21]);
 */
const AsciiCodec ascii = const AsciiCodec();
@Deprecated("Use ascii instead")
const AsciiCodec ASCII = ascii;

const int _asciiMask = 0x7F;

/**
 * An [AsciiCodec] allows encoding strings as ASCII bytes
 * and decoding ASCII bytes to strings.
 */
class AsciiCodec extends Encoding {
  final bool _allowInvalid;
  /**
   * Instantiates a new [AsciiCodec].
   *
   * If [allowInvalid] is true, the [decode] method and the converter
   * returned by [decoder] will default to allowing invalid values.
   * If allowing invalid values, the values will be decoded into the Unicode
   * Replacement character (U+FFFD). If not, an exception will be thrown.
   * Calls to the [decode] method can choose to override this default.
   *
   * Encoders will not accept invalid (non Latin-1) characters.
   */
  const AsciiCodec({bool allowInvalid: false}) : _allowInvalid = allowInvalid;

  String get name => "us-ascii";

  /**
   * Decodes the ASCII [bytes] (a list of unsigned 7-bit integers) to the
   * corresponding string.
   *
   * If [bytes] contains values that are not in the range 0 .. 127, the decoder
   * will eventually throw a [FormatException].
   *
   * If [allowInvalid] is not provided, it defaults to the value used to create
   * this [AsciiCodec].
   */
  String decode(List<int> bytes, {bool allowInvalid}) {
    if (allowInvalid == null) allowInvalid = _allowInvalid;
    if (allowInvalid) {
      return const AsciiDecoder(allowInvalid: true).convert(bytes);
    } else {
      return const AsciiDecoder(allowInvalid: false).convert(bytes);
    }
  }

  AsciiEncoder get encoder => const AsciiEncoder();

  AsciiDecoder get decoder => _allowInvalid
      ? const AsciiDecoder(allowInvalid: true)
      : const AsciiDecoder(allowInvalid: false);
}

// Superclass for [AsciiEncoder] and [Latin1Encoder].
// Generalizes common operations that only differ by a mask;
class _UnicodeSubsetEncoder extends Converter<String, List<int>> {
  final int _subsetMask;

  const _UnicodeSubsetEncoder(this._subsetMask);

  /**
   * Converts the [String] into a list of its code units.
   *
   * If [start] and [end] are provided, only the substring
   * `string.substring(start, end)` is used as input to the conversion.
   */
  List<int> convert(String string, [int start = 0, int end]) {
    int stringLength = string.length;
    RangeError.checkValidRange(start, end, stringLength);
    if (end == null) end = stringLength;
    int length = end - start;
    List<int> result = new Uint8List(length);
    for (int i = 0; i < length; i++) {
      var codeUnit = string.codeUnitAt(start + i);
      if ((codeUnit & ~_subsetMask) != 0) {
        throw new ArgumentError("String contains invalid characters.");
      }
      result[i] = codeUnit;
    }
    return result;
  }

  /**
   * Starts a chunked conversion.
   *
   * The converter works more efficiently if the given [sink] is a
   * [ByteConversionSink].
   */
  StringConversionSink startChunkedConversion(Sink<List<int>> sink) {
    if (sink is! ByteConversionSink) {
      sink = new ByteConversionSink.from(sink);
    }
    return new _UnicodeSubsetEncoderSink(_subsetMask, sink);
  }

  // Override the base-class' bind, to provide a better type.
  Stream<List<int>> bind(Stream<String> stream) => super.bind(stream);
}

/**
 * This class converts strings of only ASCII characters to bytes.
 */
class AsciiEncoder extends _UnicodeSubsetEncoder {
  const AsciiEncoder() : super(_asciiMask);
}

/**
 * This class encodes chunked strings to bytes (unsigned 8-bit
 * integers).
 */
class _UnicodeSubsetEncoderSink extends StringConversionSinkBase {
  final ByteConversionSink _sink;
  final int _subsetMask;

  _UnicodeSubsetEncoderSink(this._subsetMask, this._sink);

  void close() {
    _sink.close();
  }

  void addSlice(String source, int start, int end, bool isLast) {
    RangeError.checkValidRange(start, end, source.length);
    for (int i = start; i < end; i++) {
      int codeUnit = source.codeUnitAt(i);
      if ((codeUnit & ~_subsetMask) != 0) {
        throw new ArgumentError(
            "Source contains invalid character with code point: $codeUnit.");
      }
    }
    _sink.add(source.codeUnits.sublist(start, end));
    if (isLast) {
      close();
    }
  }
}

/**
 * This class converts Latin-1 bytes (lists of unsigned 8-bit integers)
 * to a string.
 */
abstract class _UnicodeSubsetDecoder extends Converter<List<int>, String> {
  final bool _allowInvalid;
  final int _subsetMask;

  /**
   * Instantiates a new decoder.
   *
   * The [_allowInvalid] argument defines how [convert] deals
   * with invalid bytes.
   *
   * The [_subsetMask] argument is a bit mask used to define the subset
   * of Unicode being decoded. Use [_LATIN1_MASK] for Latin-1 (8-bit) or
   * [_asciiMask] for ASCII (7-bit).
   *
   * If [_allowInvalid] is `true`, [convert] replaces invalid bytes with the
   * Unicode Replacement character `U+FFFD` (�).
   * Otherwise it throws a [FormatException].
   */
  const _UnicodeSubsetDecoder(this._allowInvalid, this._subsetMask);

  /**
   * Converts the [bytes] (a list of unsigned 7- or 8-bit integers) to the
   * corresponding string.
   *
   * If [start] and [end] are provided, only the sub-list of bytes from
   * `start` to `end` (`end` not inclusive) is used as input to the conversion.
   */
  String convert(List<int> bytes, [int start = 0, int end]) {
    int byteCount = bytes.length;
    RangeError.checkValidRange(start, end, byteCount);
    if (end == null) end = byteCount;

    for (int i = start; i < end; i++) {
      int byte = bytes[i];
      if ((byte & ~_subsetMask) != 0) {
        if (!_allowInvalid) {
          throw new FormatException("Invalid value in input: $byte");
        }
        return _convertInvalid(bytes, start, end);
      }
    }
    return new String.fromCharCodes(bytes, start, end);
  }

  String _convertInvalid(List<int> bytes, int start, int end) {
    StringBuffer buffer = new StringBuffer();
    for (int i = start; i < end; i++) {
      int value = bytes[i];
      if ((value & ~_subsetMask) != 0) value = 0xFFFD;
      buffer.writeCharCode(value);
    }
    return buffer.toString();
  }

  /**
   * Starts a chunked conversion.
   *
   * The converter works more efficiently if the given [sink] is a
   * [StringConversionSink].
   */
  ByteConversionSink startChunkedConversion(Sink<String> sink);

  // Override the base-class's bind, to provide a better type.
  Stream<String> bind(Stream<List<int>> stream) => super.bind(stream);
}

class AsciiDecoder extends _UnicodeSubsetDecoder {
  const AsciiDecoder({bool allowInvalid: false})
      : super(allowInvalid, _asciiMask);

  /**
   * Starts a chunked conversion.
   *
   * The converter works more efficiently if the given [sink] is a
   * [StringConversionSink].
   */
  ByteConversionSink startChunkedConversion(Sink<String> sink) {
    StringConversionSink stringSink;
    if (sink is StringConversionSink) {
      stringSink = sink;
    } else {
      stringSink = new StringConversionSink.from(sink);
    }
    // TODO(lrn): Use asUtf16Sink when it becomes available. It
    // works just as well, is likely to have less decoding overhead,
    // and make adding U+FFFD easier.
    // At that time, merge this with _Latin1DecoderSink;
    if (_allowInvalid) {
      return new _ErrorHandlingAsciiDecoderSink(stringSink.asUtf8Sink(false));
    } else {
      return new _SimpleAsciiDecoderSink(stringSink);
    }
  }
}

class _ErrorHandlingAsciiDecoderSink extends ByteConversionSinkBase {
  ByteConversionSink _utf8Sink;
  _ErrorHandlingAsciiDecoderSink(this._utf8Sink);

  void close() {
    _utf8Sink.close();
  }

  void add(List<int> source) {
    addSlice(source, 0, source.length, false);
  }

  void addSlice(List<int> source, int start, int end, bool isLast) {
    RangeError.checkValidRange(start, end, source.length);
    for (int i = start; i < end; i++) {
      if ((source[i] & ~_asciiMask) != 0) {
        if (i > start) _utf8Sink.addSlice(source, start, i, false);
        // Add UTF-8 encoding of U+FFFD.
        _utf8Sink.add(const <int>[0xEF, 0xBF, 0xBD]);
        start = i + 1;
      }
    }
    if (start < end) {
      _utf8Sink.addSlice(source, start, end, isLast);
    } else if (isLast) {
      close();
    }
  }
}

class _SimpleAsciiDecoderSink extends ByteConversionSinkBase {
  Sink _sink;
  _SimpleAsciiDecoderSink(this._sink);

  void close() {
    _sink.close();
  }

  void add(List<int> source) {
    for (int i = 0; i < source.length; i++) {
      if ((source[i] & ~_asciiMask) != 0) {
        throw new FormatException("Source contains non-ASCII bytes.");
      }
    }
    _sink.add(new String.fromCharCodes(source));
  }

  void addSlice(List<int> source, int start, int end, bool isLast) {
    final int length = source.length;
    RangeError.checkValidRange(start, end, length);
    if (start < end) {
      if (start != 0 || end != length) {
        source = source.sublist(start, end);
      }
      add(source);
    }
    if (isLast) close();
  }
}
