[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Mar 6 22:18:39 PST 2025
================
@@ -0,0 +1,146 @@
+//===-- Transport.cpp -----------------------------------------------------===//
+//
+// 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 "Transport.h"
+#include "Protocol.h"
+#include "c++/v1/__system_error/error_code.h"
+#include "lldb/Utility/IOObject.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <system_error>
+#include <utility>
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_dap;
+using namespace lldb_dap::protocol;
+
+static Expected<std::string> ReadFull(IOObjectSP &descriptor, size_t length) {
+ if (!descriptor || !descriptor->IsValid())
+ return createStringError("transport input is closed");
+
+ std::string data;
+ data.resize(length);
+
+ auto status = descriptor->Read(data.data(), length);
+ if (status.Fail())
+ return status.takeError();
+
+ // If we got back zero then we have reached EOF.
+ if (length == 0)
+ return createStringError(Transport::kEOF, "end-of-file");
+
+ return data.substr(0, length);
+}
+
+static Expected<std::string> ReadUntil(IOObjectSP &descriptor,
+ StringRef delimiter) {
+ std::string buffer;
+ buffer.reserve(delimiter.size() + 1);
+ while (!llvm::StringRef(buffer).ends_with(delimiter)) {
+ auto next = ReadFull(descriptor, 1);
+ if (auto Err = next.takeError())
+ return std::move(Err);
+ buffer += *next;
+ }
+ return buffer.substr(0, buffer.size() - delimiter.size());
+}
+
+static Error ReadExpected(IOObjectSP &descriptor, StringRef want) {
+ auto got = ReadFull(descriptor, want.size());
+ if (auto Err = got.takeError())
+ return Err;
+ if (*got != want) {
+ return createStringError("want %s, got %s", want.str().c_str(),
+ got->c_str());
+ }
+ return Error::success();
+}
+
+namespace lldb_dap {
+
+const std::error_code Transport::kEOF =
+ std::error_code(0x1001, std::generic_category());
+
+Transport::Transport(StringRef client_name, IOObjectSP input, IOObjectSP output)
+ : m_client_name(client_name), m_input(std::move(input)),
+ m_output(std::move(output)) {}
+
+Expected<protocol::Message> Transport::Read(std::ofstream *log) {
+ // If we don't find the expected header we have reached EOF.
+ if (auto Err = ReadExpected(m_input, "Content-Length: "))
+ return std::move(Err);
+
+ auto rawLength = ReadUntil(m_input, "\r\n\r\n");
+ if (auto Err = rawLength.takeError())
+ return std::move(Err);
+
+ size_t length;
+ if (!to_integer(*rawLength, length))
+ return createStringError("invalid content length %s", rawLength->c_str());
+
+ auto rawJSON = ReadFull(m_input, length);
+ if (auto Err = rawJSON.takeError())
+ return std::move(Err);
+ if (rawJSON->length() != length)
+ return createStringError(
+ "malformed request, expected %ld bytes, got %ld bytes", length,
----------------
JDevlieghere wrote:
We have a few places in lldb which concatenate errors with `:` so I'm trying to be more consistent in using coons to separate error messages. You used a colon on line 120 so let's do the same here.
```suggestion
"malformed request: expected %ld bytes and got %ld bytes", length,
```
https://github.com/llvm/llvm-project/pull/130026
More information about the lldb-commits
mailing list