Added filtered output stream to transform LFs to CRLFs.
This commit is contained in:
parent
ff8827bdd3
commit
462311e382
@ -286,6 +286,77 @@ void CRLFToLFFilteredOutputStream::flush()
|
||||
}
|
||||
|
||||
|
||||
// LFToCRLFFilteredOutputStream
|
||||
|
||||
LFToCRLFFilteredOutputStream::LFToCRLFFilteredOutputStream(outputStream& os)
|
||||
: m_stream(os), m_previousChar('\0')
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
outputStream& LFToCRLFFilteredOutputStream::getNextOutputStream()
|
||||
{
|
||||
return (m_stream);
|
||||
}
|
||||
|
||||
|
||||
void LFToCRLFFilteredOutputStream::write
|
||||
(const value_type* const data, const size_type count)
|
||||
{
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
std::string buffer;
|
||||
buffer.reserve(count);
|
||||
|
||||
const value_type* pos = data;
|
||||
const value_type* end = data + count;
|
||||
|
||||
value_type previousChar = m_previousChar;
|
||||
|
||||
while (pos < end)
|
||||
{
|
||||
switch (*pos)
|
||||
{
|
||||
case '\r':
|
||||
|
||||
buffer.append(1, '\r');
|
||||
buffer.append(1, '\n');
|
||||
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
|
||||
if (previousChar != '\r')
|
||||
{
|
||||
buffer.append(1, '\r');
|
||||
buffer.append(1, '\n');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
buffer.append(1, *pos);
|
||||
break;
|
||||
}
|
||||
|
||||
previousChar = *pos;
|
||||
++pos;
|
||||
}
|
||||
|
||||
m_stream.write(&buffer[0], buffer.length());
|
||||
|
||||
m_previousChar = previousChar;
|
||||
}
|
||||
|
||||
|
||||
void LFToCRLFFilteredOutputStream::flush()
|
||||
{
|
||||
m_stream.flush();
|
||||
}
|
||||
|
||||
|
||||
// stopSequenceFilteredInputStream <1>
|
||||
|
||||
template <>
|
||||
|
@ -53,6 +53,8 @@
|
||||
|
||||
#define VASSERT_EQ(msg, expected, actual) \
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE(std::string(msg), expected, actual)
|
||||
#define VASSERT_NEQ(msg, expected, actual) \
|
||||
CPPUNIT_ASSERT_MESSAGE(std::string(msg), (expected) != (actual))
|
||||
|
||||
#define VASSERT_THROW(msg, expression, exceptionType) \
|
||||
CPPUNIT_ASSERT_THROW(expression, exceptionType)
|
||||
|
@ -35,6 +35,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest)
|
||||
VMIME_TEST(testStopSequenceFilteredInputStream1)
|
||||
VMIME_TEST(testStopSequenceFilteredInputStreamN_2)
|
||||
VMIME_TEST(testStopSequenceFilteredInputStreamN_3)
|
||||
VMIME_TEST(testLFToCRLFFilteredOutputStream_Global)
|
||||
VMIME_TEST(testLFToCRLFFilteredOutputStream_Edge)
|
||||
VMIME_TEST_LIST_END
|
||||
|
||||
|
||||
@ -276,5 +278,43 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest)
|
||||
testStopSequenceFISHelper <3>("24", "xyz", "", "x", "y", "z");
|
||||
}
|
||||
|
||||
|
||||
// LFToCRLFFilteredOutputStream
|
||||
|
||||
void testLFToCRLFFilteredOutputStream_Global()
|
||||
{
|
||||
typedef vmime::utility::LFToCRLFFilteredOutputStream FILTER;
|
||||
|
||||
testFilteredOutputStreamHelper<FILTER>("1", "ABC\r\nDEF", "ABC\nDEF");
|
||||
testFilteredOutputStreamHelper<FILTER>("2", "ABC\r\nDEF", "ABC\rDEF");
|
||||
testFilteredOutputStreamHelper<FILTER>("3", "\r\n\r\nAB\r\n\r\nA\r\nB\r\n", "\n\nAB\n\nA\nB\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("4", "ABCDE\r\nF", "ABCDE\nF");
|
||||
testFilteredOutputStreamHelper<FILTER>("5", "ABCDE\r\nF", "ABCDE\r\nF");
|
||||
testFilteredOutputStreamHelper<FILTER>("6", "\r\n\r\n\r\n", "\n\n\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("7", "\r\n\r\n\r\n", "\r\r\n\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("8", "\r\n\r\n\r\n\r\n", "\r\r\r\r");
|
||||
testFilteredOutputStreamHelper<FILTER>("9", "\r\n\r\n\r\n\r\n", "\n\n\n\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("10", "\r\n\r\n\r\n", "\r\n\n\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("11", "\r\n\r\n\r\n\r\n", "\n\n\n\r\n");
|
||||
}
|
||||
|
||||
void testLFToCRLFFilteredOutputStream_Edge()
|
||||
{
|
||||
typedef vmime::utility::LFToCRLFFilteredOutputStream FILTER;
|
||||
|
||||
testFilteredOutputStreamHelper<FILTER>("1", "\r\n\r\n", "\r", "\r");
|
||||
testFilteredOutputStreamHelper<FILTER>("2", "\r\n\r\n", "\r", "\n\r");
|
||||
testFilteredOutputStreamHelper<FILTER>("3", "ABC\r\n\r\n", "ABC\r", "\n\r");
|
||||
testFilteredOutputStreamHelper<FILTER>("4", "ABC\r\n\r\n\r\n", "ABC\r", "\n\r", "\n\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("5", "\r\n\r\n", "\n", "\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("6", "\r\n\r\n", "\r\n\r\n");
|
||||
testFilteredOutputStreamHelper<FILTER>("7", "\r\n\r\n", "\r\n\r", "\n");
|
||||
|
||||
testFilteredOutputStreamHelper<FILTER>("8", "A\r\nB\r\nC\r\nD", "A\rB", "\nC\r\nD");
|
||||
testFilteredOutputStreamHelper<FILTER>("9", "\r\nA\r\nB\r\nC\r\nD", "\rA\r", "B\nC\r\nD");
|
||||
testFilteredOutputStreamHelper<FILTER>("10", "\r\nA\r\nB\r\nC\r\nD", "\nA\r", "B\nC\r\nD");
|
||||
testFilteredOutputStreamHelper<FILTER>("11", "\r\nA\r\nB\r\nC\r\nD\r\n", "\nA\rB", "\nC\r\nD\r");
|
||||
}
|
||||
|
||||
VMIME_TEST_SUITE_END
|
||||
|
||||
|
@ -155,6 +155,32 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/** A filtered output stream which replaces CR or LF characters
|
||||
* with CRLF sequences.
|
||||
*/
|
||||
|
||||
class LFToCRLFFilteredOutputStream : public filteredOutputStream
|
||||
{
|
||||
public:
|
||||
|
||||
/** Construct a new filter for the specified output stream.
|
||||
*
|
||||
* @param os stream into which write filtered data
|
||||
*/
|
||||
LFToCRLFFilteredOutputStream(outputStream& os);
|
||||
|
||||
outputStream& getNextOutputStream();
|
||||
|
||||
void write(const value_type* const data, const size_type count);
|
||||
void flush();
|
||||
|
||||
private:
|
||||
|
||||
outputStream& m_stream;
|
||||
value_type m_previousChar;
|
||||
};
|
||||
|
||||
|
||||
/** A filtered input stream which stops when a specified sequence
|
||||
* is found (eof() method will return 'true').
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user