From c8b33b0191a2db8364cacf94b267ea8a3f20ad83 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 16 May 2023 13:14:32 -0700 Subject: Add non-public API for internal users PiperOrigin-RevId: 532553508 Change-Id: I813841ff3e5085b64c9b02ca41897bf7f6a8570e --- absl/status/internal/status_internal.h | 4 ++++ absl/status/status.cc | 7 +++++++ absl/status/status.h | 9 +++++++++ absl/status/status_test.cc | 23 +++++++++++++++++++++++ 4 files changed, 43 insertions(+) (limited to 'absl/status') diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h index 873eb5c2..6198e726 100644 --- a/absl/status/internal/status_internal.h +++ b/absl/status/internal/status_internal.h @@ -66,6 +66,10 @@ struct StatusRep { std::atomic ref; absl::StatusCode code; + + // As an internal implementation detail, we guarantee that if status.message() + // is non-empty, then the resulting string_view is null terminated. + // This is required to implement 'StatusMessageAsCStr(...)' std::string message; std::unique_ptr payloads; }; diff --git a/absl/status/status.cc b/absl/status/status.cc index d011075a..26e68294 100644 --- a/absl/status/status.cc +++ b/absl/status/status.cc @@ -616,5 +616,12 @@ std::string* MakeCheckFailString(const absl::Status* status, } // namespace status_internal +const char* StatusMessageAsCStr(const Status& status) { + // As an internal implementation detail, we guarantee that if status.message() + // is non-empty, then the resulting string_view is null terminated. + auto sv_message = status.message(); + return sv_message.empty() ? "" : sv_message.data(); +} + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/status/status.h b/absl/status/status.h index c6c1cd41..595064c0 100644 --- a/absl/status/status.h +++ b/absl/status/status.h @@ -886,6 +886,15 @@ inline Status OkStatus() { return Status(); } // message-less kCancelled errors are common in the infrastructure. inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); } +// Retrieves a message's status as a null terminated C string. The lifetime of +// this string is tied to the lifetime of the status object itself. +// +// If the status's message is empty, the empty string is returned. +// +// StatusMessageAsCStr exists for C support. Use `status.message()` in C++. +const char* StatusMessageAsCStr( + const Status& status ABSL_ATTRIBUTE_LIFETIME_BOUND); + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc index 74a64ace..898a9cb2 100644 --- a/absl/status/status_test.cc +++ b/absl/status/status_test.cc @@ -132,6 +132,29 @@ TEST(Status, ConstructorWithCodeMessage) { } } +TEST(Status, StatusMessageCStringTest) { + { + absl::Status status = absl::OkStatus(); + EXPECT_EQ(status.message(), ""); + EXPECT_STREQ(absl::StatusMessageAsCStr(status), ""); + EXPECT_EQ(status.message(), absl::StatusMessageAsCStr(status)); + EXPECT_NE(absl::StatusMessageAsCStr(status), nullptr); + } + { + absl::Status status; + EXPECT_EQ(status.message(), ""); + EXPECT_NE(absl::StatusMessageAsCStr(status), nullptr); + EXPECT_STREQ(absl::StatusMessageAsCStr(status), ""); + } + { + absl::Status status(absl::StatusCode::kInternal, "message"); + EXPECT_FALSE(status.ok()); + EXPECT_EQ(absl::StatusCode::kInternal, status.code()); + EXPECT_EQ("message", status.message()); + EXPECT_STREQ("message", absl::StatusMessageAsCStr(status)); + } +} + TEST(Status, ConstructOutOfRangeCode) { const int kRawCode = 9999; absl::Status status(static_cast(kRawCode), ""); -- cgit v1.2.3