Pigweed
 
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
58constexpr std::string_view ClampedCString(span<const char> str) {
59 return std::string_view(str.data(),
60 internal::ClampedLength(str.data(), str.size()));
61}
62
63constexpr std::string_view ClampedCString(const char* str, size_t max_len) {
64 return ClampedCString(span<const char>(str, max_len));
65}
66
85constexpr Result<size_t> NullTerminatedLength(span<const char> str) {
86 PW_DASSERT(str.data() != nullptr);
87
88 const size_t length = internal::ClampedLength(str.data(), str.size());
89 if (length == str.size()) {
90 return Status::OutOfRange();
91 }
92
93 return length;
94}
95
96constexpr Result<size_t> NullTerminatedLength(const char* str, size_t max_len) {
97 return NullTerminatedLength(span<const char>(str, max_len));
98}
99
119template <typename Span>
120PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(std::string_view source,
121 Span&& dest) {
122 static_assert(
123 !std::is_base_of_v<InlineString<>, std::decay_t<Span>>,
124 "Do not use pw::string::Copy() with pw::InlineString<>. Instead, use "
125 "pw::InlineString<>'s assignment operator or assign() function, or "
126 "pw::string::Append().");
127 return internal::CopyToSpan(source, std::forward<Span>(dest));
128}
129
130template <typename Span>
131PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(const char* source, Span&& dest) {
132 PW_DASSERT(source != nullptr);
133 return Copy(ClampedCString(source, std::size(dest)),
134 std::forward<Span>(dest));
135}
136
137PW_CONSTEXPR_CPP20 inline StatusWithSize Copy(const char* source,
138 char* dest,
139 size_t num) {
140 return Copy(source, span<char>(dest, num));
141}
142
158inline Status Assign(InlineString<>& string, std::string_view view) {
159 const size_t chars_copied =
160 std::min(view.size(), static_cast<size_t>(string.capacity()));
161 string.assign(view, 0, static_cast<string_impl::size_type>(chars_copied));
162 return chars_copied == view.size() ? OkStatus() : Status::ResourceExhausted();
163}
164
165inline Status Assign(InlineString<>& string, const char* c_string) {
166 PW_DASSERT(c_string != nullptr);
167 // Clamp to capacity + 1 so strings larger than the capacity yield an error.
168 return Assign(string, ClampedCString(c_string, string.capacity() + 1));
169}
170
185inline Status Append(InlineString<>& string, std::string_view view) {
186 const size_t chars_copied = std::min(
187 view.size(), static_cast<size_t>(string.capacity() - string.size()));
188 string.append(view, 0, static_cast<string_impl::size_type>(chars_copied));
189 return chars_copied == view.size() ? OkStatus() : Status::ResourceExhausted();
190}
191
192inline Status Append(InlineString<>& string, const char* c_string) {
193 PW_DASSERT(c_string != nullptr);
194 // Clamp to capacity + 1 so strings larger than the capacity yield an error.
195 return Append(string, ClampedCString(c_string, string.capacity() + 1));
196}
197
203PW_CONSTEXPR_CPP20 inline StatusWithSize PrintableCopy(std::string_view source,
204 span<char> dest) {
205 StatusWithSize copy_result = Copy(source, dest);
206 for (size_t i = 0; i < copy_result.size(); i++) {
207 dest[i] = std::isprint(dest[i]) ? dest[i] : '.';
208 }
209
210 return copy_result;
211}
212
213} // namespace string
214} // namespace pw
pw::InlineBasicString is a fixed-capacity version of std::basic_string. In brief:
Definition: string.h:64
Definition: status.h:85
Definition: status_with_size.h:49
constexpr size_t size() const
Definition: status_with_size.h:146
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27
constexpr Status OkStatus()
Definition: status.h:234
pw::InlineBasicString and pw::InlineString are safer alternatives to std::basic_string and std::strin...
Status Append(InlineString<> &string, std::string_view view)
Definition: util.h:185
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:120
Status Assign(InlineString<> &string, std::string_view view)
Definition: util.h:158
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:58
StatusWithSize PrintableCopy(std::string_view source, span< char > dest)
Provides a safe, printable copy of a string.
Definition: util.h:203
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:85