1// Copyright (c) 2016, 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 "bin/file.h"
6
7#include "bin/builtin.h"
8#include "bin/dartutils.h"
9#include "bin/io_buffer.h"
10#include "bin/utils.h"
11
12#include "include/bin/dart_io_api.h"
13#include "include/dart_api.h"
14#include "include/dart_tools_api.h"
15
16namespace dart {
17namespace bin {
18
19// Are we capturing output from stdout for the VM service?
20static bool capture_stdout = false;
21
22// Are we capturing output from stderr for the VM service?
23static bool capture_stderr = false;
24
25void SetCaptureStdout(bool value) {
26 capture_stdout = value;
27}
28
29void SetCaptureStderr(bool value) {
30 capture_stderr = value;
31}
32
33bool ShouldCaptureStdout() {
34 return capture_stdout;
35}
36
37bool ShouldCaptureStderr() {
38 return capture_stderr;
39}
40
41bool File::ReadFully(void* buffer, int64_t num_bytes) {
42 int64_t remaining = num_bytes;
43 char* current_buffer = reinterpret_cast<char*>(buffer);
44 while (remaining > 0) {
45 int64_t bytes_read = Read(current_buffer, remaining);
46 if (bytes_read <= 0) {
47 return false;
48 }
49 remaining -= bytes_read; // Reduce the number of remaining bytes.
50 current_buffer += bytes_read; // Move the buffer forward.
51 }
52 return true;
53}
54
55bool File::WriteFully(const void* buffer, int64_t num_bytes) {
56 int64_t remaining = num_bytes;
57 const char* current_buffer = reinterpret_cast<const char*>(buffer);
58 while (remaining > 0) {
59 // On Windows, narrowing conversion from int64_t to DWORD will cause
60 // unexpected error.
61 // On MacOS, a single write() with more than kMaxInt32 will have
62 // "invalid argument" error.
63 // Therefore, limit the size for single write.
64 int64_t byte_to_write = remaining > kMaxInt32 ? kMaxInt32 : remaining;
65 int64_t bytes_written = Write(current_buffer, byte_to_write);
66 if (bytes_written < 0) {
67 return false;
68 }
69 remaining -= bytes_written; // Reduce the number of remaining bytes.
70 current_buffer += bytes_written; // Move the buffer forward.
71 }
72 if (capture_stdout || capture_stderr) {
73 intptr_t fd = GetFD();
74 if ((fd == STDOUT_FILENO) && capture_stdout) {
75 Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
76 reinterpret_cast<const uint8_t*>(buffer),
77 num_bytes);
78 } else if ((fd == STDERR_FILENO) && capture_stderr) {
79 Dart_ServiceSendDataEvent("Stderr", "WriteEvent",
80 reinterpret_cast<const uint8_t*>(buffer),
81 num_bytes);
82 }
83 }
84 return true;
85}
86
87File::FileOpenMode File::DartModeToFileMode(DartFileOpenMode mode) {
88 ASSERT((mode == File::kDartRead) || (mode == File::kDartWrite) ||
89 (mode == File::kDartAppend) || (mode == File::kDartWriteOnly) ||
90 (mode == File::kDartWriteOnlyAppend));
91 if (mode == File::kDartWrite) {
92 return File::kWriteTruncate;
93 }
94 if (mode == File::kDartAppend) {
95 return File::kWrite;
96 }
97 if (mode == File::kDartWriteOnly) {
98 return File::kWriteOnlyTruncate;
99 }
100 if (mode == File::kDartWriteOnlyAppend) {
101 return File::kWriteOnly;
102 }
103 return File::kRead;
104}
105
106} // namespace bin
107} // namespace dart
108