summaryrefslogtreecommitdiffstats
path: root/lldb/tools/lldb-vscode/IOStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/lldb-vscode/IOStream.cpp')
-rw-r--r--lldb/tools/lldb-vscode/IOStream.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/lldb/tools/lldb-vscode/IOStream.cpp b/lldb/tools/lldb-vscode/IOStream.cpp
new file mode 100644
index 00000000000..1b578bfa6d4
--- /dev/null
+++ b/lldb/tools/lldb-vscode/IOStream.cpp
@@ -0,0 +1,153 @@
+//===-- IOStream.cpp --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "IOStream.h"
+
+#if defined(_WIN32)
+#include <io.h>
+#else
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#endif
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+using namespace lldb_vscode;
+
+StreamDescriptor::StreamDescriptor() {}
+
+StreamDescriptor::StreamDescriptor(StreamDescriptor &&other) {
+ *this = std::move(other);
+}
+
+StreamDescriptor::~StreamDescriptor() {
+ if (!m_close)
+ return;
+
+ if (m_is_socket)
+#if defined(_WIN32)
+ ::closesocket(m_socket);
+#else
+ ::close(m_socket);
+#endif
+ else
+ ::close(m_fd);
+}
+
+StreamDescriptor &StreamDescriptor::operator=(StreamDescriptor &&other) {
+ m_close = other.m_close;
+ other.m_close = false;
+ m_is_socket = other.m_is_socket;
+ if (m_is_socket)
+ m_socket = other.m_socket;
+ else
+ m_fd = other.m_fd;
+ return *this;
+}
+
+StreamDescriptor StreamDescriptor::from_socket(SOCKET s, bool close) {
+ StreamDescriptor sd;
+ sd.m_is_socket = true;
+ sd.m_socket = s;
+ sd.m_close = close;
+ return sd;
+}
+
+StreamDescriptor StreamDescriptor::from_file(int fd, bool close) {
+ StreamDescriptor sd;
+ sd.m_is_socket = false;
+ sd.m_fd = fd;
+ sd.m_close = close;
+ return sd;
+}
+
+bool OutputStream::write_full(llvm::StringRef str) {
+ while (!str.empty()) {
+ int bytes_written = 0;
+ if (descriptor.m_is_socket)
+ bytes_written = ::send(descriptor.m_socket, str.data(), str.size(), 0);
+ else
+ bytes_written = ::write(descriptor.m_fd, str.data(), str.size());
+
+ if (bytes_written < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return false;
+ }
+ str = str.drop_front(bytes_written);
+ }
+
+ return true;
+}
+
+bool InputStream::read_full(std::ofstream *log, size_t length,
+ std::string &text) {
+ std::string data;
+ data.resize(length);
+
+ char *ptr = &data[0];
+ while (length != 0) {
+ int bytes_read = 0;
+ if (descriptor.m_is_socket)
+ bytes_read = ::recv(descriptor.m_socket, ptr, length, 0);
+ else
+ bytes_read = ::read(descriptor.m_fd, ptr, length);
+
+ if (bytes_read < 0) {
+ int reason = 0;
+#if defined(_WIN32)
+ if (descriptor.m_is_socket)
+ reason = WSAGetLastError();
+ else
+ reason = errno;
+#else
+ reason = errno;
+ if (reason == EINTR || reason == EAGAIN)
+ continue;
+#endif
+
+ if (log)
+ *log << "Error " << reason << " reading from input file.\n";
+ return false;
+ }
+
+ assert(bytes_read <= length);
+ ptr += bytes_read;
+ length -= bytes_read;
+ }
+ text += data;
+ return true;
+}
+
+bool InputStream::read_line(std::ofstream *log, std::string &line) {
+ line.clear();
+ while (true) {
+ if (!read_full(log, 1, line))
+ return false;
+
+ if (llvm::StringRef(line).endswith("\r\n"))
+ break;
+ }
+ line.erase(line.size() - 2);
+ return true;
+}
+
+bool InputStream::read_expected(std::ofstream *log, llvm::StringRef expected) {
+ std::string result;
+ if (!read_full(log, expected.size(), result))
+ return false;
+ if (expected != result) {
+ if (log)
+ *log << "Warning: Expected '" << expected.str() << "', got '" << result
+ << "\n";
+ }
+ return true;
+}
OpenPOWER on IntegriCloud