// Copyright (c) 2012, 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.

#ifndef RUNTIME_VM_DATASTREAM_H_
#define RUNTIME_VM_DATASTREAM_H_

#include "platform/assert.h"
#include "platform/utils.h"
#include "vm/allocation.h"
#include "vm/exceptions.h"
#include "vm/globals.h"
#include "vm/os.h"
#include "vm/zone.h"

namespace dart {

static constexpr int8_t kDataBitsPerByte = 7;
static constexpr int8_t kByteMask = (1 << kDataBitsPerByte) - 1;
static constexpr int8_t kMaxUnsignedDataPerByte = kByteMask;
static constexpr int8_t kMinDataPerByte = -(1 << (kDataBitsPerByte - 1));
static constexpr int8_t kMaxDataPerByte =
    (~kMinDataPerByte & kByteMask);  // NOLINT
static constexpr uint8_t kEndByteMarker = (255 - kMaxDataPerByte);
static constexpr uint8_t kEndUnsignedByteMarker =
    (255 - kMaxUnsignedDataPerByte);

struct LEB128Constants : AllStatic {
  // Convenience template for ensuring non-signed types trigger SFINAE.
  template <typename T, typename S>
  using only_if_signed =
      typename std::enable_if<std::is_signed<T>::value, S>::type;

  // Convenience template for ensuring signed types trigger SFINAE.
  template <typename T, typename S>
  using only_if_unsigned =
      typename std::enable_if<std::is_unsigned<T>::value, S>::type;

  // (S)LEB128 encodes 7 bits of data per byte (hence 128).
  static constexpr uint8_t kDataBitsPerByte = 7;
  static constexpr uint8_t kDataByteMask = (1 << kDataBitsPerByte) - 1;
  // If more data follows a given data byte, the high bit is set.
  static constexpr uint8_t kMoreDataMask = (1 << kDataBitsPerByte);
  // For SLEB128, the high bit in the data of the last byte is the sign bit.
  static constexpr uint8_t kSignMask = (1 << (kDataBitsPerByte - 1));
};

class NonStreamingWriteStream;

// Stream for reading various types from a buffer.
class ReadStream : public ValueObject {
 public:
  ReadStream(const uint8_t* buffer, intptr_t size)
      : buffer_(buffer), current_(buffer), end_(buffer + size) {}

  // Creates a ReadStream that starts at a given position in the buffer.
  ReadStream(const uint8_t* buffer, intptr_t size, intptr_t pos)
      : ReadStream(buffer, size) {
    SetPosition(pos);
  }

  template <int N, typename T>
  class Raw {};

  template <typename T>
  class Raw<1, T> {
   public:
    static T Read(ReadStream* st) { return bit_cast<T>(st->ReadByte()); }
  };

  template <typename T>
  class Raw<2, T> {
   public:
    static T Read(ReadStream* st) { return bit_cast<T>(st->Read16()); }
  };

  template <typename T>
  class Raw<4, T> {
   public:
    static T Read(ReadStream* st) { return bit_cast<T>(st->Read32()); }
  };

  template <typename T>
  class Raw<8, T> {
   public:
    static T Read(ReadStream* st) { return bit_cast<T>(st->Read64()); }
  };

  // Reads 'len' bytes from the stream.
  void ReadBytes(void* addr, intptr_t len) {
    ASSERT((end_ - current_) >= len);
    if (len != 0) {
      memmove(addr, current_, len);
    }
    current_ += len;
  }

  template <typename T = intptr_t>
  T ReadUnsigned() {
    return Read<T>(kEndUnsignedByteMarker);
  }

  intptr_t ReadRefId() {
    const int8_t* cursor = reinterpret_cast<const int8_t*>(current_);
    intptr_t result = 0;
    intptr_t byte;
    // clang-format off
#define STAGE                                                                  \
    byte = *cursor++;              /* ldrsb byte, [result], 1  */              \
    result = byte + (result << 7); /* add result, byte, result lsl 7 */        \
    if (byte < 0) goto done;       /* tbnz byte, 63, done */
    STAGE  // 0-7
    STAGE  // 8-14
    STAGE  // 15-21
    STAGE  // 22-28
#undef STAGE
    ASSERT(byte < 0);  // 256MB is enough for anyone...
    // clang-format on
  done:
    current_ = reinterpret_cast<const uint8_t*>(cursor);
    // With big-endian order and the has-more marker being 0, the correction
    // factor to remove the last-byte marker is a constant, which can be folded
    // into subsequent load offsets.
    return result + 128;
  }

