libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
print_api.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstring>
5#include <limits>
6#include <string_view>
7#include <utility>
8
9#include "format_surface.hpp"
10#include "printf.hpp"
11#include "writer.hpp"
12
13namespace LibXR::Print
14{
50template <typename Sink, typename Format, typename... Args>
51 requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
52[[nodiscard]] inline ErrorCode Write(Sink& sink, const Format& format, Args&&... args)
53{
54 using Built = std::remove_cvref_t<Format>;
55 return Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
56 sink, format, std::forward<Args>(args)...);
57}
58
71template <OutputSink Sink, typename Format, typename... Args>
72[[nodiscard]] inline ErrorCode FormatTo(Sink& sink, const Format& format, Args&&... args)
73{
74 return Write(sink, format, std::forward<Args>(args)...);
75}
76
88template <Text Source, OutputSink Sink, typename... Args>
89[[nodiscard]] inline ErrorCode FormatTo(Sink& sink, Args&&... args)
90{
91 constexpr LibXR::Format<Source> format{};
92 return FormatTo(sink, format, std::forward<Args>(args)...);
93}
94
106template <Text Source, OutputSink Sink, typename... Args>
107[[nodiscard]] inline ErrorCode PrintfTo(Sink& sink, Args&&... args)
108{
109 constexpr auto format = Printf::Build<Source>();
110 return FormatTo(sink, format, std::forward<Args>(args)...);
111}
112
146[[nodiscard]] inline int FormatIntoBuffer(char* buffer, size_t capacity,
147 const auto& format, auto&&... args)
148{
149 struct BufferSink
150 {
151 char* buffer = nullptr;
152 size_t retain_limit = 0;
153 size_t retained_size = 0;
154 size_t total_size = 0;
155
156 [[nodiscard]] ErrorCode Write(std::string_view chunk)
157 {
158 total_size += chunk.size();
159
160 if (buffer == nullptr || retained_size >= retain_limit)
161 {
162 return ErrorCode::OK;
163 }
164
165 size_t writable = retain_limit - retained_size;
166 size_t copy_size = chunk.size() < writable ? chunk.size() : writable;
167 if (copy_size > 0)
168 {
169 std::memcpy(buffer + retained_size, chunk.data(), copy_size);
170 retained_size += copy_size;
171 }
172 return ErrorCode::OK;
173 }
174 };
175
176 BufferSink sink{
177 .buffer = buffer,
178 .retain_limit = capacity > 0 ? capacity - 1 : 0,
179 };
180 auto ec = Write(sink, format, std::forward<decltype(args)>(args)...);
181 if (ec != ErrorCode::OK)
182 {
183 if (capacity > 0 && buffer != nullptr)
184 {
185 buffer[0] = '\0';
186 }
187 return -1;
188 }
189
190 if (capacity > 0 && buffer != nullptr)
191 {
192 buffer[sink.retained_size] = '\0';
193 }
194
195 if (sink.total_size > static_cast<size_t>(std::numeric_limits<int>::max()))
196 {
197 return -1;
198 }
199
200 return static_cast<int>(sink.total_size);
201}
202
217template <Text Source, typename... Args>
218[[nodiscard]] inline int FormatIntoBuffer(char* buffer, size_t capacity, Args&&... args)
219{
220 constexpr LibXR::Format<Source> format{};
221 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
222}
223
238template <Text Source, typename... Args>
239[[nodiscard]] inline int PrintfIntoBuffer(char* buffer, size_t capacity, Args&&... args)
240{
241 constexpr auto format = Printf::Build<Source>();
242 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
243}
244
265[[nodiscard]] inline int SNPrintf(char* buffer, size_t capacity, const auto& format,
266 auto&&... args)
267{
268 return FormatIntoBuffer(buffer, capacity, format,
269 std::forward<decltype(args)>(args)...);
270}
271
286template <Text Source, typename... Args>
287[[nodiscard]] inline int SNPrintf(char* buffer, size_t capacity, Args&&... args)
288{
289 constexpr auto format = Printf::Build<Source>();
290 return SNPrintf(buffer, capacity, format, std::forward<Args>(args)...);
291}
292
293} // namespace LibXR::Print
static consteval Compiled< Source > Build()
在编译期解析并校验 printf 格式串 / Parse and validate a printf format at compile time
Definition printf.hpp:123
@ Format
force brace-style frontend / 强制使用 brace 风格前端
ErrorCode
定义错误码枚举
@ OK
操作成功 | Operation successful