libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
writer_executor_field.hpp
1#pragma once
2
13template <OutputSink Sink>
14ErrorCode Writer::Executor<Sink>::WriteRaw(std::string_view text)
15{
16 return sink_.Write(text);
17}
18
26template <OutputSink Sink>
27ErrorCode Writer::Executor<Sink>::WritePadding(char fill, size_t count)
28{
29 char chunk[16];
30 std::memset(chunk, fill, sizeof(chunk));
31
32 while (count != 0)
33 {
34 size_t step = (count < sizeof(chunk)) ? count : sizeof(chunk);
35 auto ec = WriteRaw(std::string_view(chunk, step));
36 if (ec != ErrorCode::OK)
37 {
38 return ec;
39 }
40 count -= step;
41 }
42
43 return ErrorCode::OK;
44}
45
54template <OutputSink Sink>
55ErrorCode Writer::Executor<Sink>::WriteTextField(std::string_view text, const Spec& spec)
56{
57 size_t pad = FieldPadding(spec.width, text.size());
58 size_t left_pad = 0;
59 size_t right_pad = 0;
60 if (spec.LeftAlign())
61 {
62 right_pad = pad;
63 }
64 else if (spec.CenterAlign())
65 {
66 left_pad = pad / 2;
67 right_pad = pad - left_pad;
68 }
69 else
70 {
71 left_pad = pad;
72 }
73
74 if (auto ec = WritePadding(spec.fill, left_pad); ec != ErrorCode::OK)
75 {
76 return ec;
77 }
78 if (auto ec = WriteRaw(text); ec != ErrorCode::OK)
79 {
80 return ec;
81 }
82 return WritePadding(spec.fill, right_pad);
83}
84
97template <OutputSink Sink>
99 std::string_view prefix,
100 std::string_view digits,
101 const Spec& spec)
102{
103 auto write_char = [this](char ch) -> ErrorCode
104 {
105 if (ch == '\0')
106 {
107 return ErrorCode::OK;
108 }
109 return WriteRaw(std::string_view(&ch, 1));
110 };
111 auto write_text = [this](std::string_view text) -> ErrorCode
112 {
113 if (text.empty())
114 {
115 return ErrorCode::OK;
116 }
117 return WriteRaw(text);
118 };
119
120 size_t zeros = IntegerPrecisionZeros(spec, digits.size());
121 size_t total =
122 digits.size() + zeros + prefix.size() + static_cast<size_t>(sign_char != '\0');
123 size_t pad = FieldPadding(spec.width, total);
124 bool zero_fill =
125 spec.ZeroPad() && !spec.LeftAlign() && !spec.CenterAlign() && !spec.HasPrecision();
126 size_t left_pad = 0;
127 size_t middle_zeros = zero_fill ? pad : 0;
128 size_t right_pad = 0;
129 if (!zero_fill)
130 {
131 if (spec.LeftAlign())
132 {
133 right_pad = pad;
134 }
135 else if (spec.CenterAlign())
136 {
137 left_pad = pad / 2;
138 right_pad = pad - left_pad;
139 }
140 else
141 {
142 left_pad = pad;
143 }
144 }
145
146 if (auto ec = WritePadding(spec.fill, left_pad); ec != ErrorCode::OK)
147 {
148 return ec;
149 }
150 if (auto ec = write_char(sign_char); ec != ErrorCode::OK)
151 {
152 return ec;
153 }
154 if (auto ec = write_text(prefix); ec != ErrorCode::OK)
155 {
156 return ec;
157 }
158 if (auto ec = WritePadding('0', middle_zeros); ec != ErrorCode::OK)
159 {
160 return ec;
161 }
162 if (auto ec = WritePadding('0', zeros); ec != ErrorCode::OK)
163 {
164 return ec;
165 }
166 if (auto ec = write_text(digits); ec != ErrorCode::OK)
167 {
168 return ec;
169 }
170 return WritePadding(spec.fill, right_pad);
171}
172
183template <OutputSink Sink>
184ErrorCode Writer::Executor<Sink>::WriteFloatField(char sign_char, std::string_view text,
185 const Spec& spec)
186{
187 auto write_char = [this](char ch) -> ErrorCode
188 {
189 if (ch == '\0')
190 {
191 return ErrorCode::OK;
192 }
193 return WriteRaw(std::string_view(&ch, 1));
194 };
195
196 size_t total = text.size() + static_cast<size_t>(sign_char != '\0');
197 size_t pad = FieldPadding(spec.width, total);
198 bool zero_fill = spec.ZeroPad() && !spec.LeftAlign() && !spec.CenterAlign();
199 size_t left_pad = 0;
200 size_t middle_zeros = zero_fill ? pad : 0;
201 size_t right_pad = 0;
202 if (!zero_fill)
203 {
204 if (spec.LeftAlign())
205 {
206 right_pad = pad;
207 }
208 else if (spec.CenterAlign())
209 {
210 left_pad = pad / 2;
211 right_pad = pad - left_pad;
212 }
213 else
214 {
215 left_pad = pad;
216 }
217 }
218
219 if (auto ec = WritePadding(spec.fill, left_pad); ec != ErrorCode::OK)
220 {
221 return ec;
222 }
223 if (auto ec = write_char(sign_char); ec != ErrorCode::OK)
224 {
225 return ec;
226 }
227 if (auto ec = WritePadding('0', middle_zeros); ec != ErrorCode::OK)
228 {
229 return ec;
230 }
231 if (auto ec = WriteRaw(text); ec != ErrorCode::OK)
232 {
233 return ec;
234 }
235 return WritePadding(spec.fill, right_pad);
236}
ErrorCode WriteRaw(std::string_view text)
运行期执行器共享的字段写出原语,供所有操作码路径复用 / Executor-side field-writing primitives shared by all runtime opcodes
ErrorCode WritePadding(char fill, size_t count)
向输出端写入重复填充字符 / Write repeated fill characters into the sink
ErrorCode WriteIntegerField(char sign_char, std::string_view prefix, std::string_view digits, const Spec &spec)
按符号、前缀、精度与填充策略写出一个整数载荷 / Write one integer payload with sign, prefix, precision, and padding policy a...
ErrorCode WriteTextField(std::string_view text, const Spec &spec)
按宽度与对齐策略写出一个文本字段 / Write one text field with width/alignment policy applied
ErrorCode WriteFloatField(char sign_char, std::string_view text, const Spec &spec)
按符号与字段填充策略写出一个浮点文本载荷 / Write one float text payload with sign and field padding applied