  intptr_t Position() const { return current_ - buffer_; }
  void SetPosition(intptr_t value) {
    ASSERT((end_ - buffer_) >= value);
    current_ = buffer_ + value;
  }

  void Align(intptr_t alignment, intptr_t offset = 0) {
    intptr_t position_before = Position();
    intptr_t position_after =
        Utils::RoundUp(position_before, alignment, offset);
    Advance(position_after - position_before);
  }

  const uint8_t* AddressOfCurrentPosition() const { return current_; }

  void Advance(intptr_t value) {
    ASSERT((end_ - current_) >= value);
    current_ = current_ + value;
  }

  intptr_t PendingBytes() const {
    ASSERT(end_ >= current_);
    return (end_ - current_);
  }

  template <typename T>
  T Read() {
    return Read<T>(kEndByteMarker);
  }

  uword ReadWordWith32BitReads() {
    constexpr intptr_t kNumRead32PerWord = kBitsPerWord / kBitsPerInt32;

    uword value = 0;
    for (intptr_t j = 0; j < kNumRead32PerWord; j++) {
      const auto partial_value = Raw<kInt32Size, uint32_t>::Read(this);
      value |= (static_cast<uword>(partial_value) << (j * kBitsPerInt32));
    }
    return value;
  }

 private:
  using C = LEB128Constants;

 public:
  template <typename T = uintptr_t>
  C::only_if_unsigned<T, T> ReadLEB128() {
    constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T);
    T r = 0;
    uint8_t s = 0;
    uint8_t b;
    do {
      ASSERT(s < kBitsPerT);
      b = ReadByte();
      r |= static_cast<T>(b & C::kDataByteMask) << s;
      s += C::kDataBitsPerByte;
    } while ((b & C::kMoreDataMask) != 0);
    ASSERT(s < C::kDataBitsPerByte + kBitsPerT);
    return r;
  }

  template <typename T>
  C::only_if_signed<T, T> ReadLEB128() {
    return bit_cast<T>(ReadLEB128<typename std::make_unsigned<T>::type>());
  }

  template <typename T>
  C::only_if_unsigned<T, T> ReadSLEB128() {
    constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T);
    T r = 0;
    uint8_t s = 0;
    uint8_t b;
    do {
      ASSERT(s < kBitsPerT);
      b = ReadByte();
      r |= static_cast<T>(b & C::kDataByteMask) << s;
      s += C::kDataBitsPerByte;
    } while ((b & C::kMoreDataMask) != 0);
    ASSERT(s < C::kDataBitsPerByte + kBitsPerT);
    // At this point, [s] contains how many data bits have made it into the
    // value. If the value is negative and the count of data bits is less than
    // the size of the value, then we need to extend the sign by setting the
    // remaining (unset) most significant bits (MSBs).
    T sign_bits = 0;
    if ((b & C::kSignMask) != 0 && s < kBitsPerT) {
      // Create a bitmask for the current data bits and invert it.
      sign_bits = ~((static_cast<T>(1) << s) - 1);
    }
    return r | sign_bits;
  }

  template <typename T = intptr_t>
  C::only_if_signed<T, T> ReadSLEB128() {
    return bit_cast<T>(ReadSLEB128<typename std::make_unsigned<T>::type>());
  }

 private:
  uint16_t Read16() { return Read16(kEndByteMarker); }

  uint32_t Read32() { return Read32(kEndByteMarker); }

  uint64_t Read64() { return Read64(kEndByteMarker); }

  template <typename T>
  T Read(uint8_t end_byte_marker) {
    using Unsigned = typename std::make_unsigned<T>::type;
    Unsigned b = ReadByte();
    if (b > kMaxUnsignedDataPerByte) {
      return b - end_byte_marker;
    }
    T r = 0;
    uint8_t s = 0;
    do {
      r |= static_cast<Unsigned>(b) << s;
      s += kDataBitsPerByte;
      b = ReadByte();
    } while (b <= kMaxUnsignedDataPerByte);
    return r | (static_cast<Unsigned>(b - end_byte_marker) << s);
  }

