blob: de779371a7cf848da1afcdcfd9208f0abfc7a65d [file] [log] [blame]
// Copyright (c) 2018, 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.
#include "vm/datastream.h"
namespace dart {
StreamingWriteStream::StreamingWriteStream(intptr_t initial_capacity,
Dart_StreamingWriteCallback callback,
void* callback_data)
: flushed_size_(0), callback_(callback), callback_data_(callback_data) {
buffer_ = reinterpret_cast<uint8_t*>(malloc(initial_capacity));
if (buffer_ == NULL) {
OUT_OF_MEMORY();
}
cursor_ = buffer_;
limit_ = buffer_ + initial_capacity;
}
StreamingWriteStream::~StreamingWriteStream() {
Flush();
free(buffer_);
}
void StreamingWriteStream::VPrint(const char* format, va_list args) {
// Measure.
va_list measure_args;
va_copy(measure_args, args);
intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
va_end(measure_args);
// Alloc.
EnsureAvailable(len + 1);
// Print.
va_list print_args;
va_copy(print_args, args);
Utils::VSNPrint(reinterpret_cast<char*>(cursor_), len + 1, format,
print_args);
va_end(print_args);
cursor_ += len; // Not len + 1 to swallow the terminating NUL.
}
void StreamingWriteStream::EnsureAvailableSlowPath(intptr_t needed) {
Flush();
intptr_t available = limit_ - cursor_;
if (available >= needed) return;
intptr_t new_capacity = Utils::RoundUp(needed, 64 * KB);
free(buffer_);
buffer_ = reinterpret_cast<uint8_t*>(malloc(new_capacity));
if (buffer_ == NULL) {
OUT_OF_MEMORY();
}
cursor_ = buffer_;
limit_ = buffer_ + new_capacity;
}
void StreamingWriteStream::Flush() {
intptr_t size = cursor_ - buffer_;
callback_(callback_data_, buffer_, size);
flushed_size_ += size;
cursor_ = buffer_;
}
} // namespace dart