// 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();

const int _ASCII_MASK = 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(_ASCII_MASK);
}

/**
 * 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
   * [_ASCII_MASK] 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, _ASCII_MASK);

  /**
   * 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] & ~_ASCII_MASK) != 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] & ~_ASCII_MASK) != 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();
  }
}
