src/AwkHandler.h
branchv_0
changeset 20 f937ad57351f
parent 19 e4558df9ba2d
child 21 d46a727b7965
equal deleted inserted replaced
19:e4558df9ba2d 20:f937ad57351f
   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 				}