API Reference#
pw_string: Efficient, easy, and safe string manipulation
Overview#
This module provides two types of strings and utility functions for working with strings.
pw::StringBuilder
pw::StringBuilder
facilitates creating formatted strings in a fixed-sized buffer or in a pw::InlineString
. It is designed to give the flexibility of std::ostringstream, but with a small footprint.
pw::InlineString
pw::InlineBasicString
and pw::InlineString
are safer alternatives to std::basic_string
and std::string
.
String utility functions
The pw::string::*
functions provide safer alternatives to C++ standard library string functions.
UTF-8 Helpers
pw::StringBuilder#
pw::StringBuilder
facilitates creating formatted strings in a fixed-sized buffer or in a pw::InlineString
. It is designed to give the flexibility of std::ostringstream, but with a small footprint.
-
class StringBuilder#
pw::StringBuilder
instances are always null-terminated (unless they are constructed with an empty buffer) and never overflow. Status is tracked for each operation and an overall status is maintained, which reflects the most recent error.pw::StringBuilder
does not own the buffer it writes to. It can be used to write strings to any buffer. Thepw::StringBuffer
template class, defined below, allocates a buffer alongside apw::StringBuilder
.pw::StringBuilder
supports C++-style<<
output, similar tostd::ostringstream
. It also supports append functions likestd::string
andprintf
-style output.Support for custom types is added by overloading
operator<<
in the same namespace as the custom type. For example:namespace my_project { struct MyType { int foo; const char* bar; }; pw::StringBuilder& operator<<(pw::StringBuilder& sb, const MyType& value) { return sb << "MyType(" << value.foo << ", " << value.bar << ')'; } } // namespace my_project
The
ToString
template function can be specialized to support custom types withpw::StringBuilder
, though overloadingoperator<<
is generally preferred. For example:namespace pw { template <> StatusWithSize ToString<MyStatus>(MyStatus value, span<char> buffer) { return Copy(MyStatusString(value), buffer); } } // namespace pw
Subclassed by pw::StringBuffer< kSizeBytes >
Public Functions
-
inline explicit constexpr StringBuilder(span<char> buffer)#
Creates an empty
pw::StringBuilder
.
-
StringBuilder(const StringBuilder&) = delete#
Disallow copy/assign to avoid confusion about where the string is actually stored.
pw::StringBuffer
instances may be copied into one another.
-
inline const char *c_str() const#
Returns the contents of the string buffer. Always null-terminated.
-
inline std::string_view view() const#
Returns a
std::string_view
of the contents of thispw::StringBuilder
. Thestd::string_view
is invalidated if thepw::StringBuilder
contents change.
-
inline operator std::string_view() const#
Allow implicit conversions to
std::string_view
sopw::StringBuilder
instances can be passed into functions that take astd::string_view
.
-
inline span<const std::byte> as_bytes() const#
Returns a
span<const std::byte>
representation of thispw::StringBuffer
.
-
inline Status status() const#
Returns the status of
pw::StringBuilder
, which reflects the most recent error that occurred while updating the string. After an update fails, the status remains non-OK until it is cleared withpw::StringBuilder::clear()
orpw::StringBuilder::clear_status()
.- Returns:
Code
Description
No errors have occurred.
Output to the
StringBuilder
was truncated.printf
-style formatting failed.An operation outside the buffer was attempted.
-
inline StatusWithSize status_with_size() const#
Returns
status()
andsize()
as aStatusWithSize
.
-
inline Status last_status() const#
The status from the last operation. May be OK while
status()
is not OK.
-
inline bool ok() const#
True if
status()
isOkStatus()
.
-
inline bool empty() const#
True if the string is empty.
-
inline size_t size() const#
Returns the current length of the string, excluding the null terminator.
-
inline size_t max_size() const#
Returns the maximum length of the string, excluding the null terminator.
-
void clear()#
Clears the string and resets its error state.
-
inline void clear_status()#
Sets the statuses to
OkStatus()
;.
-
inline void push_back(char ch)#
Appends a single character. Sets the status to
RESOURCE_EXHAUSTED
if the character cannot be added because the buffer is full.
-
inline void pop_back()#
Removes the last character. Sets the status to
OUT_OF_RANGE
if the buffer is empty (in which case the unsigned overflow is intentional).
-
StringBuilder &append(size_t count, char ch)#
Appends the provided character
count
times.
-
StringBuilder &append(const char *str, size_t count)#
Appends
count
characters fromstr
to the end of theStringBuilder
. If count exceeds the remaining space in theStringBuffer
,max_size() - size()
characters are appended and the status is set toRESOURCE_EXHAUSTED
.str
is not considered null-terminated and may contain null characters.
-
StringBuilder &append(const char *str)#
Appends characters from the null-terminated string to the end of the
StringBuilder
. If the string’s length exceeds the remaining space in the buffer,max_size() - size()
characters are copied and the status is set toRESOURCE_EXHAUSTED
.This function uses
string::Length
instead ofstd::strlen
to avoid unbounded reads if the string is not null-terminated.
-
StringBuilder &append(std::string_view str)#
Appends a
std::string_view
to the end of theStringBuilder
.
-
StringBuilder &append(std::string_view str, size_t pos, size_t count = std::string_view::npos)#
Appends a substring from the
std::string_view
to theStringBuilder
. Copies up to count characters starting frompos
to the end of theStringBuilder
. Ifpos > str.size()
, sets the status toOUT_OF_RANGE
.
-
template<typename T>
inline StringBuilder &operator<<(const T &value)# Appends to the end of the
StringBuilder
using the<<
operator. This enables C++ stream-style formatted toStringBuilder
instances.
-
inline StringBuilder &operator<<(bool value)#
Provide a few additional
operator<<
overloads that reduce code size.
-
StringBuilder &Format(const char *format, ...)#
Appends a
printf
-style string to the end of theStringBuilder
. If the formatted string does not fit, the results are truncated and the status is set toRESOURCE_EXHAUSTED
.Note
Internally, calls
string::Format
, which callsstd::vsnprintf
.- Parameters:
format – The format string
... – Arguments for format specification
- Returns:
-
StringBuilder &FormatVaList(const char *format, va_list args)#
Appends a
vsnprintf
-style string withva_list
arguments to the end of theStringBuilder
. If the formatted string does not fit, the results are truncated and the status is set toRESOURCE_EXHAUSTED
.Note
Internally, calls
string::Format
, which callsstd::vsnprintf
.
-
void resize(size_t new_size)#
Sets the size of the
StringBuilder
. This function only truncates; ifnew_size > size()
, it sets status toOUT_OF_RANGE
and does nothing.
-
inline explicit constexpr StringBuilder(span<char> buffer)#
pw::InlineString#
-
template<typename T, size_t kCapacity = string_impl::kGeneric>
class InlineBasicString# pw::InlineBasicString
is a fixed-capacity version ofstd::basic_string
. In brief:It is always null-terminated.
It stores the string contents inline and uses no dynamic memory.
It implements mostly the same API as
std::basic_string
, but the capacity of the string is fixed at construction and cannot grow. Attempting to increase the size beyond the capacity triggers an assert.
pw::InlineBasicString
is efficient and compact. The current size and capacity are stored in a single word. Accessing its contents is a simple array access within the object, with no pointer indirection, even when working from a generic referencepw::InlineBasicString<T>
where the capacity is not specified as a template argument. A string object can be used safely without the need to know its capacity.See also
pw::InlineString
, which is an alias ofpw::InlineBasicString<char>
and is equivalent tostd::string
.
-
template<size_t kCapacity = string_impl::kGeneric>
using pw::InlineString = InlineBasicString<char, kCapacity># pw::InlineString
is an alias ofpw::InlineBasicString<char>
and is equivalent tostd::string
.
String utility functions#
pw::string::Assign()#
-
inline Status pw::string::Assign(InlineString<> &string, std::string_view view)#
Assigns a
std::string_view
to apw::InlineString
, truncating if it does not fit. Theassign()
function ofpw::InlineString
asserts if the string’s requested size exceeds its capacity;pw::string::Assign()
returns aStatus
instead.- Returns:
Code
Description
The entire
std::string_view
was copied to the end of thepw::InlineString
.The
std::string_view
was truncated to fit.
pw::string::Append()#
-
inline Status pw::string::Append(InlineString<> &string, std::string_view view)#
Appends a
std::string_view
to apw::InlineString
, truncating if it does not fit. Theappend()
function ofpw::InlineString
asserts if the string’s requested size exceeds its capacity;pw::string::Append()
returns aStatus
instead.- Returns:
Code
Description
The entire
std::string_view
was assigned.The
std::string_view
was truncated to fit.
pw::string::ClampedCString()#
-
constexpr std::string_view pw::string::ClampedCString(span<const char> str)#
Safe alternative to the
string_view
constructor that avoids the risk of an unbounded implicit or explicit use ofstrlen
.This is strongly recommended over using something like C11’s
strnlen_s
as astring_view
does not require null-termination.
pw::string::Copy()#
-
inline StatusWithSize pw::string::Copy(const char *source, char *dest, size_t num)#
-
template<typename Span>
inline StatusWithSize pw::string::Copy(const char *source, Span &&dest)#
-
template<typename Span>
inline StatusWithSize pw::string::Copy(std::string_view source, Span &&dest)# pw::string::Copy
is a safer alternative tostd::strncpy
as it always null-terminates whenever the destination buffer has a non-zero size.Copies the
source
string to thedest
, truncating if the full string does not fit. Always null terminates ifdest.size()
ornum
is greater than 0.- Pre:
The destination and source shall not overlap. The source shall be a valid pointer.
- Returns:
Code
Description
Returns the number of characters written, excluding the null terminator.
The string is truncated.
It also has variants that provide a destination of pw::Vector<char>
(see pw_containers for details) that do not store the null
terminator in the vector.
pw::string::Format()#
The pw::string::Format
functions are safer alternatives to std::snprintf
and std::vsnprintf
. The snprintf
return value is awkward to interpret, and misinterpreting it can lead to serious bugs.
These functions return a pw::StatusWithSize
. The pw::Status
is set to reflect any errors and the return value is always the number of characters written before the null terminator.
-
StatusWithSize pw::string::Format(span<char> buffer, const char *format, ...)#
Writes a printf-style formatted string to the provided buffer, similarly to
std::snprintf()
.The
std::snprintf()
return value is awkward to interpret, and misinterpreting it can lead to serious bugs.- Returns:
Code
Description
Returns the number of characters written, excluding the null terminator. The buffer is always null-terminated unless it is empty.
The buffer was too small to fit the output.
There was a formatting error.
-
StatusWithSize pw::string::FormatVaList(span<char> buffer, const char *format, va_list args)#
Writes a printf-style formatted string with va_list-packed arguments to the provided buffer, similarly to
std::vsnprintf()
.- Returns:
See
pw::string::Format()
.
-
Status pw::string::Format(InlineString<> &string, const char *format, ...)#
Appends a printf-style formatted string to the provided
pw::InlineString
, similarly tostd::snprintf()
.- Returns:
See
pw::string::Format()
.
-
Status pw::string::FormatVaList(InlineString<> &string, const char *format, va_list args)#
Appends a printf-style formatted string with va_list-packed arguments to the provided
InlineString
, similarly tostd::vsnprintf()
.- Returns:
See
pw::string::Format()
.
-
Status pw::string::FormatOverwrite(InlineString<> &string, const char *format, ...)#
Writes a printf-style format string to the provided
InlineString
, overwriting any contents.- Returns:
See
pw::string::Format()
.
-
inline Status pw::string::FormatOverwriteVaList(InlineString<> &string, const char *format, va_list args)#
Writes a printf-style formatted string with
va_list
-packed arguments to the providedInlineString
, overwriting any contents.- Returns:
See
pw::string::Format()
.
pw::string::NullTerminatedLength()#
-
constexpr Result<size_t> pw::string::NullTerminatedLength(span<const char> str)#
pw::string::NullTerminatedLength
is a safer alternative tostrlen
for calculating the null-terminated length of the string within the specified span, excluding the null terminator.Like
strnlen_s
in C11, the scan for the null-terminator is bounded.- Pre:
The string shall be at a valid pointer.
- Returns:
Code
Description
Returns the null-terminated length of the string excluding the null terminator.
The string is not null-terminated.
pw::string::PrintableCopy()#
-
inline StatusWithSize pw::string::PrintableCopy(std::string_view source, span<char> dest)#
Provides a safe, printable copy of a string.
Copies the
source
string to thedest
string with same behavior aspw::string::Copy
, with the difference that any non-printable characters are changed to.
.
UTF-8 Helpers#
-
constexpr Result<EncodedCodePoint> pw::utf8::EncodeCodePoint(uint32_t code_point)#
Encodes a single code point as UTF-8.
UTF-8 encodes as 1-4 bytes from a range of
[0, 0x10FFFF]
.1-byte encoding has a top bit of zero:
N-bytes sequences are denoted by annotating the top N+1 bits of the leading byte and then using a 2-bit continuation marker on the following bytes.[0, 0x7F] 1-bytes: b0xxx xxxx
[0x00080, 0x0007FF] 2-bytes: b110x xxxx 10xx xxxx [0x00800, 0x00FFFF] 3-bytes: b1110 xxxx 10xx xxxx 10xx xxxx [0x10000, 0x10FFFF] 4-bytes: b1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
- Returns:
Code
Description
The codepoint encoded as UTF-8.
The code point was not in the valid range for UTF-8 encoding.
-
Status pw::utf8::WriteCodePoint(uint32_t code_point, pw::StringBuilder &output)#
Helper that writes a code point to the provided
pw::StringBuilder
.
-
constexpr pw::Result<utf::CodePointAndSize> pw::utf8::ReadCodePoint(std::string_view str)#
Reads the first code point from a UTF-8 encoded
str
.This is a very basic decoder without much thought for performance and very basic validation that the correct number of bytes are available and that each byte of a multibyte sequence has a continuation character. See
pw::utf8::EncodeCharacter()
for encoding details.- Returns:
Code
Description
The decoded code point and the number of bytes read.
The string was empty or malformed.
The decoded code point was not in the valid range.