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