libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
streamstring.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 <functional>
14#include <promeki/function.h>
15#include <promeki/namespace.h>
16#include <promeki/string.h>
17#include <promeki/iodevice.h>
18#include <promeki/textstream.h>
19
20PROMEKI_NAMESPACE_BEGIN
21
30class StreamStringIODevice : public IODevice {
31 PROMEKI_OBJECT(StreamStringIODevice, IODevice)
32 public:
34 using OnNewLineFunc = Function<bool(String &)>;
35
40 StreamStringIODevice(ObjectBase *parent = nullptr) : IODevice(parent) {}
41
46 void setOnNewLine(OnNewLineFunc func) { _onNewLine = std::move(func); }
47
52 const String &line() const { return _line; }
53
55 void clearLine() { _line.clear(); }
56
58 Error open(OpenMode mode) override {
59 if (isOpen()) return Error(Error::AlreadyOpen);
60 setOpenMode(mode);
61 return Error();
62 }
63
65 Error close() override {
66 setOpenMode(NotOpen);
67 return Error();
68 }
69
71 bool isOpen() const override { return openMode() != NotOpen; }
72
74 int64_t read(void *, int64_t) override { return -1; }
75
82 int64_t write(const void *data, int64_t maxSize) override {
83 if (!isOpen() || !isWritable()) return -1;
84 const char *p = static_cast<const char *>(data);
85 for (int64_t i = 0; i < maxSize; i++) {
86 if (p[i] == '\n') {
87 flushLine();
88 } else {
89 _line += p[i];
90 }
91 }
92 return maxSize;
93 }
94
96 void flush() override { flushLine(); }
97
99 bool isSequential() const override { return true; }
100
101 private:
102 OnNewLineFunc _onNewLine;
103 String _line;
104
105 void flushLine() {
106 if (!_line.isEmpty() && _onNewLine) {
107 if (_onNewLine(_line)) _line.clear();
108 }
109 }
110};
111
136class StreamString {
137 public:
139 using OnNewLineFunc = Function<bool(String &)>;
140
142 StreamString() : _stream(&_device) { _device.open(IODevice::WriteOnly); }
143
148 StreamString(OnNewLineFunc func) : _stream(&_device) {
149 _device.setOnNewLine(std::move(func));
150 _device.open(IODevice::WriteOnly);
151 }
152
154 StreamString(const StreamString &) = delete;
156 StreamString &operator=(const StreamString &) = delete;
158 StreamString(StreamString &&) = delete;
160 StreamString &operator=(StreamString &&) = delete;
161
166 TextStream &stream() { return _stream; }
167
172 void setOnNewLine(OnNewLineFunc func) {
173 _device.setOnNewLine(std::move(func));
174 return;
175 }
176
181 const String &line() const { return _device.line(); }
182
184 void clear() {
185 _device.clearLine();
186 return;
187 }
188
189 private:
190 StreamStringIODevice _device;
191 TextStream _stream;
192};
193
194PROMEKI_NAMESPACE_END
195
196#endif // PROMEKI_ENABLE_CORE