libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
display.hpp
1
17static size_t HistoryLineSize(const HistoryLine& line)
18{
19 size_t size = 0;
20 while (size < MAX_LINE_SIZE && line[size] != '\0')
21 {
22 size++;
23 }
24 return size;
25}
26
41const HistoryLine& HistoryFromNewest(int index_from_newest)
42{
43 DEV_ASSERT(index_from_newest >= 0);
44 DEV_ASSERT(index_from_newest < static_cast<int>(history_.Size()));
45 return history_[-index_from_newest - 1];
46}
47
56void LineFeed()
57{
58 if (MODE == Mode::CRLF)
59 {
60 write_stream_ << ConstRawData("\r\n");
61 }
62 else if (MODE == Mode::LF)
63 {
64 write_stream_ << ConstRawData('\n');
65 }
66 else if (MODE == Mode::CR)
67 {
68 write_stream_ << ConstRawData('\r');
69 }
70}
71
80void UpdateDisplayPosition()
81{
82 write_stream_ << ConstRawData(KEY_SAVE) << ConstRawData(CLEAR_BEHIND)
83 << ConstRawData(&input_line_[input_line_.Size() + offset_], -offset_)
84 << ConstRawData(KEY_LOAD);
85}
86
92bool CanDisplayChar() { return input_line_.EmptySize() > 1; }
93
99bool CanDeleteChar() { return input_line_.Size() + offset_ > 0; }
100
106void AddCharToInputLine(char data)
107{
108 if (offset_ == 0)
109 {
110 input_line_.Push(data);
111 }
112 else
113 {
114 input_line_.Insert(data, input_line_.Size() + offset_);
115 }
116 input_line_[input_line_.Size()] = '\0';
117}
118
125void DisplayChar(char data)
126{
127 bool use_history = false;
128
129 if (history_index_ >= 0)
130 {
131 CopyHistoryToInputLine();
132 use_history = true;
133 }
134
135 if (CanDisplayChar())
136 {
137 AddCharToInputLine(data);
138 if (use_history)
139 {
140 ShowHistory();
141 }
142 else
143 {
144 write_stream_ << ConstRawData(input_line_[input_line_.Size() - 1 + offset_]);
145 }
146 if (offset_ != 0)
147 {
148 UpdateDisplayPosition();
149 }
150 }
151 else
152 {
153 line_truncated_ = true;
154 }
155}
156
162void RemoveCharFromInputLine()
163{
164 if (offset_ == 0)
165 {
166 input_line_.Pop();
167 }
168 else
169 {
170 input_line_.Delete(input_line_.Size() + offset_ - 1);
171 }
172 input_line_[input_line_.Size()] = '\0';
173}
174
180void DeleteChar()
181{
182 bool use_history = false;
183
184 if (history_index_ >= 0)
185 {
186 CopyHistoryToInputLine();
187 use_history = true;
188 }
189
190 if (CanDeleteChar())
191 {
192 RemoveCharFromInputLine();
193 if (use_history)
194 {
195 ShowHistory();
196 }
197 else
198 {
199 write_stream_ << ConstRawData(DELETE_CHAR);
200 }
201
202 if (offset_ != 0)
203 {
204 UpdateDisplayPosition();
205 }
206 }
207}
208
213void ShowHeader()
214{
215 write_stream_ << ConstRawData(ramfs_.root_.GetName(), strlen(ramfs_.root_.GetName()));
216 if (current_dir_ == &ramfs_.root_)
217 {
218 write_stream_ << ConstRawData(":/");
219 }
220 else
221 {
222 write_stream_ << ConstRawData(":") << ConstRawData(current_dir_->GetName());
223 }
224
225 write_stream_ << ConstRawData("$ ");
226}
227
236void ShowTruncatedLineNotice()
237{
238 char digits[20];
239 size_t pos = sizeof(digits);
240 size_t value = MAX_LINE_SIZE;
241 do
242 {
243 digits[--pos] = static_cast<char>('0' + value % 10);
244 value /= 10;
245 } while (value != 0);
246
247 write_stream_ << ConstRawData("Line truncated to ")
248 << ConstRawData(&digits[pos], sizeof(digits) - pos)
249 << ConstRawData(" characters (MAX_LINE_SIZE).");
250 LineFeed();
251}
252
257void ClearLine() { write_stream_ << ConstRawData(CLEAR_LINE); }
258
263void Clear() { write_stream_ << ConstRawData(CLEAR_ALL); }
264
273void ShowHistory()
274{
275 ClearLine();
276 ShowHeader();
277 offset_ = 0;
278 if (history_index_ >= 0)
279 {
280 const auto& line = HistoryFromNewest(history_index_);
281 write_stream_ << ConstRawData(line.data(), HistoryLineSize(line));
282 }
283 else
284 {
285 write_stream_ << ConstRawData(&input_line_[0], input_line_.Size());
286 }
287}
288
294void CopyHistoryToInputLine()
295{
296 input_line_.Reset();
297 const auto& line = HistoryFromNewest(history_index_);
298 for (size_t i = 0; i < HistoryLineSize(line); i++)
299 {
300 input_line_.Push(line[i]);
301 }
302 input_line_[input_line_.Size()] = '\0';
303 history_index_ = -1;
304 offset_ = 0;
305 line_truncated_ = false;
306}
307
316void AddHistory()
317{
318 HistoryLine line{};
319 const size_t line_size =
320 LibXR::min(static_cast<size_t>(input_line_.Size()), MAX_LINE_SIZE);
321 input_line_.Push('\0');
322 if (line_size > 0)
323 {
324 std::memcpy(line.data(), &input_line_[0], line_size);
325 }
326 line[line_size] = '\0';
327
328 if (history_.EmptySize() == 0)
329 {
330 history_.Pop();
331 }
332 history_.Push(line);
333}
constexpr auto min(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最小值 / Computes the minimum of two numbers