// Setting up needed variables for the unrolled loop sections below.
#define UNROLLED_INIT()                                                        \
  using Unsigned = typename std::make_unsigned<T>::type;                       \
  Unsigned b = ReadByte();                                                     \
  if (b > kMaxUnsignedDataPerByte) {                                           \
    return b - end_byte_marker;                                                \
  }                                                                            \
  T r = b;

// Part of the unrolled loop where the loop may stop, having read the last part,
// or continue reading.
#define UNROLLED_BODY(bit_start)                                               \
  static_assert(bit_start % kDataBitsPerByte == 0,                             \
                "Bit start must be a multiple of the data bits per byte");     \
  static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T),        \
                "Starting unrolled body at invalid bit position");             \
  static_assert(bit_start + kDataBitsPerByte < kBitsPerByte * sizeof(T),       \
                "Unrolled body should not contain final bits in value");       \
  b = ReadByte();                                                              \
  if (b > kMaxUnsignedDataPerByte) {                                           \
    return r | (static_cast<T>(b - end_byte_marker) << bit_start);             \
  }                                                                            \
  r |= b << bit_start;

// The end of the unrolled loop.
#define UNROLLED_END(bit_start)                                                \
  static_assert(bit_start % kDataBitsPerByte == 0,                             \
                "Bit start must be a multiple of the data bits per byte");     \
  static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T),        \
                "Starting unrolled end at invalid bit position");              \
  static_assert(bit_start + kDataBitsPerByte >= kBitsPerByte * sizeof(T),      \
                "Unrolled end does not contain final bits in value");          \
  b = ReadByte();                                                              \
  ASSERT(b > kMaxUnsignedDataPerByte);                                         \
  return r | (static_cast<T>(b - end_byte_marker) << bit_start);

  uint16_t Read16(uint8_t end_byte_marker) {
    using T = uint16_t;
    UNROLLED_INIT();
    UNROLLED_BODY(7);
    UNROLLED_END(14);
  }

  uint32_t Read32(uint8_t end_byte_marker) {
    using T = uint32_t;
    UNROLLED_INIT();
    UNROLLED_BODY(7);
    UNROLLED_BODY(14);
    UNROLLED_BODY(21);
    UNROLLED_END(28);
  }

  uint64_t Read64(uint8_t end_byte_marker) {
    using T = uint64_t;
    UNROLLED_INIT();
    UNROLLED_BODY(7);
    UNROLLED_BODY(14);
    UNROLLED_BODY(21);
    UNROLLED_BODY(28);
    UNROLLED_BODY(35);
    UNROLLED_BODY(42);
    UNROLLED_BODY(49);
    UNROLLED_BODY(56);
    UNROLLED_END(63);
  }

  DART_FORCE_INLINE uint8_t ReadByte() {
    ASSERT(current_ < end_);
    return *current_++;
  }

 private:
  ReadStream(const uint8_t* buffer, const uint8_t* current, const uint8_t* end)
      : buffer_(buffer), current_(current), end_(end) {}

  const uint8_t* buffer_;
  const uint8_t* current_;
  const uint8_t* end_;

  friend class Deserializer;
  DISALLOW_COPY_AND_ASSIGN(ReadStream);
};

// Base class for streams that write bytes to some backing store. Generally,
// BaseWriteStream is a more appropriate superclass of new WriteStreams since
// it offers more functionality (e.g., Printf).
struct AbstractWriteStream : public ValueObject {
  AbstractWriteStream() {}
  virtual ~AbstractWriteStream() {}

  virtual intptr_t Position() const = 0;
  virtual intptr_t Align(intptr_t alignment, intptr_t offset = 0) = 0;
  virtual void WriteBytes(const void* addr, intptr_t len) = 0;
  virtual void WriteByte(uint8_t value) = 0;

 private:
  using C = LEB128Constants;

