C/C++ API Reference
Loading...
Searching...
No Matches
util.h
Go to the documentation of this file.
1// Copyright 2021 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
19
20#include <cctype>
21#include <cstddef>
22#include <string_view>
23
24#include "pw_assert/assert.h"
25#include "pw_polyfill/language_feature_macros.h"
26#include "pw_result/result.h"
27#include "pw_span/span.h"
28#include "pw_status/status.h"
29#include "pw_status/status_with_size.h"
30#include "pw_string/internal/length.h"
31#include "pw_string/string.h"
32
33namespace pw {
34namespace string {
35namespace internal {
36
37PW_CONSTEXPR_CPP20 inline StatusWithSize CopyToSpan(std::string_view source,
38 span<char> dest) {
39 if (dest.empty()) {
40 return StatusWithSize::ResourceExhausted();
41 }
42
43 const size_t copied = source.copy(dest.data(), dest.size() - 1);
44 dest[copied] = '\0';
45
46 return StatusWithSize(
47 copied == source.size() ? OkStatus() : Status::ResourceExhausted(),
48 copied);
49}
50
51} // namespace internal
52
54
60constexpr std::string_view ClampedCString(span<const char> str) {
61 return std::string_view(str.data(),
62 internal::ClampedLength(str.data(), str.size()));
63}
64
65constexpr std::string_view ClampedCString(const char* str, size_t max_len) {
66 return ClampedCString(span<const char>(str, max_len));
67}
68
69// clang-format off
80// clang-format on
82 PW_DASSERT(str.data() != nullptr);
83
84 const size_t length = internal::ClampedLength(str.data(), str.size());
85 if (length == str.size()) {
86 return Status::OutOfRange();
87 }
88
89 return length;
90}
91
92constexpr Result<size_t> NullTerminatedLength(const char* str, size_t max_len) {
93 return NullTerminatedLength(span<const char>(str, max_len));
94}
95
109template <typename Span>
110PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(std::string_view source,
111 Span&& dest) {
112 static_assert(
113 !std::is_base_of_v<InlineString<>, std::decay_t<Span>>,
114 "Do not use pw::string::Copy() with pw::InlineString<>. Instead, use "
115 "pw::InlineString<>'s assignment operator or assign() function, or "
116 "pw::string::Append().");
117 return internal::CopyToSpan(source, std::forward<Span>(dest));
118}
119
120template <typename Span>
121PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(const char* source, Span&& dest) {
122 PW_DASSERT(source != nullptr);
123 return Copy(ClampedCString(source, std::size(dest)),
124 std::forward<Span>(dest));
125}
126
127PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(const char* source,
128 char* dest,
129 size_t num) {
130 return Copy(source, span<char>(dest, num));
131}
132
142inline Status Assign(InlineString<>& string, std::string_view view) {
143 const size_t chars_copied =
144 std::min(view.size(), static_cast<size_t>(string.capacity()));
145 string.assign(view, 0, static_cast<string_impl::size_type>(chars_copied));
146 return chars_copied == view.size() ? OkStatus() : Status::ResourceExhausted();
147}
148
149inline Status Assign(InlineString<>& string, const char* c_string) {
150 PW_DASSERT(c_string != nullptr);
151 // Clamp to capacity + 1 so strings larger than the capacity yield an error.
152 return Assign(string, ClampedCString(c_string, string.capacity() + 1));
153}
154
163inline Status Append(InlineString<>& string, std::string_view view) {
164 const size_t chars_copied = std::min(
165 view.size(), static_cast<size_t>(string.capacity() - string.size()));
166 string.append(view, 0, static_cast<string_impl::size_type>(chars_copied));
167 return chars_copied == view.size() ? OkStatus() : Status::ResourceExhausted();
168}
169
170inline Status Append(InlineString<>& string, const char* c_string) {
171 PW_DASSERT(c_string != nullptr);
172 // Clamp to capacity + 1 so strings larger than the capacity yield an error.
173 return Append(string, ClampedCString(c_string, string.capacity() + 1));
174}
175
181PW_CONSTEXPR_CPP20 inline StatusWithSize PrintableCopy(std::string_view source,
182 span<char> dest) {
183 StatusWithSize copy_result = Copy(source, dest);
184 for (size_t i = 0; i < copy_result.size(); i++) {
185 dest[i] = std::isprint(dest[i]) ? dest[i] : '.';
186 }
187
188 return copy_result;
189}
190
192
193} // namespace string
194} // namespace pw
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:68
Definition: result.h:143
Definition: status.h:120
static constexpr Status OutOfRange()
Definition: status.h:267
static constexpr Status ResourceExhausted()
Definition: status.h:230
Definition: status_with_size.h:51
constexpr size_t size() const
Definition: status_with_size.h:148
Definition: span_impl.h:235
#define PW_CONSTEXPR_CPP20
Definition: language_feature_macros.h:27
constexpr Status OkStatus()
Definition: status.h:450
Status Append(InlineString<> &string, std::string_view view)
Definition: util.h:163
StatusWithSize Copy(std::string_view source, Span &&dest)
pw::string::Copy is a safer alternative to std::strncpy as it always null-terminates whenever the des...
Definition: util.h:110
Status Assign(InlineString<> &string, std::string_view view)
Definition: util.h:142
constexpr std::string_view ClampedCString(span< const char > str)
Safe alternative to the string_view constructor that avoids the risk of an unbounded implicit or expl...
Definition: util.h:60
StatusWithSize PrintableCopy(std::string_view source, span< char > dest)
Provides a safe, printable copy of a string.
Definition: util.h:181
constexpr Result< size_t > NullTerminatedLength(span< const char > str)
pw::string::NullTerminatedLength is a safer alternative to strlen for calculating the null-terminated...
Definition: util.h:81
The Pigweed namespace.
Definition: alignment.h:27
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...