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

/**
 * The [ByteConversionSink] provides an interface for converters to
 * efficiently transmit byte data.
 *
 * Instead of limiting the interface to one non-chunked list of bytes it
 * accepts its input in chunks (themselves being lists of bytes).
 *
 * This abstract class will likely get more methods over time. Implementers are
 * urged to extend or mix in [ByteConversionSinkBase] to ensure that their
 * class covers the newly added methods.
 */
abstract class ByteConversionSink extends ChunkedConversionSink<List<int>> {
  ByteConversionSink();
  factory ByteConversionSink.withCallback(void callback(List<int> accumulated))
      = _ByteCallbackSink;
  factory ByteConversionSink.from(ChunkedConversionSink<List<int>> sink)
      = _ByteAdapterSink;

  /**
   * Adds the next [chunk] to `this`.
   *
   * Adds the bytes defined by [start] and [end]-exclusive to `this`.
   *
   * If [isLast] is `true` closes `this`.
   *
   * Contrary to `add` the given [chunk] must not be held onto. Once the method
   * returns, it is safe to overwrite the data in it.
   */
  void addSlice(List<int> chunk, int start, int end, bool isLast);

  // TODO(floitsch): add more methods:
  // - iterateBytes.
}

/**
 * This class provides a base-class for converters that need to accept byte
 * inputs.
 */
abstract class ByteConversionSinkBase extends ByteConversionSink {

  void add(List<int> chunk);
  void close();

  void addSlice(List<int> chunk, int start, int end, bool isLast) {
    add(chunk.sublist(start, end));
    if (isLast) close();
  }
}

/**
 * This class adapts a simple [ChunkedConversionSink] to a [ByteConversionSink].
 *
 * All additional methods of the [ByteConversionSink] (compared to the
 * ChunkedConversionSink) are redirected to the `add` method.
 */
class _ByteAdapterSink extends ByteConversionSinkBase {
  final ChunkedConversionSink<List<int>> _sink;

  _ByteAdapterSink(this._sink);

  void add(List<int> chunk) => _sink.add(chunk);
  void close() => _sink.close();
}

/**
 * This class accumulates all chunks into one list of bytes
 * and invokes a callback when the sink is closed.
 *
 * This class can be used to terminate a chunked conversion.
 */
class _ByteCallbackSink extends ByteConversionSinkBase {
  static const _INITIAL_BUFFER_SIZE = 1024;

  final _ChunkedConversionCallback<List<int>> _callback;
  // TODO(11971, floitsch): use Uint8List instead of normal lists.
  List<int> _buffer = new List<int>(_INITIAL_BUFFER_SIZE);
  int _bufferIndex = 0;

  _ByteCallbackSink(void callback(List<int> accumulated))
      : this._callback = callback;

  void add(Iterable<int> chunk) {
    int freeCount = _buffer.length - _bufferIndex;
    if (chunk.length > freeCount) {
      // Grow the buffer.
      int oldLength = _buffer.length;
      int newLength = _roundToPowerOf2(chunk.length + oldLength) * 2;
      // TODO(11971, floitsch): use Uint8List instead of normal lists.
      List<int> grown = new List<int>(newLength);
      grown.setRange(0, _buffer.length, _buffer);
      _buffer = grown;
    }
    _buffer.setRange(_bufferIndex, _bufferIndex + chunk.length, chunk);
    _bufferIndex += chunk.length;
  }

  static int _roundToPowerOf2(int v) {
    assert(v > 0);
    v--;
    v |= v >> 1;
    v |= v >> 2;
    v |= v >> 4;
    v |= v >> 8;
    v |= v >> 16;
    v++;
    return v;
  }

  void close() {
    _callback(_buffer.sublist(0, _bufferIndex));
  }
}