 public:
  template <typename T>
  C::only_if_unsigned<T, void> WriteLEB128(T value) {
    T remainder = value;
    bool is_last_part;
    do {
      uint8_t part = static_cast<uint8_t>(remainder & C::kDataByteMask);
      remainder >>= C::kDataBitsPerByte;
      // For unsigned types, we're done when the remainder has no bits set.
      is_last_part = remainder == static_cast<T>(0);
      if (!is_last_part) {
        // Mark this part as a non-final part for this value.
        part |= C::kMoreDataMask;
      }
      WriteByte(part);
    } while (!is_last_part);
  }

  template <typename T>
  C::only_if_signed<T, void> WriteLEB128(T value) {
    // If we're trying to LEB128 encode a negative value, chances are we should
    // be using SLEB128 instead.
    ASSERT(value >= 0);
    return WriteLEB128(bit_cast<typename std::make_unsigned<T>::type>(value));
  }

  template <typename T>
  C::only_if_signed<T, void> WriteSLEB128(T value) {
    constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T);
    using Unsigned = typename std::make_unsigned<T>::type;
    // Record whether the original value was negative.
    const bool is_negative = value < 0;
    T remainder = value;
    bool is_last_part;
    do {
      uint8_t part = static_cast<uint8_t>(remainder & C::kDataByteMask);
      remainder >>= C::kDataBitsPerByte;
      // For signed types, we're done when either:
      // - the remainder has all bits set and the part's sign bit is set
      //   for negative values, or
      // - the remainder has no bits set and the part's sign bit is unset for
      //   non-negative values.
      // If the remainder matches but the sign bit does not, we need one more
      // part to set the sign bit correctly when decoding.
      if (is_negative) {
        // Right shifts of negative values in C are not guaranteed to be
        // arithmetic. For negative values, set the [kDataBitsPerByte] most
        // significant bits after shifting to ensure the value stays negative.
        constexpr intptr_t preserved_bits = kBitsPerT - C::kDataBitsPerByte;
        // The sign extension mask is the inverse of the preserved bits mask.
        constexpr T sign_extend =
            ~static_cast<T>((static_cast<Unsigned>(1) << preserved_bits) - 1);
        // Sign extend for negative values just in case a non-arithmetic right
        // shift is used by the compiler.
        remainder |= sign_extend;
        ASSERT(remainder < 0);  // Remainder should still be negative.
        is_last_part =
            remainder == ~static_cast<T>(0) && (part & C::kSignMask) != 0;
      } else {
        ASSERT(remainder >= 0);  // Remainder should still be non-negative.
        is_last_part =
            (remainder == static_cast<T>(0) && (part & C::kSignMask) == 0);
      }
      if (!is_last_part) {
        // Mark this part as a non-final part for this value.
        part |= C::kMoreDataMask;
      }
      WriteByte(part);
    } while (!is_last_part);
  }

  template <typename T>
  C::only_if_unsigned<T, void> WriteSLEB128(T value) {
    return WriteSLEB128(bit_cast<typename std::make_signed<T>::type>(value));
  }
};

// Base class for streams that writing various types into a buffer, possibly
// flushing data out periodically to a more permanent store.
class BaseWriteStream : public AbstractWriteStream {
 public:
  explicit BaseWriteStream(intptr_t initial_size)
      : initial_size_(Utils::RoundUpToPowerOfTwo(initial_size)) {}

  DART_FORCE_INLINE intptr_t bytes_written() const { return Position(); }
  virtual intptr_t Position() const { return current_ - buffer_; }
  intptr_t initial_size() const { return initial_size_; }

  virtual intptr_t Align(intptr_t alignment, intptr_t offset = 0) {
    const intptr_t position_before = Position();
    const intptr_t position_after =
        Utils::RoundUp(position_before, alignment, offset);
    const intptr_t length = position_after - position_before;
    if (length != 0) {
      EnsureSpace(length);
      memset(current_, 0, length);
      SetPosition(position_after);
    }
    return length;
  }

  template <int N, typename T>
  class Raw {};

  template <typename T>
  class Raw<1, T> {
   public:
    static void Write(BaseWriteStream* st, T value) {
      st->WriteByte(bit_cast<uint8_t>(value));
    }
  };

  template <typename T>
  class Raw<2, T> {
   public:
    static void Write(BaseWriteStream* st, T value) {
      st->Write<int16_t>(bit_cast<int16_t>(value));
    }
  };

