| // Copyright (c) 2016, 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 "bin/file.h" | |
| #include "bin/builtin.h" | |
| #include "bin/dartutils.h" | |
| #include "bin/io_buffer.h" | |
| #include "bin/utils.h" | |
| #include "include/bin/dart_io_api.h" | |
| #include "include/dart_api.h" | |
| #include "include/dart_tools_api.h" | |
| namespace dart { | |
| namespace bin { | |
| // Are we capturing output from stdout for the VM service? | |
| static bool capture_stdout = false; | |
| // Are we capturing output from stderr for the VM service? | |
| static bool capture_stderr = false; | |
| void SetCaptureStdout(bool value) { | |
| capture_stdout = value; | |
| } | |
| void SetCaptureStderr(bool value) { | |
| capture_stderr = value; | |
| } | |
| bool ShouldCaptureStdout() { | |
| return capture_stdout; | |
| } | |
| bool ShouldCaptureStderr() { | |
| return capture_stderr; | |
| } | |
| bool File::ReadFully(void* buffer, int64_t num_bytes) { | |
| int64_t remaining = num_bytes; | |
| char* current_buffer = reinterpret_cast<char*>(buffer); | |
| while (remaining > 0) { | |
| int64_t bytes_read = Read(current_buffer, remaining); | |
| if (bytes_read <= 0) { | |
| return false; | |
| } | |
| remaining -= bytes_read; // Reduce the number of remaining bytes. | |
| current_buffer += bytes_read; // Move the buffer forward. | |
| } | |
| return true; | |
| } | |
| bool File::WriteFully(const void* buffer, int64_t num_bytes) { | |
| int64_t remaining = num_bytes; | |
| const char* current_buffer = reinterpret_cast<const char*>(buffer); | |
| while (remaining > 0) { | |
| // On Windows, narrowing conversion from int64_t to DWORD will cause | |
| // unexpected error. | |
| // On MacOS, a single write() with more than kMaxInt32 will have | |
| // "invalid argument" error. | |
| // Therefore, limit the size for single write. | |
| int64_t byte_to_write = remaining > kMaxInt32 ? kMaxInt32 : remaining; | |
| int64_t bytes_written = Write(current_buffer, byte_to_write); | |
| if (bytes_written < 0) { | |
| return false; | |
| } | |
| remaining -= bytes_written; // Reduce the number of remaining bytes. | |
| current_buffer += bytes_written; // Move the buffer forward. | |
| } | |
| if (capture_stdout || capture_stderr) { | |
| intptr_t fd = GetFD(); | |
| const char* result = nullptr; | |
| if ((fd == STDOUT_FILENO) && capture_stdout) { | |
| result = Dart_ServiceSendDataEvent( | |
| "Stdout", "WriteEvent", reinterpret_cast<const uint8_t*>(buffer), | |
| num_bytes); | |
| } else if ((fd == STDERR_FILENO) && capture_stderr) { | |
| result = Dart_ServiceSendDataEvent( | |
| "Stderr", "WriteEvent", reinterpret_cast<const uint8_t*>(buffer), | |
| num_bytes); | |
| } | |
| ASSERT(result == nullptr); | |
| } | |
| return true; | |
| } | |
| File::FileOpenMode File::DartModeToFileMode(DartFileOpenMode mode) { | |
| ASSERT((mode == File::kDartRead) || (mode == File::kDartWrite) || | |
| (mode == File::kDartAppend) || (mode == File::kDartWriteOnly) || | |
| (mode == File::kDartWriteOnlyAppend)); | |
| if (mode == File::kDartWrite) { | |
| return File::kWriteTruncate; | |
| } | |
| if (mode == File::kDartAppend) { | |
| return File::kWrite; | |
| } | |
| if (mode == File::kDartWriteOnly) { | |
| return File::kWriteOnlyTruncate; | |
| } | |
| if (mode == File::kDartWriteOnlyAppend) { | |
| return File::kWriteOnly; | |
| } | |
| return File::kRead; | |
| } | |
| } // namespace bin | |
| } // namespace dart |