summaryrefslogtreecommitdiff
path: root/absl/status
diff options
context:
space:
mode:
authorGravatar Eric Fiselier <ericwf@google.com>2023-05-16 13:14:32 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-05-16 13:15:35 -0700
commitc8b33b0191a2db8364cacf94b267ea8a3f20ad83 (patch)
tree11b74079844f36e5048b50f3d8d7040a77548f3e /absl/status
parentabe63eb9bd1213c018bf82765ab747334d3b33d8 (diff)
Add non-public API for internal users
PiperOrigin-RevId: 532553508 Change-Id: I813841ff3e5085b64c9b02ca41897bf7f6a8570e
Diffstat (limited to 'absl/status')
-rw-r--r--absl/status/internal/status_internal.h4
-rw-r--r--absl/status/status.cc7
-rw-r--r--absl/status/status.h9
-rw-r--r--absl/status/status_test.cc23
4 files changed, 43 insertions, 0 deletions
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<int32_t> 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<status_internal::Payloads> 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<absl::StatusCode>(kRawCode), "");