summaryrefslogtreecommitdiff
path: root/absl/strings/cord.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/cord.cc')
-rw-r--r--absl/strings/cord.cc95
1 files changed, 57 insertions, 38 deletions
diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc
index 08a165e1..f67326fd 100644
--- a/absl/strings/cord.cc
+++ b/absl/strings/cord.cc
@@ -37,6 +37,7 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
+#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
#include "absl/crc/crc32c.h"
#include "absl/crc/internal/crc_cord_state.h"
@@ -74,18 +75,21 @@ using ::absl::cord_internal::kMinFlatLength;
using ::absl::cord_internal::kInlinedVectorSize;
using ::absl::cord_internal::kMaxBytesToCopy;
-static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
- int indent = 0);
-static bool VerifyNode(CordRep* root, CordRep* start_node);
+static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data,
+ absl::Nonnull<std::ostream*> os, int indent = 0);
+static bool VerifyNode(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> start_node);
-static inline CordRep* VerifyTree(CordRep* node) {
+static inline absl::Nullable<CordRep*> VerifyTree(
+ absl::Nullable<CordRep*> node) {
assert(node == nullptr || VerifyNode(node, node));
static_cast<void>(&VerifyNode);
return node;
}
-static CordRepFlat* CreateFlat(const char* data, size_t length,
- size_t alloc_hint) {
+static absl::Nonnull<CordRepFlat*> CreateFlat(absl::Nonnull<const char*> data,
+ size_t length,
+ size_t alloc_hint) {
CordRepFlat* flat = CordRepFlat::New(length + alloc_hint);
flat->length = length;
memcpy(flat->Data(), data, length);
@@ -94,7 +98,8 @@ static CordRepFlat* CreateFlat(const char* data, size_t length,
// Creates a new flat or Btree out of the specified array.
// The returned node has a refcount of 1.
-static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
+static absl::Nonnull<CordRep*> NewBtree(absl::Nonnull<const char*> data,
+ size_t length, size_t alloc_hint) {
if (length <= kMaxFlatLength) {
return CreateFlat(data, length, alloc_hint);
}
@@ -107,14 +112,16 @@ static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
// Create a new tree out of the specified array.
// The returned node has a refcount of 1.
-static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) {
+static absl::Nullable<CordRep*> NewTree(absl::Nullable<const char*> data,
+ size_t length, size_t alloc_hint) {
if (length == 0) return nullptr;
return NewBtree(data, length, alloc_hint);
}
namespace cord_internal {
-void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
+void InitializeCordRepExternal(absl::string_view data,
+ absl::Nonnull<CordRepExternal*> rep) {
assert(!data.empty());
rep->length = data.size();
rep->tag = EXTERNAL;
@@ -128,7 +135,7 @@ void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
// and not wasteful, we move the string into an external cord rep, preserving
// the already allocated string contents.
// Requires the provided string length to be larger than `kMaxInline`.
-static CordRep* CordRepFromString(std::string&& src) {
+static absl::Nonnull<CordRep*> CordRepFromString(std::string&& src) {
assert(src.length() > cord_internal::kMaxInline);
if (
// String is short: copy data to avoid external block overhead.
@@ -160,12 +167,13 @@ static CordRep* CordRepFromString(std::string&& src) {
constexpr unsigned char Cord::InlineRep::kMaxInline;
#endif
-inline void Cord::InlineRep::set_data(const char* data, size_t n) {
+inline void Cord::InlineRep::set_data(absl::Nonnull<const char*> data,
+ size_t n) {
static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15");
data_.set_inline_data(data, n);
}
-inline char* Cord::InlineRep::set_data(size_t n) {
+inline absl::Nonnull<char*> Cord::InlineRep::set_data(size_t n) {
assert(n <= kMaxInline);
ResetToEmpty();
set_inline_size(n);
@@ -189,13 +197,13 @@ inline void Cord::InlineRep::remove_prefix(size_t n) {
// Returns `rep` converted into a CordRepBtree.
// Directly returns `rep` if `rep` is already a CordRepBtree.
-static CordRepBtree* ForceBtree(CordRep* rep) {
+static absl::Nonnull<CordRepBtree*> ForceBtree(CordRep* rep) {
return rep->IsBtree()
? rep->btree()
: CordRepBtree::Create(cord_internal::RemoveCrcNode(rep));
}
-void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
+void Cord::InlineRep::AppendTreeToInlined(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(!is_tree());
if (!data_.is_empty()) {
@@ -205,14 +213,16 @@ void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
EmplaceTree(tree, method);
}
-void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::AppendTreeToTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(is_tree());
const CordzUpdateScope scope(data_.cordz_info(), method);
tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree);
SetTree(tree, scope);
}
-void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::AppendTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(tree != nullptr);
assert(tree->length != 0);
assert(!tree->IsCrc());
@@ -223,7 +233,7 @@ void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
}
}
-void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
+void Cord::InlineRep::PrependTreeToInlined(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(!is_tree());
if (!data_.is_empty()) {
@@ -233,7 +243,7 @@ void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
EmplaceTree(tree, method);
}
-void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
+void Cord::InlineRep::PrependTreeToTree(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(is_tree());
const CordzUpdateScope scope(data_.cordz_info(), method);
@@ -241,7 +251,8 @@ void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
SetTree(tree, scope);
}
-void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::PrependTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(tree != nullptr);
assert(tree->length != 0);
assert(!tree->IsCrc());
@@ -256,8 +267,9 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
// suitable leaf is found, the function will update the length field for all
// nodes to account for the size increase. The append region address will be
// written to region and the actual size increase will be written to size.
-static inline bool PrepareAppendRegion(CordRep* root, char** region,
- size_t* size, size_t max_length) {
+static inline bool PrepareAppendRegion(
+ absl::Nonnull<CordRep*> root, absl::Nonnull<absl::Nullable<char*>*> region,
+ absl::Nonnull<size_t*> size, size_t max_length) {
if (root->IsBtree() && root->refcount.IsOne()) {
Span<char> span = root->btree()->GetAppendBuffer(max_length);
if (!span.empty()) {
@@ -460,11 +472,11 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
CommitTree(root, rep, scope, method);
}
-inline CordRep* Cord::TakeRep() const& {
+inline absl::Nonnull<CordRep*> Cord::TakeRep() const& {
return CordRep::Ref(contents_.tree());
}
-inline CordRep* Cord::TakeRep() && {
+inline absl::Nonnull<CordRep*> Cord::TakeRep() && {
CordRep* rep = contents_.tree();
contents_.clear();
return rep;
@@ -522,7 +534,7 @@ inline void Cord::AppendImpl(C&& src) {
contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord);
}
-static CordRep::ExtractResult ExtractAppendBuffer(CordRep* rep,
+static CordRep::ExtractResult ExtractAppendBuffer(absl::Nonnull<CordRep*> rep,
size_t min_capacity) {
switch (rep->tag) {
case cord_internal::BTREE:
@@ -769,8 +781,9 @@ int ClampResult(int memcmp_res) {
return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0);
}
-int CompareChunks(absl::string_view* lhs, absl::string_view* rhs,
- size_t* size_to_compare) {
+int CompareChunks(absl::Nonnull<absl::string_view*> lhs,
+ absl::Nonnull<absl::string_view*> rhs,
+ absl::Nonnull<size_t*> size_to_compare) {
size_t compared_size = std::min(lhs->size(), rhs->size());
assert(*size_to_compare >= compared_size);
*size_to_compare -= compared_size;
@@ -868,7 +881,8 @@ void Cord::SetExpectedChecksum(uint32_t crc) {
SetCrcCordState(std::move(state));
}
-const crc_internal::CrcCordState* Cord::MaybeGetCrcCordState() const {
+absl::Nullable<const crc_internal::CrcCordState*> Cord::MaybeGetCrcCordState()
+ const {
if (!contents_.is_tree() || !contents_.tree()->IsCrc()) {
return nullptr;
}
@@ -885,7 +899,8 @@ absl::optional<uint32_t> Cord::ExpectedChecksum() const {
inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
size_t size_to_compare) const {
- auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
+ auto advance = [](absl::Nonnull<Cord::ChunkIterator*> it,
+ absl::Nonnull<absl::string_view*> chunk) {
if (!chunk->empty()) return true;
++*it;
if (it->bytes_remaining_ == 0) return false;
@@ -915,7 +930,8 @@ inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size,
size_t size_to_compare) const {
- auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
+ auto advance = [](absl::Nonnull<Cord::ChunkIterator*> it,
+ absl::Nonnull<absl::string_view*> chunk) {
if (!chunk->empty()) return true;
++*it;
if (it->bytes_remaining_ == 0) return false;
@@ -1037,7 +1053,7 @@ Cord::operator std::string() const {
return s;
}
-void CopyCordToString(const Cord& src, std::string* dst) {
+void CopyCordToString(const Cord& src, absl::Nonnull<std::string*> dst) {
if (!src.contents_.is_tree()) {
src.contents_.CopyTo(dst);
} else {
@@ -1046,7 +1062,7 @@ void CopyCordToString(const Cord& src, std::string* dst) {
}
}
-void Cord::CopyToArraySlowPath(char* dst) const {
+void Cord::CopyToArraySlowPath(absl::Nonnull<char*> dst) const {
assert(contents_.is_tree());
absl::string_view fragment;
if (GetFlatAux(contents_.tree(), &fragment)) {
@@ -1372,7 +1388,8 @@ absl::string_view Cord::FlattenSlowPath() {
return absl::string_view(new_buffer, total_size);
}
-/* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) {
+/* static */ bool Cord::GetFlatAux(absl::Nonnull<CordRep*> rep,
+ absl::Nonnull<absl::string_view*> fragment) {
assert(rep != nullptr);
if (rep->length == 0) {
*fragment = absl::string_view();
@@ -1406,7 +1423,7 @@ absl::string_view Cord::FlattenSlowPath() {
}
/* static */ void Cord::ForEachChunkAux(
- absl::cord_internal::CordRep* rep,
+ absl::Nonnull<absl::cord_internal::CordRep*> rep,
absl::FunctionRef<void(absl::string_view)> callback) {
assert(rep != nullptr);
if (rep->length == 0) return;
@@ -1431,8 +1448,8 @@ absl::string_view Cord::FlattenSlowPath() {
}
}
-static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
- int indent) {
+static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data,
+ absl::Nonnull<std::ostream*> os, int indent) {
const int kIndentStep = 1;
absl::InlinedVector<CordRep*, kInlinedVectorSize> stack;
absl::InlinedVector<int, kInlinedVectorSize> indents;
@@ -1482,15 +1499,17 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
ABSL_INTERNAL_CHECK(indents.empty(), "");
}
-static std::string ReportError(CordRep* root, CordRep* node) {
+static std::string ReportError(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> node) {
std::ostringstream buf;
buf << "Error at node " << node << " in:";
DumpNode(root, true, &buf);
return buf.str();
}
-static bool VerifyNode(CordRep* root, CordRep* start_node) {
- absl::InlinedVector<CordRep*, 2> worklist;
+static bool VerifyNode(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> start_node) {
+ absl::InlinedVector<absl::Nonnull<CordRep*>, 2> worklist;
worklist.push_back(start_node);
do {
CordRep* node = worklist.back();