diff options
| author | Vincent Richard <[email protected]> | 2005-06-16 00:22:01 +0200 |
|---|---|---|
| committer | Vincent Richard <[email protected]> | 2005-06-16 00:22:01 +0200 |
| commit | 6bf5f9192e2b433c997327a81f2d6c7062278126 (patch) | |
| tree | eb25b79b744d788314b6c01a854c242f26b309ed /src/utility/filteredStream.cpp | |
| parent | Fixed a bug in word parsing. (diff) | |
| download | vmime-6bf5f9192e2b433c997327a81f2d6c7062278126.tar.gz vmime-6bf5f9192e2b433c997327a81f2d6c7062278126.zip | |
Added dotFilteredInputStream + fixed CRLFToLFFilteredOutputStream + added unit tests.
Diffstat (limited to 'src/utility/filteredStream.cpp')
| -rw-r--r-- | src/utility/filteredStream.cpp | 123 |
1 files changed, 120 insertions, 3 deletions
diff --git a/src/utility/filteredStream.cpp b/src/utility/filteredStream.cpp index d55e891e..c198c230 100644 --- a/src/utility/filteredStream.cpp +++ b/src/utility/filteredStream.cpp @@ -21,10 +21,99 @@ #include <algorithm> + namespace vmime { namespace utility { +// dotFilteredInputStream + +dotFilteredInputStream::dotFilteredInputStream(inputStream& is) + : m_stream(is) +{ +} + + +inputStream& dotFilteredInputStream::getPreviousInputStream() +{ + return (m_stream); +} + + +const bool dotFilteredInputStream::eof() const +{ + return (m_stream.eof()); +} + + +void dotFilteredInputStream::reset() +{ + m_previousChar2 = '\0'; + m_previousChar1 = '\0'; + + m_stream.reset(); +} + + +const stream::size_type dotFilteredInputStream::read(value_type* const data, const size_type count) +{ + const stream::size_type read = m_stream.read(data, count); + + const value_type* readPtr = data; + value_type* writePtr = data; + + const value_type* end = data + read; + + stream::size_type written = 0; + + // Replace "\n.." with "\n." + while (readPtr < end) + { + if (*readPtr == '.') + { + const value_type prevChar2 = + (readPtr == data + 1 ? m_previousChar1 : + readPtr == data ? m_previousChar2 : *(readPtr - 2)); + const value_type prevChar1 = + (readPtr == data ? m_previousChar1 : *(readPtr - 1)); + + if (prevChar2 == '\n' && prevChar1 == '.') + { + // Ignore last dot + } + else + { + *writePtr = *readPtr; + + ++writePtr; + ++written; + } + } + else + { + *writePtr = *readPtr; + + ++writePtr; + ++written; + } + + ++readPtr; + } + + m_previousChar2 = (read >= 2 ? data[read - 2] : m_previousChar1); + m_previousChar1 = (read >= 1 ? data[read - 1] : '\0'); + + return (written); +} + + +const stream::size_type dotFilteredInputStream::skip(const size_type /* count */) +{ + // Skipping bytes is not supported + return 0; +} + + // dotFilteredOutputStream dotFilteredOutputStream::dotFilteredOutputStream(outputStream& os) @@ -42,6 +131,9 @@ outputStream& dotFilteredOutputStream::getNextOutputStream() void dotFilteredOutputStream::write (const value_type* const data, const size_type count) { + if (count == 0) + return; + const value_type* pos = data; const value_type* end = data + count; const value_type* start = data; @@ -85,10 +177,25 @@ outputStream& CRLFToLFFilteredOutputStream::getNextOutputStream() void CRLFToLFFilteredOutputStream::write (const value_type* const data, const size_type count) { + if (count == 0) + return; + const value_type* pos = data; const value_type* end = data + count; const value_type* start = data; + // Warning: if the whole buffer finishes with '\r', this + // last character will not be written back... + // TODO: add a finalize() method? + if (m_previousChar == '\r') + { + if (*pos != '\n') + { + m_stream.write("\r", 1); // write back \r + m_previousChar = *pos; + } + } + // Replace "\r\n" (CRLF) with "\n" (LF) while ((pos = std::find(pos, end, '\n')) != end) { @@ -97,7 +204,9 @@ void CRLFToLFFilteredOutputStream::write if (previousChar == '\r') { - m_stream.write(start, pos - 1 - data); // do not write \r + if (pos != data) + m_stream.write(start, pos - 1 - data); // do not write \r + m_stream.write("\n", 1); start = pos + 1; @@ -106,8 +215,16 @@ void CRLFToLFFilteredOutputStream::write ++pos; } - m_stream.write(start, end - start); - m_previousChar = data[count - 1]; + if (data[count - 1] == '\r') + { + m_stream.write(start, end - start - 1); + m_previousChar = '\r'; + } + else + { + m_stream.write(start, end - start); + m_previousChar = data[count - 1]; + } } |
