microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
foreign_string_view.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2//
3// SPDX-License-Identifier: BSD-2-Clause
4
5#pragma once
6
10#include "../microfmt.hpp"
11#include "address_space.hpp"
12
13#include <cstddef>
14#include <cstdint>
15#include <string_view>
16
17namespace microfmt {
18
19// ============================================================================
20// Foreign String View
21// ============================================================================
22
30public:
34 constexpr foreign_string_view() noexcept = default;
35
44 constexpr foreign_string_view(uintptr_t addr, address_space_ref space,
45 span<char> scratch RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS,
46 size_t max_limit = 4096) noexcept
47 : addr_(addr), space_(space), scratch_(scratch), max_limit_(max_limit) {}
48
58 template <size_t N>
59 constexpr foreign_string_view(uintptr_t addr, address_space_ref space,
60 char (&scratch RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS)[N],
61 size_t max_limit = 4096) noexcept
62 : addr_(addr), space_(space), scratch_(scratch, N), max_limit_(max_limit) {}
63
68 [[nodiscard]] constexpr uintptr_t address() const noexcept { return addr_; }
69
74 [[nodiscard]] constexpr address_space_ref space() const noexcept { return space_; }
75
80 [[nodiscard]] constexpr span<char> scratch() const noexcept RELOCO_LIFETIMEBOUND { return scratch_; }
81
86 [[nodiscard]] constexpr size_t max_limit() const noexcept { return max_limit_; }
87
88private:
90 uintptr_t addr_{0};
92 address_space_ref space_{};
94 span<char> scratch_{};
96 size_t max_limit_{4096};
97};
98
99// ============================================================================
100// microfmt Formatter Specialization
101// ============================================================================
102
109template <> struct formatter<foreign_string_view> {
113 constexpr void parse(format_parse_context &) noexcept {}
114
120 void format(const foreign_string_view &view, const sink &out) const noexcept {
121 if (view.address() == 0) {
122 out.write("(null)");
123 return;
124 }
125
126 if (!view.space() || view.scratch().empty()) {
127 microfmt::format_to(out, "<invalid-foreign@{:#x}>", view.address());
128 return;
129 }
130
131 uintptr_t cur = view.address();
132 size_t total = 0;
133
134 while (total < view.max_limit()) {
135 auto chunk = view.space().read_string_chunk(cur, view.scratch());
136 if (!chunk) {
137 if (total == 0) {
138 microfmt::format_to(out, "<fault@{:#x}>", view.address());
139 } else {
140 out.write("<fault>");
141 }
142 return;
143 }
144
145 const size_t chunk_len = chunk->length;
146 if (chunk_len > 0) {
147 const size_t limit_left = view.max_limit() - total;
148 const size_t to_write = (chunk_len > limit_left) ? limit_left : chunk_len;
149 const auto scratch = view.scratch();
150 out.write(microfmt::string_view(scratch.data(), to_write));
151 total += to_write;
152 cur += to_write;
153 }
154
155 if (chunk->null_terminated || total >= view.max_limit()) {
156 break;
157 }
158 }
159
160 if (total >= view.max_limit()) {
161 out.write("...");
162 }
163 }
164};
165
166} // namespace microfmt
Type-erased remote address-space access and remote string/object views.
Type-erased, two-word handle to a remote address space.
Definition address_space.hpp:204
Streaming view of a foreign or non-contiguous string.
Definition foreign_string_view.hpp:29
constexpr uintptr_t address() const noexcept
Returns the foreign string address.
Definition foreign_string_view.hpp:68
constexpr size_t max_limit() const noexcept
Returns the maximum render length.
Definition foreign_string_view.hpp:86
constexpr span< char > scratch() const noexcept RELOCO_LIFETIMEBOUND
Returns the scratch chunk buffer.
Definition foreign_string_view.hpp:80
constexpr foreign_string_view(uintptr_t addr, address_space_ref space, char(&scratch RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS)[N], size_t max_limit=4096) noexcept
Constructs a view over a foreign string using a fixed C array as scratch.
Definition foreign_string_view.hpp:59
constexpr address_space_ref space() const noexcept
Returns the address space handle.
Definition foreign_string_view.hpp:74
constexpr foreign_string_view() noexcept=default
Constructs an empty (null) foreign string view.
Definition microfmt.hpp:881
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Definition assert.hpp:19
reloco::sink sink
Type-erased, zero-allocation output sink.
Definition microfmt.hpp:46
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
constexpr void parse(format_parse_context &) noexcept
No-op parse; foreign strings accept no format specifier.
Definition foreign_string_view.hpp:113
void format(const foreign_string_view &view, const sink &out) const noexcept
Renders the foreign string, chunk-by-chunk.
Definition foreign_string_view.hpp:120
Definition microfmt.hpp:985