1// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/datastream.h"
6
7namespace dart {
8
9StreamingWriteStream::StreamingWriteStream(intptr_t initial_capacity,
10 Dart_StreamingWriteCallback callback,
11 void* callback_data)
12 : flushed_size_(0), callback_(callback), callback_data_(callback_data) {
13 buffer_ = reinterpret_cast<uint8_t*>(malloc(initial_capacity));
14 if (buffer_ == NULL) {
15 OUT_OF_MEMORY();
16 }
17 cursor_ = buffer_;
18 limit_ = buffer_ + initial_capacity;
19}
20
21StreamingWriteStream::~StreamingWriteStream() {
22 Flush();
23 free(buffer_);
24}
25
26void StreamingWriteStream::VPrint(const char* format, va_list args) {
27 // Measure.
28 va_list measure_args;
29 va_copy(measure_args, args);
30 intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
31 va_end(measure_args);
32
33 // Alloc.
34 EnsureAvailable(len + 1);
35
36 // Print.
37 va_list print_args;
38 va_copy(print_args, args);
39 Utils::VSNPrint(reinterpret_cast<char*>(cursor_), len + 1, format,
40 print_args);
41 va_end(print_args);
42 cursor_ += len; // Not len + 1 to swallow the terminating NUL.
43}
44
45void StreamingWriteStream::EnsureAvailableSlowPath(intptr_t needed) {
46 Flush();
47
48 intptr_t available = limit_ - cursor_;
49 if (available >= needed) return;
50
51 intptr_t new_capacity = Utils::RoundUp(needed, 64 * KB);
52 free(buffer_);
53 buffer_ = reinterpret_cast<uint8_t*>(malloc(new_capacity));
54 if (buffer_ == NULL) {
55 OUT_OF_MEMORY();
56 }
57 cursor_ = buffer_;
58 limit_ = buffer_ + new_capacity;
59}
60
61void StreamingWriteStream::Flush() {
62 intptr_t size = cursor_ - buffer_;
63 callback_(callback_data_, buffer_, size);
64 flushed_size_ += size;
65 cursor_ = buffer_;
66}
67
68} // namespace dart
69