56 } |
57 } |
57 |
58 |
58 Message(int code, std::wstring p1, std::wstring p2) : code(code), parameters({p1, p2}) { |
59 Message(int code, std::wstring p1, std::wstring p2) : code(code), parameters({p1, p2}) { |
59 } |
60 } |
60 }; |
61 }; |
|
62 |
|
63 private: |
61 |
64 |
62 static const char SEPARATOR = '\0'; |
65 static const char SEPARATOR = '\0'; |
63 |
66 |
64 int readInt() { |
67 int readInt() { |
65 return std::stoi(readString()); |
68 return std::stoi(readString()); |
89 Message m; |
92 Message m; |
90 m.code = readInt(); |
93 m.code = readInt(); |
91 int count = readInt(); |
94 int count = readInt(); |
92 for (int i = 0; i < count; i++) m.parameters.push_back(readString()); |
95 for (int i = 0; i < count; i++) m.parameters.push_back(readString()); |
93 return m; |
96 return m; |
|
97 } |
|
98 |
|
99 /** |
|
100 * The std::wsmatch contains only references to original string, |
|
101 * so we need to copy it in order to make it persistent and independent from variables that may evaporate. |
|
102 */ |
|
103 void copyMatches(std::wsmatch& source, std::vector<std::wstring>& destination) { |
|
104 for (std::wstring s : source) destination.emplace_back(s); |
94 } |
105 } |
95 |
106 |
96 void processMessages() { |
107 void processMessages() { |
97 while (true) { |
108 while (true) { |
98 Message m = read(); |
109 Message m = read(); |
126 |
137 |
127 class Option { |
138 class Option { |
128 public: |
139 public: |
129 std::wstring name; |
140 std::wstring name; |
130 std::wstring value; |
141 std::wstring value; |
|
142 std::vector<std::wstring> nameMatch; |
|
143 std::vector<std::wstring> valueMatch; |
|
144 |
|
145 Option(std::wstring name, std::wstring value) : name(name), value(value) { |
|
146 } |
131 }; |
147 }; |
132 |
148 |
133 std::vector<std::wstring> versionsSupported; |
149 std::vector<std::wstring> versionsSupported; |
134 std::vector<AttributeMetadata> inputAttributes; |
150 std::vector<AttributeMetadata> inputAttributes; |
135 std::vector<std::wstring> outputAttributeAliases; |
151 std::vector<std::wstring> outputAttributeAliases; |
199 virtual std::wstring getAlias(int index, const std::wstring& defaultValue) { |
215 virtual std::wstring getAlias(int index, const std::wstring& defaultValue) { |
200 if (outputAttributeAliases.size() > index) return outputAttributeAliases[index]; |
216 if (outputAttributeAliases.size() > index) return outputAttributeAliases[index]; |
201 else return defaultValue; |
217 else return defaultValue; |
202 } |
218 } |
203 |
219 |
|
220 virtual std::vector<Option> getOptions(std::wstring name) { |
|
221 std::vector<Option> result; |
|
222 for (Option o : options) if (o.name == name) result.push_back(o); |
|
223 return result; |
|
224 } |
|
225 |
|
226 virtual std::vector<Option> getOptions(std::wregex namePattern) { |
|
227 std::vector<Option> result; |
|
228 std::wsmatch nameMatch; |
|
229 for (Option o : options) if (std::regex_match(o.name, nameMatch, namePattern)) { |
|
230 copyMatches(nameMatch, o.nameMatch); |
|
231 result.push_back(o); |
|
232 } |
|
233 return result; |
|
234 } |
|
235 |
|
236 virtual std::vector<Option> getOptions(std::wregex namePattern, std::wregex valuePattern) { |
|
237 // TODO: support multiple modes: |
|
238 // a) throw an exception if valuePattern does not match |
|
239 // b) return option even if valuePattern does not match (valueMatch will be empty) |
|
240 // c) skip options with value not matching (current behavior) |
|
241 std::wsmatch nameMatch; |
|
242 std::wsmatch valueMatch; |
|
243 std::vector<Option> result; |
|
244 for (Option o : options) if (std::regex_match(o.name, nameMatch, namePattern) && std::regex_match(o.value, valueMatch, valuePattern)) { |
|
245 copyMatches(nameMatch, o.nameMatch); |
|
246 copyMatches(valueMatch, o.valueMatch); |
|
247 result.push_back(o); |
|
248 } |
|
249 return result; |
|
250 } |
|
251 |
204 virtual std::vector<AttributeMetadata> getOutputAttributesMetadata() = 0; |
252 virtual std::vector<AttributeMetadata> getOutputAttributesMetadata() = 0; |
205 virtual std::vector<OutputAttribute> getOutputAttributes() = 0; |
253 virtual std::vector<OutputAttribute> getOutputAttributes() = 0; |
206 |
254 |
207 public: |
255 public: |
208 |
256 |
223 const std::wstring Streamlet::INTEGER = L"integer"; |
275 const std::wstring Streamlet::INTEGER = L"integer"; |
224 const std::wstring Streamlet::STRING = L"string"; |
276 const std::wstring Streamlet::STRING = L"string"; |
225 |
277 |
226 #define STREAMLET_RUN(clazz) \ |
278 #define STREAMLET_RUN(clazz) \ |
227 int main(int argc, char** argv) { \ |
279 int main(int argc, char** argv) { \ |
|
280 setlocale(LC_ALL, ""); \ |
228 clazz s; \ |
281 clazz s; \ |
229 return s.run(); \ |
282 return s.run(); \ |
230 } |
283 } |