libxr
Embedded C++ framework for bare-metal, RTOS and Linux
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{
49template <typename Sink, typename Format, typename... Args>
50 requires OutputSink<Sink> && CompiledFormat<std::remove_cvref_t<Format>>
51[[nodiscard]] inline ErrorCode Write(Sink& sink, const Format& format, Args&&... args)
52{
53 using Built = std::remove_cvref_t<Format>;
54 return Writer::template RunArgumentOrder<Sink, Built, Built::ArgumentOrder()>(
55 sink, format, std::forward<Args>(args)...);
56}
57
70template <OutputSink Sink, typename Format, typename... Args>
71[[nodiscard]] inline ErrorCode FormatTo(Sink& sink, const Format& format, Args&&... args)
72{
73 return Write(sink, format, std::forward<Args>(args)...);
74}
75
87template <Text Source, OutputSink Sink, typename... Args>
88[[nodiscard]] inline ErrorCode FormatTo(Sink& sink, Args&&... args)
89{
90 constexpr LibXR::Format<Source> format{};
91 return FormatTo(sink, format, std::forward<Args>(args)...);
92}
93
105template <Text Source, OutputSink Sink, typename... Args>
106[[nodiscard]] inline ErrorCode PrintfTo(Sink& sink, Args&&... args)
107{
108 constexpr auto format = Printf::Build<Source>();
109 return FormatTo(sink, format, std::forward<Args>(args)...);
110}
111
145[[nodiscard]] inline int FormatIntoBuffer(char* buffer, size_t capacity,
146 const auto& format, auto&&... args)
147{
148 struct BufferSink
149 {
150 char* buffer = nullptr;
151 size_t retain_limit = 0;
152 size_t retained_size = 0;
153 size_t total_size = 0;
154
155 [[nodiscard]] ErrorCode Write(std::string_view chunk)
156 {
157 total_size += chunk.size();
158
159 if (buffer == nullptr || retained_size >= retain_limit)
160 {
161 return ErrorCode::OK;
162 }
163
164 size_t writable = retain_limit - retained_size;
165 size_t copy_size = chunk.size() < writable ? chunk.size() : writable;
166 if (copy_size > 0)
167 {
168 std::memcpy(buffer + retained_size, chunk.data(), copy_size);
169 retained_size += copy_size;
170 }
171 return ErrorCode::OK;
172 }
173 };
174
175 BufferSink sink{
176 .buffer = buffer,
177 .retain_limit = capacity > 0 ? capacity - 1 : 0,
178 };
179 auto ec = Write(sink, format, std::forward<decltype(args)>(args)...);
180 if (ec != ErrorCode::OK)
181 {
182 if (capacity > 0 && buffer != nullptr)
183 {
184 buffer[0] = '\0';
185 }
186 return -1;
187 }
188
189 if (capacity > 0 && buffer != nullptr)
190 {
191 buffer[sink.retained_size] = '\0';
192 }
193
194 if (sink.total_size > static_cast<size_t>(std::numeric_limits<int>::max()))
195 {
196 return -1;
197 }
198
199 return static_cast<int>(sink.total_size);
200}
201
216template <Text Source, typename... Args>
217[[nodiscard]] inline int FormatIntoBuffer(char* buffer, size_t capacity, Args&&... args)
218{
219 constexpr LibXR::Format<Source> format{};
220 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
221}
222
237template <Text Source, typename... Args>
238[[nodiscard]] inline int PrintfIntoBuffer(char* buffer, size_t capacity, Args&&... args)
239{
240 constexpr auto format = Printf::Build<Source>();
241 return FormatIntoBuffer(buffer, capacity, format, std::forward<Args>(args)...);
242}
243
264[[nodiscard]] inline int SNPrintf(char* buffer, size_t capacity, const auto& format,
265 auto&&... args)
266{
267 return FormatIntoBuffer(buffer, capacity, format,
268 std::forward<decltype(args)>(args)...);
269}
270
285template <Text Source, typename... Args>
286[[nodiscard]] inline int SNPrintf(char* buffer, size_t capacity, Args&&... args)
287{
288 constexpr auto format = Printf::Build<Source>();
289 return SNPrintf(buffer, capacity, format, std::forward<Args>(args)...);
290}
291
292} // namespace LibXR::Print
static consteval Compiled< Source > Build()
在编译期解析并校验 printf 格式串 / Parse and validate a printf format at compile time
Definition printf.hpp:124
@ Format
强制使用 brace 风格前端 / force brace-style frontend
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful