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