  template <typename T>
  class Raw<4, T> {
   public:
    static void Write(BaseWriteStream* st, T value) {
      st->Write<int32_t>(bit_cast<int32_t>(value));
    }
  };

  template <typename T>
  class Raw<8, T> {
   public:
    static void Write(BaseWriteStream* st, T value) {
      st->Write<int64_t>(bit_cast<int64_t>(value));
    }
  };

  void WriteWordWith32BitWrites(uword value) {
    constexpr intptr_t kNumWrite32PerWord = kBitsPerWord / kBitsPerInt32;

    const uint32_t mask = Utils::NBitMask(kBitsPerInt32);
    for (intptr_t j = 0; j < kNumWrite32PerWord; j++) {
      const uint32_t shifted_value = (value >> (j * kBitsPerInt32));
      Raw<kInt32Size, uint32_t>::Write(this, shifted_value & mask);
    }
  }

  template <typename T>
  void WriteUnsigned(T value) {
    ASSERT(value >= 0);
    while (value > kMaxUnsignedDataPerByte) {
      WriteByte(static_cast<uint8_t>(value & kByteMask));
      value = value >> kDataBitsPerByte;
    }
    WriteByte(static_cast<uint8_t>(value + kEndUnsignedByteMarker));
  }

  void WriteRefId(intptr_t value) {
    ASSERT(Utils::IsUint(28, value));  // 256MB is enough for anyone...
    EnsureSpace(4);
    if ((value >> 21) != 0) {
      *current_++ = (value >> 21) & 127;
    }
    if ((value >> 14) != 0) {
      *current_++ = (value >> 14) & 127;
    }
    if ((value >> 7) != 0) {
      *current_++ = (value >> 7) & 127;
    }
    *current_++ = ((value >> 0) & 127) | 128;
  }

  void WriteBytes(const void* addr, intptr_t len) {
    if (len != 0) {
      EnsureSpace(len);
      memmove(current_, addr, len);
      current_ += len;
    }
  }

  void WriteWord(uword value) { WriteFixed(value); }

  void WriteTargetWord(word value);

  void Printf(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
    va_list args;
    va_start(args, format);
    VPrintf(format, args);
    va_end(args);
  }

  void VPrintf(const char* format, va_list args) {
    // Measure.
    va_list measure_args;
    va_copy(measure_args, args);
    intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
    va_end(measure_args);

    // Alloc.
    EnsureSpace(len + 1);

    // Print.
    va_list print_args;
    va_copy(print_args, args);
    Utils::VSNPrint(reinterpret_cast<char*>(current_), len + 1, format,
                    print_args);
    va_end(print_args);
    current_ += len;  // Not len + 1 to swallow the terminating NUL.
  }

  template <typename T>
  void Write(T value) {
    T v = value;
    while (v < kMinDataPerByte || v > kMaxDataPerByte) {
      WriteByte(static_cast<uint8_t>(v & kByteMask));
      v = v >> kDataBitsPerByte;
    }
    WriteByte(static_cast<uint8_t>(v + kEndByteMarker));
  }

  template <typename T>
  void WriteFixed(T value) {
    WriteBytes(&value, sizeof(value));
  }

  DART_FORCE_INLINE virtual void WriteByte(uint8_t value) {
    EnsureSpace(1);
    *current_++ = value;
  }

  void WriteString(const char* cstr) { WriteBytes(cstr, strlen(cstr)); }

 protected:
  void EnsureSpace(intptr_t size_needed) {
    if (Remaining() >= size_needed) return;
    intptr_t increment_size = capacity_;
    if (size_needed > increment_size) {
      increment_size = Utils::RoundUp(size_needed, initial_size_);
    }
    intptr_t new_size = capacity_ + increment_size;
    ASSERT(new_size > capacity_);
    Realloc(new_size);
    if (buffer_ == nullptr) {
      Exceptions::ThrowOOM();
    }
    ASSERT(Remaining() >= size_needed);
  }

  virtual void SetPosition(intptr_t value) {
    EnsureSpace(value - BaseWriteStream::Position());
    current_ = buffer_ + value;
  }

  DART_FORCE_INLINE intptr_t Remaining() const {
    return capacity_ - BaseWriteStream::Position();
  }

