[Lldb-commits] [lldb] [lldb-dap] Refactoring IOStream into Transport handler. (PR #130026)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Tue Mar 11 01:30:05 PDT 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());
----------------
labath wrote:
Hmm... I can't say I like the repetitiveness of of the log statements in the Read function, nor the fact that `Read` and `Write` methods handle errors differently (one logs while the other returns them). What exactly was making that complicated?
Another option would be to return an `Expected<optional<Message>>` with a `nullopt` meaning "EOF". It's a bit of a mouthful, but we do have APIs like that, and it doesn't look like this function will be used from that many places.
https://github.com/llvm/llvm-project/pull/130026
More information about the lldb-commits
mailing list