// 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(Sink<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 [Sink] to a [ByteConversionSink].
 *
 * All additional methods of the [ByteConversionSink] (compared to the
 * ChunkedConversionSink) are redirected to the `add` method.
 */
class _ByteAdapterSink extends ByteConversionSinkBase {
  final Sink<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;
  List<int> _buffer = new Uint8List(_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;
      List<int> grown = new Uint8List(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));
  }
}
