libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
textstream.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <cstdio>
14#include <cstdint>
15#include <promeki/namespace.h>
16#include <promeki/string.h>
17#include <promeki/iodevice.h>
18
19PROMEKI_NAMESPACE_BEGIN
20
21class Buffer;
22class Variant;
23
63class TextStream {
64 public:
66 enum Status {
67 Ok,
68 ReadPastEnd,
69 WriteFailed
70 };
71
73 enum FieldAlignment {
74 Left,
75 Right,
76 Center
77 };
78
80 enum RealNumberNotation {
81 SmartNotation,
82 Fixed,
83 Scientific
84 };
85
94 explicit TextStream(IODevice *device);
95
104 explicit TextStream(Buffer *buffer);
105
114 explicit TextStream(String *string);
115
125 explicit TextStream(FILE *file);
126
128 ~TextStream();
129
130 // ============================================================
131 // Status
132 // ============================================================
133
138 Status status() const { return _status; }
139
143 void resetStatus() { _status = Ok; }
144
149 bool atEnd() const;
150
158 void flush();
159
164 IODevice *device() const { return _device; }
165
166 // ============================================================
167 // Encoding
168 // ============================================================
169
177 void setEncoding(const String &encoding);
178
183 String encoding() const { return _encoding; }
184
185 // ============================================================
186 // Formatting controls
187 // ============================================================
188
198 void setFieldWidth(int width) { _fieldWidth = width; }
199
204 int fieldWidth() const { return _fieldWidth; }
205
210 void setFieldAlignment(FieldAlignment align) { _fieldAlignment = align; }
211
216 FieldAlignment fieldAlignment() const { return _fieldAlignment; }
217
222 void setPadChar(char c) { _padChar = c; }
223
228 char padChar() const { return _padChar; }
229
237 void setIntegerBase(int base) { _integerBase = base; }
238
243 int integerBase() const { return _integerBase; }
244
249 void setRealNumberPrecision(int precision) { _realNumberPrecision = precision; }
250
255 int realNumberPrecision() const { return _realNumberPrecision; }
256
261 void setRealNumberNotation(RealNumberNotation notation) { _realNumberNotation = notation; }
262
267 RealNumberNotation realNumberNotation() const { return _realNumberNotation; }
268
269 // ============================================================
270 // Write operators
271 // ============================================================
272
274 TextStream &operator<<(const String &val);
276 TextStream &operator<<(const char *val);
278 TextStream &operator<<(char val);
280 TextStream &operator<<(int val);
282 TextStream &operator<<(unsigned int val);
284 TextStream &operator<<(int64_t val);
286 TextStream &operator<<(uint64_t val);
288 TextStream &operator<<(float val);
290 TextStream &operator<<(double val);
292 TextStream &operator<<(bool val);
294 TextStream &operator<<(const Variant &val);
295
297 TextStream &operator<<(TextStream &(*manip)(TextStream &));
298
299 // ============================================================
300 // Read operators
301 // ============================================================
302
304 TextStream &operator>>(String &val);
306 TextStream &operator>>(char &val);
308 TextStream &operator>>(int &val);
310 TextStream &operator>>(int64_t &val);
312 TextStream &operator>>(double &val);
313
314 // ============================================================
315 // Read methods
316 // ============================================================
317
325 String readLine();
326
331 String readAll();
332
338 String read(size_t maxLength);
339
340 private:
345 void writeString(const String &str);
346
352 String applyPadding(const String &str);
353
359 bool readChar(char &ch);
360
369 void unreadChar(char ch);
370
374 void skipWhitespace();
375
380 String readToken();
381
382 IODevice *_device = nullptr;
383 IODevice::UPtr _ownedDevice;
384
385 // Encoding
386 String _encoding{"UTF-8"};
387
388 // Formatting state
389 int _fieldWidth = 0;
390 FieldAlignment _fieldAlignment = Right;
391 char _padChar = ' ';
392 int _integerBase = 10;
393 int _realNumberPrecision = 6;
394 RealNumberNotation _realNumberNotation = SmartNotation;
395
396 // Status
397 Status _status = Ok;
398};
399
400// ============================================================================
401// Manipulators
402// ============================================================================
403
405inline TextStream &endl(TextStream &s) {
406 s << '\n';
407 s.flush();
408 return s;
409}
410
412inline TextStream &flush(TextStream &s) {
413 s.flush();
414 return s;
415}
416
418inline TextStream &hex(TextStream &s) {
419 s.setIntegerBase(16);
420 return s;
421}
422
424inline TextStream &dec(TextStream &s) {
425 s.setIntegerBase(10);
426 return s;
427}
428
430inline TextStream &oct(TextStream &s) {
431 s.setIntegerBase(8);
432 return s;
433}
434
436inline TextStream &bin(TextStream &s) {
437 s.setIntegerBase(2);
438 return s;
439}
440
442inline TextStream &fixed(TextStream &s) {
443 s.setRealNumberNotation(TextStream::Fixed);
444 return s;
445}
446
448inline TextStream &scientific(TextStream &s) {
449 s.setRealNumberNotation(TextStream::Scientific);
450 return s;
451}
452
454inline TextStream &left(TextStream &s) {
455 s.setFieldAlignment(TextStream::Left);
456 return s;
457}
458
460inline TextStream &right(TextStream &s) {
461 s.setFieldAlignment(TextStream::Right);
462 return s;
463}
464
466inline TextStream &center(TextStream &s) {
467 s.setFieldAlignment(TextStream::Center);
468 return s;
469}
470
471// ============================================================================
472// Stream operators for foundational generic types
473//
474// These templated operators live here (rather than alongside their
475// respective class definitions) so the @ref TextStream definition is
476// fully visible at template-parse time. The corresponding class
477// header (atomic.h, pair.h, span.h) is forward-declared below — actual
478// usage requires both the class header and this header to be included.
479// ============================================================================
480
481template <typename T> class Atomic;
482template <typename A, typename B> class Pair;
483template <typename T> class Span;
484
495template <typename T> inline TextStream &operator<<(TextStream &s, const Atomic<T> &a) {
496 s << a.value();
497 return s;
498}
499
509template <typename A, typename B> inline TextStream &operator<<(TextStream &s, const Pair<A, B> &p) {
510 s << "(" << p.first() << ", " << p.second() << ")";
511 return s;
512}
513
524template <typename T> inline TextStream &operator<<(TextStream &s, const Span<T> &span) {
525 s << "[";
526 for (size_t i = 0; i < span.size(); ++i) {
527 if (i != 0) s << ", ";
528 s << span[i];
529 }
530 s << "]";
531 return s;
532}
533
534PROMEKI_NAMESPACE_END
535
536#endif // PROMEKI_ENABLE_CORE