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
88 PW_DASSERT(str.data() != nullptr);
89
90 const size_t length = internal::ClampedLength(str.data(), str.size());
91 if (length == str.size()) {
92 return Status::OutOfRange();
93 }
94
95 return length;
96}
97
98constexpr Result<size_t> NullTerminatedLength(const char* str, size_t max_len) {
99 return NullTerminatedLength(span<const char>(str, max_len));
100}
101
121template <typename Span>
122PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(std::string_view source,
123 Span&& dest) {
124 static_assert(
125 !std::is_base_of_v<InlineString<>, std::decay_t<Span>>,
126 "Do not use pw::string::Copy() with pw::InlineString<>. Instead, use "
127 "pw::InlineString<>'s assignment operator or assign() function, or "
128 "pw::string::Append().");
129 return internal::CopyToSpan(source, std::forward<Span>(dest));
130}
131
132template <typename Span>
133PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(const char* source, Span&& dest) {
134 PW_DASSERT(source != nullptr);
135 return Copy(ClampedCString(source, std::size(dest)),
136 std::forward<Span>(dest));
137}
138
139PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(const char* source,
140 char* dest,
141 size_t num) {
142 return Copy(source, span<char>(dest, num));
143}
144
160inline Status Assign(InlineString<>& string, std::string_view view) {
161 const size_t chars_copied =
162 std::min(view.size(), static_cast<size_t>(string.capacity()));
163 string.assign(view, 0, static_cast<string_impl::size_type>(chars_copied));
164 return chars_copied == view.size() ? OkStatus() : Status::ResourceExhausted();
165}
166
167inline Status Assign(InlineString<>& string, const char* c_string) {
168 PW_DASSERT(c_string != nullptr);
169 // Clamp to capacity + 1 so strings larger than the capacity yield an error.
170 return Assign(string, ClampedCString(c_string, string.capacity() + 1));
171}
172
187inline Status Append(InlineString<>& string, std::string_view view) {
188 const size_t chars_copied = std::min(
189 view.size(), static_cast<size_t>(string.capacity() - string.size()));
190 string.append(view, 0, static_cast<string_impl::size_type>(chars_copied));
191 return chars_copied == view.size() ? OkStatus() : Status::ResourceExhausted();
192}
193
194inline Status Append(InlineString<>& string, const char* c_string) {
195 PW_DASSERT(c_string != nullptr);
196 // Clamp to capacity + 1 so strings larger than the capacity yield an error.
197 return Append(string, ClampedCString(c_string, string.capacity() + 1));
198}
199
205PW_CONSTEXPR_CPP20 inline StatusWithSize PrintableCopy(std::string_view source,
206 span<char> dest) {
207 StatusWithSize copy_result = Copy(source, dest);
208 for (size_t i = 0; i < copy_result.size(); i++) {
209 dest[i] = std::isprint(dest[i]) ? dest[i] : '.';
210 }
211
212 return copy_result;
213}
214
216
217} // namespace string
218} // namespace pw
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:68
Definition: poll.h:25
Definition: status.h:109
static constexpr Status OutOfRange()
Operation attempted out of range; e.g. seeking past end of file.
Definition: status.h:172
static constexpr Status ResourceExhausted()
Definition: status.h:157
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:297
Status Append(InlineString<> &string, std::string_view view)
Definition: util.h:187
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:122
Status Assign(InlineString<> &string, std::string_view view)
Definition: util.h:160
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:205
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:87
The Pigweed namespace.
Definition: alignment.h:27
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...