  // Resizes the internal buffer to the requested new capacity. Should set
  // buffer_, capacity_, and current_ appropriately.
  //
  // Instead of templating over an Allocator (which would then cause users
  // of the templated class to need to be templated, etc.), we just add an
  // Realloc method to override appropriately in subclasses. Less flexible,
  // but requires less changes throughout the codebase.
  virtual void Realloc(intptr_t new_capacity) = 0;

  const intptr_t initial_size_;
  uint8_t* buffer_ = nullptr;
  uint8_t* current_ = nullptr;
  intptr_t capacity_ = 0;

  DISALLOW_COPY_AND_ASSIGN(BaseWriteStream);
};

// A base class for non-streaming write streams. Since these streams are
// not flushed periodically, the internal buffer contains all written data
// and can be retrieved via buffer(). NonStreamingWriteStream also provides
// SetPosition as part of its public API for non-sequential writing.
class NonStreamingWriteStream : public BaseWriteStream {
 public:
  explicit NonStreamingWriteStream(intptr_t initial_size)
      : BaseWriteStream(initial_size) {}

 public:
  uint8_t* buffer() const { return buffer_; }

  // Sets the position of the buffer
  DART_FORCE_INLINE void SetPosition(intptr_t value) {
    BaseWriteStream::SetPosition(value);
  }
};

// A non-streaming write stream that uses realloc for reallocation, and frees
// the buffer when destructed unless ownership is transferred using Steal().
class MallocWriteStream : public NonStreamingWriteStream {
 public:
  explicit MallocWriteStream(intptr_t initial_size)
      : NonStreamingWriteStream(initial_size) {}
  ~MallocWriteStream();

  // Resets the stream and returns the original buffer, which is now considered
  // owned by the caller. Sets [*length] to the length of the returned buffer.
  uint8_t* Steal(intptr_t* length) {
    ASSERT(length != nullptr);
    *length = bytes_written();
    uint8_t* const old_buffer = buffer_;
    // We don't immediately reallocate a new space just in case this steal
    // is the last use of this stream.
    current_ = buffer_ = nullptr;
    capacity_ = 0;
    return old_buffer;
  }

 private:
  virtual void Realloc(intptr_t new_size);

  DISALLOW_COPY_AND_ASSIGN(MallocWriteStream);
};

// A non-streaming write stream that uses a zone for reallocation.
class ZoneWriteStream : public NonStreamingWriteStream {
 public:
  ZoneWriteStream(Zone* zone, intptr_t initial_size)
      : NonStreamingWriteStream(initial_size), zone_(zone) {}

 private:
  virtual void Realloc(intptr_t new_size);

  Zone* const zone_;

  DISALLOW_COPY_AND_ASSIGN(ZoneWriteStream);
};

// A streaming write stream that uses the internal buffer only for non-flushed
// data. Like MallocWriteStream, uses realloc for reallocation, and flushes and
// frees the internal buffer when destructed. Since part or all of the written
// data may be flushed and no longer in the internal buffer, it does not provide
// a way to retrieve the written contents.
class StreamingWriteStream : public BaseWriteStream {
 public:
  explicit StreamingWriteStream(intptr_t initial_capacity,
                                Dart_StreamingWriteCallback callback,
                                void* callback_data)
      : BaseWriteStream(initial_capacity),
        callback_(callback),
        callback_data_(callback_data) {}
  ~StreamingWriteStream();

 private:
  // Flushes any unflushed data to callback_data and resets the internal
  // buffer. Changes current_ and flushed_size_ accordingly.
  virtual void Flush();

  virtual void Realloc(intptr_t new_size);

  virtual intptr_t Position() const {
    return flushed_size_ + BaseWriteStream::Position();
  }

  virtual void SetPosition(intptr_t value) {
    // Make sure we're not trying to set the position to already-flushed data.
    ASSERT(value >= flushed_size_);
    BaseWriteStream::SetPosition(value - flushed_size_);
  }

  const Dart_StreamingWriteCallback callback_;
  void* const callback_data_;
  intptr_t flushed_size_ = 0;

  DISALLOW_COPY_AND_ASSIGN(StreamingWriteStream);
};

}  // namespace dart

#endif  // RUNTIME_VM_DATASTREAM_H_
