154 string_t escapeAwkValue(const string_t& value) { |
154 string_t escapeAwkValue(const string_t& value) { |
155 // FIXME: escape field and record separators |
155 // FIXME: escape field and record separators |
156 return value; |
156 return value; |
157 } |
157 } |
158 |
158 |
|
159 void processAwkOutput(int awkOutputReaderFD) { |
|
160 locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else? |
|
161 |
|
162 __gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in); |
|
163 std::wistream awkOutputReader(&awkOutputReaderBuffer); |
|
164 |
|
165 if (currentRelationConfiguration->drop) { |
|
166 for (wchar_t ch; awkOutputReader.read(&ch, 1).good();); // just eat the lines from the AWK |
|
167 } else { |
|
168 std::wstringstream currentValue; |
|
169 for (wchar_t ch; awkOutputReader.read(&ch, 1).good();) { |
|
170 if (ch == '\t' || ch == '\n') { |
|
171 relationalWriter->writeAttribute(currentValue.str()); |
|
172 currentValue.str(L""); |
|
173 currentValue.clear(); |
|
174 } else if (ch == '\\') { |
|
175 ch = awkOutputReader.get(); |
|
176 if (ch == 't') currentValue << L'\t'; |
|
177 else if (ch == 'n') currentValue << L'\n'; |
|
178 else if (ch == '\\') currentValue << L'\\'; |
|
179 else throw cli::RelpipeCLIException(L"Unknown escape sequence. Only \\t, \\n and \\\\ are supported.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
|
180 } else { |
|
181 currentValue << ch; |
|
182 } |
|
183 } |
|
184 } |
|
185 |
|
186 closeOrThrow(awkOutputReaderFD); |
|
187 } |
|
188 |
159 public: |
189 public: |
160 |
190 |
161 /** |
191 /** |
162 * @param relationalWriter |
192 * @param relationalWriter |
163 * @param relationalWriterFlush the writer must be flushed before fork() in order to |
193 * @param relationalWriterFlush the writer must be flushed before fork() in order to |
255 throw cli::RelpipeCLIException(L"Unable to fork Writer process.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
285 throw cli::RelpipeCLIException(L"Unable to fork Writer process.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
256 } else if (writerPid == 0) { |
286 } else if (writerPid == 0) { |
257 // Writer child process |
287 // Writer child process |
258 closeOrThrow(awkInputWriterFD); |
288 closeOrThrow(awkInputWriterFD); |
259 |
289 |
260 locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else? |
|
261 |
|
262 __gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in); |
|
263 std::wistream awkOutputReader(&awkOutputReaderBuffer); |
|
264 |
|
265 if (currentRelationConfiguration->drop) { |
290 if (currentRelationConfiguration->drop) { |
266 // TODO: omit whole this process and pipe AWK output to /dev/null? |
291 // TODO: omit whole this process and pipe AWK output to /dev/null? |
267 } else { |
292 } else { |
268 // FIXME: currentWriterMetadata |
293 // FIXME: currentWriterMetadata |
269 relationalWriter->startRelation(name,{ |
294 relationalWriter->startRelation(name,{ |
270 {L"message", writer::TypeId::STRING}, |
295 {L"message", writer::TypeId::STRING}, |
271 }, true); |
296 }, true); |
272 } |
297 } |
273 |
298 |
274 for (string_t line; getline(awkOutputReader, line).good();) { |
299 processAwkOutput(awkOutputReaderFD); |
275 if (currentRelationConfiguration->drop) { |
|
276 // just eat the lines from the AWK |
|
277 } else { |
|
278 relationalWriter->writeAttribute(line); |
|
279 } |
|
280 } |
|
281 |
|
282 closeOrThrow(awkOutputReaderFD); |
|
283 exit(0); |
300 exit(0); |
284 } else { |
301 } else { |
285 // Parent process |
302 // Parent process |
286 closeOrThrow(awkOutputReaderFD); |
303 closeOrThrow(awkOutputReaderFD); |
287 } |
304 } |