acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
text_reader.h
1// Created by camilo on 2022-04-26 05:41 <3ThomasBorregaardSorensen!!
2#pragma once
3
4
5#include "acme/exception/parsing.h"
6#include "acme/prototype/string/string_block.h"
7
8
9class CLASS_DECL_ACME text_reader
10{
11public:
12
13
14 const_char_pointer m_psz;
15
16
17 text_reader() {}
18 text_reader(const_char_pointer psz) : m_psz(psz) { }
19 text_reader(const text_reader & textreader) :
20 m_psz(textreader.m_psz)
21 {
22
23 }
24 text_reader(text_reader && textreader) :
25 m_psz(textreader.m_psz)
26 {
27 textreader.m_psz = nullptr;
28 }
29 ~text_reader()
30 {
31
32 }
33
34
35 text_reader & operator >>(bool & b)
36 {
37
38 skip_whitespace(m_psz);
39
40 auto word = read_word(m_psz);
41
42 paired_trim(word, "\"'([{", "\"')]}");
43
44 if (word == "0")
45 {
46
47 b = false;
48
49 }
50 else if (word == "1")
51 {
52
53 b = true;
54
55 }
56 else if (word.case_insensitive_order("false") == 0)
57 {
58
59 b = false;
60
61 }
62 else if (word.case_insensitive_order("true") == 0)
63 {
64
65 b = true;
66
67 }
68 else if (word.case_insensitive_order("no") == 0)
69 {
70
71 b = false;
72
73 }
74 else if (word.case_insensitive_order("yes") == 0)
75 {
76
77 b = true;
78
79 }
80 else
81 {
82
83 throw parsing_exception("text_reader::operator >> (bool &) invalid value for boolean : \"" + string(word) + "\"");
84
85 }
86
87 return *this;
88
89 }
90
91
92 text_reader & operator >>(::i8 & ch)
93 {
94
95 ch = *m_psz++;
96
97 return *this;
98
99 }
100
101
102 text_reader & operator >>(::u8 & uch)
103 {
104
105 uch = *((::u8 *)m_psz);
106
107 m_psz++;
108
109 return *this;
110
111 }
112
113
114#ifdef WINDOWS
115
116
117 text_reader & operator >>(unichar & wch)
118 {
119
120 wch = ::consume_unicode_index(m_psz);
121
122 return *this;
123
124 }
125
126
127#endif
128
129
130 //text_reader & operator >>(::i8 & i)
131 //{
132
133 // i = *m_psz++;
134
135 // return *this;
136
137 //}
138
139
140
141
142 text_reader & operator >>(::i16 & sh)
143 {
144
145 read_integer(sh, m_psz);
146
147 return *this;
148
149 }
150
151
152 text_reader & operator >>(::u16 & u)
153 {
154
155 read_natural(u, m_psz);
156
157 return *this;
158
159 }
160
161
162 text_reader & operator >>(::i32 & i)
163 {
164
165 read_integer(i, m_psz);
166
167 return *this;
168
169 }
170
171
172 text_reader & operator >>(::u32 & u)
173 {
174
175 read_natural(u, m_psz);
176
177 return *this;
178
179 }
180
181
182 text_reader & operator >>(::i64 & i)
183 {
184
185 read_integer(i, m_psz);
186
187 return *this;
188
189 }
190
191
192 text_reader & operator >>(::u64 & u)
193 {
194
195 read_natural(u, m_psz);
196
197 return *this;
198
199 }
200
201
202 text_reader & operator >>(::f32 & f)
203 {
204
205 read_f32(f, m_psz);
206
207 return *this;
208
209 }
210
211
212 text_reader & operator >>(::f64 & d)
213 {
214
215 read_f32(d, m_psz);
216
217 return *this;
218
219 }
220
221
222 text_reader & operator >>(string & str)
223 {
224
225 str = read_line(m_psz);
226
227 return *this;
228
229 }
230
231
232 text_reader & operator >>(::property_set & set)
233 {
234
235 set.parse_network_payload(m_psz);
236
237 return *this;
238
239 }
240
241
242 static string read_line(const_char_pointer &psz)
243 {
244
245 if (::is_null(psz))
246 {
247
248 return "";
249
250 }
251
252 if (*psz == '\0')
253 {
254
255 return "";
256
257 }
258
259 auto pszStart = psz;
260
261 while (*psz != '\r' && *psz != '\n' && *psz != '\0')
262 {
263
264 psz++;
265
266 }
267
268 auto pszEnd = psz;
269
270 if (*psz == '\n' && *(psz - 1) == '\r')
271 {
272
273 psz++;
274
275 }
276
277 return { pszStart, pszEnd - pszStart };
278
279 }
280
281
282 static const_ansi_range read_word(const_char_pointer &psz)
283 {
284
285 if (::is_null(psz))
286 {
287
288 return {};
289
290 }
291
292 if (*psz == '\0')
293 {
294
295 return {};
296
297 }
298
299 auto pszStart = psz;
300
301 while (!character_isspace(*psz) && *psz != '\0')
302 {
303
304 psz++;
305
306 }
307
308 auto pszEnd = psz;
309
310 if (*psz == '\n' && *(psz - 1) == '\r')
311 {
312
313 psz++;
314
315 }
316
317 return { pszStart, pszEnd - pszStart };
318
319 }
320
321
322 template < typename TYPE >
323 void read_natural(TYPE & t, const_char_pointer &psz)
324 {
325
326 skip_whitespace(psz);
327
328 auto pszStart = psz;
329
330 auto l = strtol(psz, (char_pointer *) & psz, 10);
331
332 if (psz == pszStart || l < 0)
333 {
334
335 throw parsing_exception("cannot text_reader::read_natural from \"" + ellipsis(pszStart, 20) + "\"");
336
337 }
338
339 t = (TYPE)l;
340
341 }
342
343
344 template < typename TYPE >
345 void read_integer(TYPE & t, const_char_pointer &psz)
346 {
347
348 skip_whitespace(psz);
349
350 auto pszStart = psz;
351
352 t = (TYPE)strtol(psz, (char_pointer *) & psz, 10);
353
354 if (psz == pszStart)
355 {
356
357 throw parsing_exception("cannot text_reader::read_integer from \"" + ellipsis(pszStart, 20) + "\"");
358
359 }
360
361 }
362
363
364 template < typename TYPE >
365 void read_f32(TYPE & t, const_char_pointer &psz)
366 {
367
368 skip_whitespace(psz);
369
370 auto pszStart = psz;
371
372 t = (TYPE)strtod(psz, (char_pointer *) & psz);
373
374 if (psz == pszStart)
375 {
376
377 throw parsing_exception("cannot text_reader::read_f32 from \"" + ellipsis(pszStart, 32) + "\"");
378
379 }
380
381 }
382
383
384 static void skip_whitespace(const_char_pointer &psz)
385 {
386
387 while (unicode_is_whitespace(*psz))
388 {
389
390 psz++;
391
392 }
393
394 }
395
396
397 static void paired_trim(const_ansi_range & block, const_char_pointer pszBeg, const_char_pointer pszEnd)
398 {
399
400 const_char_pointer pszBegChar = pszBeg;
401 const_char_pointer pszEndChar = pszEnd;
402
403 for (;
404 *pszBegChar != '\0' &&
405 *pszEndChar != '\0';
406 pszBegChar++,
407 pszEndChar++
408 )
409 {
410
411 if (*block.begin() == *pszBegChar && *(block.end() - 1) == *pszEndChar)
412 {
413
414 block.begin()++;
415 block.end()--;
416
417 pszBegChar = pszBeg;
418 pszEndChar = pszEnd;
419
420 }
421
422 }
423
424 }
425
426
427 static string ellipsis(const_char_pointer psz, character_count maximum_length)
428 {
429
430 if (maximum_length < 3)
431 {
432
433 throw ::exception(error_bad_argument);
434
435 }
436
437 auto pszStart = psz;
438
439 character_count i = 0;
440
441 for (; i < maximum_length; i++, psz++)
442 {
443
444 if (*psz == '\0')
445 {
446
447 break;
448
449 }
450
451 }
452
453 string str;
454
455 auto pszBuffer = str.get_buffer(i);
456
457 if (i == maximum_length && *psz != '\0')
458 {
459
460 memory_copy(pszBuffer, pszStart, maximum_length - 3);
461
462 ansi_copy(pszBuffer + maximum_length - 3, "...");
463
464 }
465 else
466 {
467
468 memory_copy(pszBuffer, pszStart, i);
469
470 }
471
472 str.release_buffer(i);
473
474 return ::transfer(str);
475
476 }
477
478};
479
480
481
Definition parsing.h:10
Definition property_set.h:512
Definition block.h:46