From 9619c359c13908bd560a37946c780b3eb516fd10 Mon Sep 17 00:00:00 2001 From: zimoch Date: Tue, 7 Dec 2010 10:07:58 +0000 Subject: [PATCH] separator pre-parsing did not work as expected. Problems with whitespace separators. Back to old soluton --- src/StreamCore.cc | 113 ++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 84 deletions(-) diff --git a/src/StreamCore.cc b/src/StreamCore.cc index fe8fa90..1148752 100644 --- a/src/StreamCore.cc +++ b/src/StreamCore.cc @@ -722,7 +722,8 @@ printSeparator() long i = 0; for (; i < separator.length(); i++) { - if (separator[i] == StreamProtocolParser::skip) continue; // wildcard + if (separator[i] == StreamProtocolParser::skip || + separator[i] == StreamProtocolParser::whitespace) continue; // wildcards if (separator[i] == esc) i++; // escaped literal byte outputLine.append(separator[i]); } @@ -1299,7 +1300,7 @@ matchInput() // ignore next input byte consumedInput++; break; - case ' ': + case StreamProtocolParser::whitespace: // any number of whitespace (including 0) while (isspace(inputLine[consumedInput])) consumedInput++; break; @@ -1378,96 +1379,43 @@ matchSeparator() { // called before value is read, first value has Separator flag cleared // for second and next value set Separator flag - // first skip over leading separator (all but first value) - // then find next separator and terminate with null byte to - // help parsing one value (e.g. %s) if (!separator) { - separatorStart = -1; + // empty separator matches return true; } - if (flags & Separator) - { - // not first element in array: expect to be at the separator - - if (separatorStart == -1) { - return false; // no separator found - } - if (separator[0] == ' ' && separator.length() == 1 - && consumedInput != separatorStart) - { - // space-only separator may have matched zero spaces - // last found separator is still ahead - inputLine[separatorStart] = '\0'; - return true; - } - - if (consumedInput != separatorStart) - { - long i = separatorStart - consumedInput; - error("%s: %ld byte%s input left before separator: \"%s%s\" after \"%s%s\"\n", - name(), i, i != 1 ? "s" : "", - inputLine.expand(consumedInput, i > 20 ? 20 : i)(), - i > 20 ? "..." : "", - consumedInput > 20 ? "..." : "", - inputLine.expand(consumedInput, -20)()); - return false; - } - consumedInput = separatorEnd; - } - else + if (!(flags & Separator)) { + // before first element, don't expect separator yet flags |= Separator; + return true; } - - // find next Separator and replace first byte with '\0' to help parsing elements - // don't worry now if there is none, just set separatorStart = -1 - if (separator[0] == ' ' && separator.length() == 1) + long i; + long j = consumedInput; + for (i = 0; i < separator.length(); i++) { - // space-only separator: find any whitespace after non-whitespace - long j = consumedInput; - while (isspace(inputLine[j])) j++; - if (!inputLine[j]) { - separatorStart = -1; - return true; - } - while (inputLine[j] && !isspace(inputLine[j])) j++; - separatorStart = j; - while (isspace(inputLine[j])) j++; - separatorEnd = j; - } - else - { - long i = 0; - if (separator[0] == ' ' && separator[1] != ' ') - i = 1; // handle leading whitespaces later - separatorStart = inputLine.find(separator[i], consumedInput); - if (separatorStart == -1) return true; - - // check rest of separator and handle escapes - long j; - for (j = separatorStart+1; ++i < separator.length(); j++) + switch (separator[i]) { - if (separator[i] == StreamProtocolParser::skip) continue; // wildcard - // allow format here? - if (separator[i] == esc) i++; // escaped literal byte - if (separator[i] != inputLine[j]) - { - separatorStart = -1; - return true; - } - } - separatorEnd = j; - // separator found - if (separator[0] == ' ' && separator[1] != ' ') - { - // now skip leading whitespaces - while (separatorStart > consumedInput && - isspace(inputLine[separatorStart - 1])) separatorStart--; + case StreamProtocolParser::skip: + j++; + continue; + case StreamProtocolParser::whitespace: + while (isspace(inputLine[j])) j++; + continue; + case esc: + i++; + default: + if (separator[i] != inputLine[j]) + { + // no match + // don't complain here, just return false + return false; + } + j++; } } - separatorStore = inputLine[separatorStart]; - inputLine[separatorStart] = '\0'; + // separator successfully read + consumedInput = j; return true; } @@ -1484,7 +1432,6 @@ scanValue(const StreamFormat& fmt, long& value) if (!matchSeparator()) return -1; long consumed = StreamFormatConverter::find(fmt.conv)-> scanLong(fmt, inputLine(consumedInput), value); - if (separatorStart >= 0) inputLine[separatorStart] = separatorStore; debug("StreamCore::scanValue(%s, format=%%%c, long) input=\"%s\"\n", name(), fmt.conv, inputLine.expand(consumedInput)()); if (consumed < 0) @@ -1516,7 +1463,6 @@ scanValue(const StreamFormat& fmt, double& value) if (!matchSeparator()) return -1; long consumed = StreamFormatConverter::find(fmt.conv)-> scanDouble(fmt, inputLine(consumedInput), value); - if (separatorStart >= 0) inputLine[separatorStart] = separatorStore; debug("StreamCore::scanValue(%s, format=%%%c, double) input=\"%s\"\n", name(), fmt.conv, inputLine.expand(consumedInput, 20)()); if (consumed < 0) @@ -1549,7 +1495,6 @@ scanValue(const StreamFormat& fmt, char* value, long maxlen) if (!matchSeparator()) return -1; long consumed = StreamFormatConverter::find(fmt.conv)-> scanString(fmt, inputLine(consumedInput), value, maxlen); - if (separatorStart >= 0) inputLine[separatorStart] = separatorStore; debug("StreamCore::scanValue(%s, format=%%%c, char*, maxlen=%ld) input=\"%s\"\n", name(), fmt.conv, maxlen, inputLine.expand(consumedInput)()); if (consumed < 0)