| Index: vm/datastream.h
|
| ===================================================================
|
| --- vm/datastream.h (revision 0)
|
| +++ vm/datastream.h (revision 0)
|
| @@ -0,0 +1,203 @@
|
| +// 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 VM_DATASTREAM_H_
|
| +#define VM_DATASTREAM_H_
|
| +
|
| +#include "platform/assert.h"
|
| +#include "vm/allocation.h"
|
| +#include "vm/globals.h"
|
| +
|
| +namespace dart {
|
| +
|
| +static const int8_t kDataBitsPerByte = 7;
|
| +static const int8_t kByteMask = (1 << kDataBitsPerByte) - 1;
|
| +static const int8_t kMaxUnsignedDataPerByte = kByteMask;
|
| +static const int8_t kMinDataPerByte = -(1 << (kDataBitsPerByte - 1));
|
| +static const int8_t kMaxDataPerByte = (~kMinDataPerByte & kByteMask);
|
| +static const uint8_t kEndByteMarker = (255 - kMaxDataPerByte);
|
| +
|
| +typedef uint8_t* (*ReAlloc)(uint8_t* ptr, intptr_t old_size, intptr_t new_size);
|
| +
|
| +// 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) {}
|
| +
|
| + 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->Read<int16_t>());
|
| + }
|
| + };
|
| +
|
| + template<typename T>
|
| + class Raw<4, T> {
|
| + public:
|
| + static T Read(ReadStream* st) {
|
| + return bit_cast<T>(st->Read<int32_t>());
|
| + }
|
| + };
|
| +
|
| + template<typename T>
|
| + class Raw<8, T> {
|
| + public:
|
| + static T Read(ReadStream* st) {
|
| + return bit_cast<T>(st->Read<int64_t>());
|
| + }
|
| + };
|
| +
|
| + void ReadBytes(uint8_t* addr, intptr_t len) {
|
| + ASSERT((current_ + len) < end_);
|
| + memmove(addr, current_, len);
|
| + current_ += len;
|
| + }
|
| +
|
| + private:
|
| + template<typename T>
|
| + T Read() {
|
| + uint8_t b = ReadByte();
|
| + if (b > kMaxUnsignedDataPerByte) {
|
| + return static_cast<T>(b) - kEndByteMarker;
|
| + }
|
| + T r = 0;
|
| + uint8_t s = 0;
|
| + do {
|
| + r |= static_cast<T>(b) << s;
|
| + s += kDataBitsPerByte;
|
| + b = ReadByte();
|
| + } while (b <= kMaxUnsignedDataPerByte);
|
| + return r | ((static_cast<T>(b) - kEndByteMarker) << s);
|
| + }
|
| +
|
| + uint8_t ReadByte() {
|
| + ASSERT(current_ < end_);
|
| + return *current_++;
|
| + }
|
| +
|
| + private:
|
| + const uint8_t* buffer_;
|
| + const uint8_t* current_;
|
| + const uint8_t* end_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ReadStream);
|
| +};
|
| +
|
| +
|
| +// Stream for writing various types into a buffer.
|
| +class WriteStream : public ValueObject {
|
| + public:
|
| + static const int kBufferIncrementSize = 64 * KB;
|
| +
|
| + WriteStream(uint8_t** buffer, ReAlloc alloc) :
|
| + buffer_(buffer),
|
| + end_(NULL),
|
| + current_(NULL),
|
| + current_size_(0),
|
| + alloc_(alloc) {
|
| + ASSERT(buffer != NULL);
|
| + ASSERT(alloc != NULL);
|
| + *buffer_ = reinterpret_cast<uint8_t*>(alloc_(NULL,
|
| + 0,
|
| + kBufferIncrementSize));
|
| + ASSERT(*buffer_ != NULL);
|
| + current_ = *buffer_;
|
| + current_size_ = kBufferIncrementSize;
|
| + end_ = *buffer_ + kBufferIncrementSize;
|
| + }
|
| +
|
| + uint8_t* buffer() const { return *buffer_; }
|
| + int bytes_written() const { return current_ - *buffer_; }
|
| +
|
| + void set_current(uint8_t* value) { current_ = value; }
|
| +
|
| + template<int N, typename T>
|
| + class Raw { };
|
| +
|
| + template<typename T>
|
| + class Raw<1, T> {
|
| + public:
|
| + static void Write(WriteStream* st, T value) {
|
| + st->WriteByte(bit_cast<int8_t>(value));
|
| + }
|
| + };
|
| +
|
| + template<typename T>
|
| + class Raw<2, T> {
|
| + public:
|
| + static void Write(WriteStream* st, T value) {
|
| + st->Write<int16_t>(bit_cast<int16_t>(value));
|
| + }
|
| + };
|
| +
|
| + template<typename T>
|
| + class Raw<4, T> {
|
| + public:
|
| + static void Write(WriteStream* st, T value) {
|
| + st->Write<int32_t>(bit_cast<int32_t>(value));
|
| + }
|
| + };
|
| +
|
| + template<typename T>
|
| + class Raw<8, T> {
|
| + public:
|
| + static void Write(WriteStream* st, T value) {
|
| + st->Write<int64_t>(bit_cast<int64_t>(value));
|
| + }
|
| + };
|
| +
|
| + private:
|
| + 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));
|
| + }
|
| +
|
| + void WriteByte(uint8_t value) {
|
| + if (current_ >= end_) {
|
| + intptr_t new_size = (current_size_ + kBufferIncrementSize);
|
| + *buffer_ = reinterpret_cast<uint8_t*>(alloc_(*buffer_,
|
| + current_size_,
|
| + new_size));
|
| + ASSERT(*buffer_ != NULL);
|
| + current_ = *buffer_ + current_size_;
|
| + current_size_ = new_size;
|
| + end_ = *buffer_ + new_size;
|
| + }
|
| + ASSERT(current_ < end_);
|
| + *current_++ = value;
|
| + }
|
| +
|
| + private:
|
| + uint8_t** const buffer_;
|
| + uint8_t* end_;
|
| + uint8_t* current_;
|
| + intptr_t current_size_;
|
| + ReAlloc alloc_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WriteStream);
|
| +};
|
| +
|
| +} // namespace dart
|
| +
|
| +#endif // VM_DATASTREAM_H_
|
|
|