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>
|
// stopSequenceFilteredInputStream <1>
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -53,6 +53,8 @@
|
|||||||
|
|
||||||
#define VASSERT_EQ(msg, expected, actual) \
|
#define VASSERT_EQ(msg, expected, actual) \
|
||||||
CPPUNIT_ASSERT_EQUAL_MESSAGE(std::string(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) \
|
#define VASSERT_THROW(msg, expression, exceptionType) \
|
||||||
CPPUNIT_ASSERT_THROW(expression, exceptionType)
|
CPPUNIT_ASSERT_THROW(expression, exceptionType)
|
||||||
|
@ -35,6 +35,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest)
|
|||||||
VMIME_TEST(testStopSequenceFilteredInputStream1)
|
VMIME_TEST(testStopSequenceFilteredInputStream1)
|
||||||
VMIME_TEST(testStopSequenceFilteredInputStreamN_2)
|
VMIME_TEST(testStopSequenceFilteredInputStreamN_2)
|
||||||
VMIME_TEST(testStopSequenceFilteredInputStreamN_3)
|
VMIME_TEST(testStopSequenceFilteredInputStreamN_3)
|
||||||
|
VMIME_TEST(testLFToCRLFFilteredOutputStream_Global)
|
||||||
|
VMIME_TEST(testLFToCRLFFilteredOutputStream_Edge)
|
||||||
VMIME_TEST_LIST_END
|
VMIME_TEST_LIST_END
|
||||||
|
|
||||||
|
|
||||||
@ -276,5 +278,43 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest)
|
|||||||
testStopSequenceFISHelper <3>("24", "xyz", "", "x", "y", "z");
|
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
|
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
|
/** A filtered input stream which stops when a specified sequence
|
||||||
* is found (eof() method will return 'true').
|
* is found (eof() method will return 'true').
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user