read and un-escape the AWK output, convert to relational attributes v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 07 May 2019 22:21:56 +0200
branchv_0
changeset 20 f937ad57351f
parent 19 e4558df9ba2d
child 21 d46a727b7965
read and un-escape the AWK output, convert to relational attributes
src/AwkHandler.h
--- a/src/AwkHandler.h	Tue May 07 21:33:59 2019 +0200
+++ b/src/AwkHandler.h	Tue May 07 22:21:56 2019 +0200
@@ -156,6 +156,36 @@
 		return value;
 	}
 
+	void processAwkOutput(int awkOutputReaderFD) {
+		locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else?
+
+		__gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in);
+		std::wistream awkOutputReader(&awkOutputReaderBuffer);
+
+		if (currentRelationConfiguration->drop) {
+			for (wchar_t ch; awkOutputReader.read(&ch, 1).good();); // just eat the lines from the AWK
+		} else {
+			std::wstringstream currentValue;
+			for (wchar_t ch; awkOutputReader.read(&ch, 1).good();) {
+				if (ch == '\t' || ch == '\n') {
+					relationalWriter->writeAttribute(currentValue.str());
+					currentValue.str(L"");
+					currentValue.clear();
+				} else if (ch == '\\') {
+					ch = awkOutputReader.get();
+					if (ch == 't') currentValue << L'\t';
+					else if (ch == 'n') currentValue << L'\n';
+					else if (ch == '\\') currentValue << L'\\';
+					else throw cli::RelpipeCLIException(L"Unknown escape sequence. Only \\t, \\n and \\\\ are supported.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
+				} else {
+					currentValue << ch;
+				}
+			}
+		}
+
+		closeOrThrow(awkOutputReaderFD);
+	}
+
 public:
 
 	/**
@@ -257,11 +287,6 @@
 					// Writer child process
 					closeOrThrow(awkInputWriterFD);
 
-					locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else?
-
-					__gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in);
-					std::wistream awkOutputReader(&awkOutputReaderBuffer);
-
 					if (currentRelationConfiguration->drop) {
 						// TODO: omit whole this process and pipe AWK output to /dev/null?
 					} else {
@@ -271,15 +296,7 @@
 						}, true);
 					}
 
-					for (string_t line; getline(awkOutputReader, line).good();) {
-						if (currentRelationConfiguration->drop) {
-							// just eat the lines from the AWK
-						} else {
-							relationalWriter->writeAttribute(line);
-						}
-					}
-
-					closeOrThrow(awkOutputReaderFD);
+					processAwkOutput(awkOutputReaderFD);
 					exit(0);
 				} else {
 					// Parent process