Added ability to parse directly from an input stream (eg. file). This allows very big messages to be parsed without loading the whole message data into memory.
This commit is contained in:
parent
cc49395dd2
commit
4f33877820
@ -2,6 +2,12 @@
|
|||||||
VERSION 0.9.2svn
|
VERSION 0.9.2svn
|
||||||
================
|
================
|
||||||
|
|
||||||
|
2012-04-16 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
|
||||||
|
* MIME Parser can now operate directly on an input stream (eg. file).
|
||||||
|
This allows very big messages to be parsed without loading the whole
|
||||||
|
message data into memory.
|
||||||
|
|
||||||
2010-11-16 Vincent Richard <vincent@vincent-richard.net>
|
2010-11-16 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
|
||||||
* Started version 0.9.2.
|
* Started version 0.9.2.
|
||||||
|
@ -153,11 +153,14 @@ libvmime_sources = [
|
|||||||
'utility/inputStreamSocketAdapter.cpp', 'utility/inputStreamSocketAdapter.hpp',
|
'utility/inputStreamSocketAdapter.cpp', 'utility/inputStreamSocketAdapter.hpp',
|
||||||
'utility/inputStreamStringAdapter.cpp', 'utility/inputStreamStringAdapter.hpp',
|
'utility/inputStreamStringAdapter.cpp', 'utility/inputStreamStringAdapter.hpp',
|
||||||
'utility/inputStreamStringProxyAdapter.cpp', 'utility/inputStreamStringProxyAdapter.hpp',
|
'utility/inputStreamStringProxyAdapter.cpp', 'utility/inputStreamStringProxyAdapter.hpp',
|
||||||
|
'utility/seekableInputStream.hpp',
|
||||||
|
'utility/seekableInputStreamRegionAdapter.cpp', 'utility/seekableInputStreamRegionAdapter.hpp',
|
||||||
'utility/outputStream.cpp', 'utility/outputStream.hpp',
|
'utility/outputStream.cpp', 'utility/outputStream.hpp',
|
||||||
'utility/outputStreamAdapter.cpp', 'utility/outputStreamAdapter.hpp',
|
'utility/outputStreamAdapter.cpp', 'utility/outputStreamAdapter.hpp',
|
||||||
'utility/outputStreamByteArrayAdapter.cpp', 'utility/outputStreamByteArrayAdapter.hpp',
|
'utility/outputStreamByteArrayAdapter.cpp', 'utility/outputStreamByteArrayAdapter.hpp',
|
||||||
'utility/outputStreamSocketAdapter.cpp', 'utility/outputStreamSocketAdapter.hpp',
|
'utility/outputStreamSocketAdapter.cpp', 'utility/outputStreamSocketAdapter.hpp',
|
||||||
'utility/outputStreamStringAdapter.cpp', 'utility/outputStreamStringAdapter.hpp',
|
'utility/outputStreamStringAdapter.cpp', 'utility/outputStreamStringAdapter.hpp',
|
||||||
|
'utility/parserInputStreamAdapter.cpp', 'utility/parserInputStreamAdapter.hpp',
|
||||||
'utility/stringProxy.cpp', 'utility/stringProxy.hpp',
|
'utility/stringProxy.cpp', 'utility/stringProxy.hpp',
|
||||||
'utility/stringUtils.cpp', 'utility/stringUtils.hpp',
|
'utility/stringUtils.cpp', 'utility/stringUtils.hpp',
|
||||||
'utility/url.cpp', 'utility/url.hpp',
|
'utility/url.cpp', 'utility/url.hpp',
|
||||||
|
@ -50,7 +50,7 @@ addressList::~addressList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::parse(const string& buffer, const string::size_type position,
|
void addressList::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
removeAllAddresses();
|
removeAllAddresses();
|
||||||
@ -72,7 +72,7 @@ void addressList::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void addressList::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
string::size_type pos = curLinePos;
|
string::size_type pos = curLinePos;
|
||||||
@ -248,9 +248,9 @@ const std::vector <ref <address> > addressList::getAddressList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > addressList::getChildComponents() const
|
const std::vector <ref <component> > addressList::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
copy_vector(m_list, list);
|
copy_vector(m_list, list);
|
||||||
|
|
||||||
|
224
src/body.cpp
224
src/body.cpp
@ -31,10 +31,13 @@
|
|||||||
|
|
||||||
#include "vmime/utility/random.hpp"
|
#include "vmime/utility/random.hpp"
|
||||||
|
|
||||||
|
#include "vmime/utility/seekableInputStreamRegionAdapter.hpp"
|
||||||
|
|
||||||
#include "vmime/parserHelpers.hpp"
|
#include "vmime/parserHelpers.hpp"
|
||||||
|
|
||||||
#include "vmime/emptyContentHandler.hpp"
|
#include "vmime/emptyContentHandler.hpp"
|
||||||
#include "vmime/stringContentHandler.hpp"
|
#include "vmime/stringContentHandler.hpp"
|
||||||
|
#include "vmime/streamContentHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -52,11 +55,28 @@ body::~body()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void body::parse(const string& buffer, const string::size_type position,
|
void body::parseImpl
|
||||||
const string::size_type end, string::size_type* newPosition)
|
(ref <utility::parserInputStreamAdapter> parser,
|
||||||
|
const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end,
|
||||||
|
utility::stream::size_type* newPosition)
|
||||||
{
|
{
|
||||||
removeAllParts();
|
removeAllParts();
|
||||||
|
|
||||||
|
m_prologText.clear();
|
||||||
|
m_epilogText.clear();
|
||||||
|
|
||||||
|
if (end == position)
|
||||||
|
{
|
||||||
|
|
||||||
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
|
if (newPosition)
|
||||||
|
*newPosition = end;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether the body is a MIME-multipart
|
// Check whether the body is a MIME-multipart
|
||||||
bool isMultipart = false;
|
bool isMultipart = false;
|
||||||
string boundary;
|
string boundary;
|
||||||
@ -80,37 +100,61 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
{
|
{
|
||||||
// No "boundary" parameter specified: we can try to
|
// No "boundary" parameter specified: we can try to
|
||||||
// guess it by scanning the body contents...
|
// guess it by scanning the body contents...
|
||||||
string::size_type pos = buffer.find("\n--", position);
|
utility::stream::size_type pos = position;
|
||||||
|
|
||||||
if ((pos != string::npos) && (pos < end))
|
parser->seek(pos);
|
||||||
|
|
||||||
|
if (pos + 2 < end && parser->matchBytes("--", 2))
|
||||||
{
|
{
|
||||||
pos += 3;
|
pos += 2;
|
||||||
|
}
|
||||||
const string::size_type start = pos;
|
else
|
||||||
|
|
||||||
char_t c = buffer[pos];
|
|
||||||
string::size_type length = 0;
|
|
||||||
|
|
||||||
// We have to stop after a reasonnably long boundary length (100)
|
|
||||||
// not to take the whole body contents for a boundary...
|
|
||||||
while (pos < end && length < 100 && !(c == '\r' || c == '\n'))
|
|
||||||
{
|
{
|
||||||
++length;
|
pos = parser->findNext("\n--", position);
|
||||||
c = buffer[pos++];
|
|
||||||
|
if ((pos != utility::stream::npos) && (pos + 3 < end))
|
||||||
|
pos += 3; // skip \n--
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos < end && length < 100)
|
if ((pos != utility::stream::npos) && (pos < end))
|
||||||
|
{
|
||||||
|
parser->seek(pos);
|
||||||
|
|
||||||
|
// Read some bytes after boundary separator
|
||||||
|
utility::stream::value_type buffer[256];
|
||||||
|
const utility::stream::size_type bufferLen =
|
||||||
|
parser->read(buffer, std::min(end - pos, sizeof(buffer) / sizeof(buffer[0])));
|
||||||
|
|
||||||
|
buffer[sizeof(buffer) / sizeof(buffer[0]) - 1] = '\0';
|
||||||
|
|
||||||
|
// Extract boundary from buffer (stop at first CR or LF).
|
||||||
|
// We have to stop after a reasonnably long boundary length (100)
|
||||||
|
// not to take the whole body contents for a boundary...
|
||||||
|
string::value_type boundaryBytes[100];
|
||||||
|
string::size_type boundaryLen = 0;
|
||||||
|
|
||||||
|
for (string::value_type c = buffer[0] ;
|
||||||
|
boundaryLen < bufferLen && boundaryLen < 100 && !(c == '\r' || c == '\n') ;
|
||||||
|
c = buffer[++boundaryLen])
|
||||||
|
{
|
||||||
|
boundaryBytes[boundaryLen] = buffer[boundaryLen];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boundaryLen >= 1 && boundaryLen < 100)
|
||||||
{
|
{
|
||||||
// RFC #1521, Page 31:
|
// RFC #1521, Page 31:
|
||||||
// "...the boundary parameter, which consists of 1 to 70
|
// "...the boundary parameter, which consists of 1 to 70
|
||||||
// characters from a set of characters known to be very
|
// characters from a set of characters known to be very
|
||||||
// robust through email gateways, and NOT ending with
|
// robust through email gateways, and NOT ending with
|
||||||
// white space..."
|
// white space..."
|
||||||
while (pos != start && parserHelpers::isSpace(buffer[pos - 1]))
|
while (boundaryLen != 0 &&
|
||||||
--pos;
|
parserHelpers::isSpace(boundaryBytes[boundaryLen - 1]))
|
||||||
|
{
|
||||||
|
boundaryLen--;
|
||||||
|
}
|
||||||
|
|
||||||
boundary = string(buffer.begin() + start,
|
if (boundaryLen >= 1)
|
||||||
buffer.begin() + pos);
|
boundary = string(boundaryBytes, boundaryBytes + boundaryLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,51 +170,79 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
{
|
{
|
||||||
const string boundarySep("--" + boundary);
|
const string boundarySep("--" + boundary);
|
||||||
|
|
||||||
string::size_type partStart = position;
|
utility::stream::size_type partStart = position;
|
||||||
string::size_type pos = position;
|
utility::stream::size_type pos = position;
|
||||||
|
|
||||||
bool lastPart = false;
|
bool lastPart = false;
|
||||||
|
|
||||||
while (pos != string::npos && pos < end)
|
while (pos != utility::stream::npos && pos < end)
|
||||||
{
|
{
|
||||||
pos = buffer.find(boundarySep, pos);
|
pos = parser->findNext(boundarySep, pos);
|
||||||
|
|
||||||
if (pos == string::npos ||
|
if (pos == utility::stream::npos)
|
||||||
((pos == 0 || buffer[pos - 1] == '\n') &&
|
break; // not found
|
||||||
(buffer[pos + boundarySep.length()] == '\r' ||
|
|
||||||
buffer[pos + boundarySep.length()] == '\n' ||
|
if (pos != 0)
|
||||||
buffer[pos + boundarySep.length()] == '-'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
break;
|
parser->seek(pos - 1);
|
||||||
|
|
||||||
|
if (parser->peekByte() != '\n')
|
||||||
|
{
|
||||||
|
// Boundary is not at a beginning of a line
|
||||||
|
pos++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// boundary not a beginning of line, or just a prefix of another, continue the search.
|
parser->skip(1 + boundarySep.length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser->seek(pos + boundarySep.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
const utility::stream::value_type next = parser->peekByte();
|
||||||
|
|
||||||
|
if (next == '\r' || next == '\n' || next == '-')
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Boundary is a prefix of another, continue the search
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos != string::npos && pos < end)
|
if (pos != utility::stream::npos && pos < end)
|
||||||
{
|
{
|
||||||
vmime::text text;
|
vmime::text text;
|
||||||
text.parse(buffer, position, pos);
|
text.parse(parser, position, pos);
|
||||||
|
|
||||||
m_prologText = text.getWholeBuffer();
|
m_prologText = text.getWholeBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0 ; !lastPart && (pos != string::npos) && (pos < end) ; ++index)
|
for (int index = 0 ; !lastPart && (pos != utility::stream::npos) && (pos < end) ; ++index)
|
||||||
{
|
{
|
||||||
string::size_type partEnd = pos;
|
utility::stream::size_type partEnd = pos;
|
||||||
|
|
||||||
// Get rid of the [CR]LF just before the boundary string
|
// Get rid of the [CR]LF just before the boundary string
|
||||||
if (pos >= (position + 1) && buffer[pos - 1] == '\n') --partEnd;
|
if (pos >= (position + 1))
|
||||||
if (pos >= (position + 2) && buffer[pos - 2] == '\r') --partEnd;
|
{
|
||||||
|
parser->seek(pos - 1);
|
||||||
|
|
||||||
|
if (parser->peekByte() == '\n')
|
||||||
|
--partEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos >= (position + 2))
|
||||||
|
{
|
||||||
|
parser->seek(pos - 2);
|
||||||
|
|
||||||
|
if (parser->peekByte() == '\r')
|
||||||
|
--partEnd;
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether it is the last part (boundary terminated by "--")
|
// Check whether it is the last part (boundary terminated by "--")
|
||||||
pos += boundarySep.length();
|
pos += boundarySep.length();
|
||||||
|
parser->seek(pos);
|
||||||
|
|
||||||
if (pos + 1 < end && buffer[pos] == '-' && buffer[pos + 1] == '-')
|
if (pos + 1 < end && parser->matchBytes("--", 2))
|
||||||
{
|
{
|
||||||
lastPart = true;
|
lastPart = true;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
@ -180,15 +252,15 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
// "...(If a boundary appears to end with white space, the
|
// "...(If a boundary appears to end with white space, the
|
||||||
// white space must be presumed to have been added by a
|
// white space must be presumed to have been added by a
|
||||||
// gateway, and must be deleted.)..."
|
// gateway, and must be deleted.)..."
|
||||||
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t'))
|
parser->seek(pos);
|
||||||
++pos;
|
pos += parser->skipIf(parserHelpers::isSpaceOrTab, end);
|
||||||
|
|
||||||
// End of boundary line
|
// End of boundary line
|
||||||
if (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] =='\n')
|
if (pos + 1 < end && parser->matchBytes("\r\n", 2))
|
||||||
{
|
{
|
||||||
pos += 2;
|
pos += 2;
|
||||||
}
|
}
|
||||||
else if (pos < end && buffer[pos] == '\n')
|
else if (pos < end && parser->peekByte() == '\n')
|
||||||
{
|
{
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
@ -202,7 +274,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
if (partEnd < partStart)
|
if (partEnd < partStart)
|
||||||
std::swap(partStart, partEnd);
|
std::swap(partStart, partEnd);
|
||||||
|
|
||||||
part->parse(buffer, partStart, partEnd, NULL);
|
part->parse(parser, partStart, partEnd, NULL);
|
||||||
part->m_parent = m_part;
|
part->m_parent = m_part;
|
||||||
|
|
||||||
m_parts.push_back(part);
|
m_parts.push_back(part);
|
||||||
@ -210,23 +282,37 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
|
|
||||||
partStart = pos;
|
partStart = pos;
|
||||||
|
|
||||||
while (pos != string::npos && pos < end)
|
while (pos != utility::stream::npos && pos < end)
|
||||||
{
|
{
|
||||||
pos = buffer.find(boundarySep, pos);
|
pos = parser->findNext(boundarySep, pos);
|
||||||
|
|
||||||
if (pos == string::npos ||
|
if (pos == utility::stream::npos)
|
||||||
((pos == 0 || buffer[pos - 1] == '\n') &&
|
break; // not found
|
||||||
(buffer[pos + boundarySep.length()] == '\r' ||
|
|
||||||
buffer[pos + boundarySep.length()] == '\n' ||
|
if (pos != 0)
|
||||||
buffer[pos + boundarySep.length()] == '-'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
break;
|
parser->seek(pos - 1);
|
||||||
|
|
||||||
|
if (parser->peekByte() != '\n')
|
||||||
|
{
|
||||||
|
// Boundary is not at a beginning of a line
|
||||||
|
pos++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// boundary not a beginning of line, or just a prefix of another, continue the search.
|
parser->skip(1 + boundarySep.length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parser->seek(pos + boundarySep.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
const utility::stream::value_type next = parser->peekByte();
|
||||||
|
|
||||||
|
if (next == '\r' || next == '\n' || next == '-')
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Boundary is a prefix of another, continue the search
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,13 +320,13 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
m_contents = vmime::create <emptyContentHandler>();
|
m_contents = vmime::create <emptyContentHandler>();
|
||||||
|
|
||||||
// Last part was not found: recover from missing boundary
|
// Last part was not found: recover from missing boundary
|
||||||
if (!lastPart && pos == string::npos)
|
if (!lastPart && pos == utility::stream::npos)
|
||||||
{
|
{
|
||||||
ref <bodyPart> part = vmime::create <bodyPart>();
|
ref <bodyPart> part = vmime::create <bodyPart>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
part->parse(buffer, partStart, end);
|
part->parse(parser, partStart, end);
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{
|
{
|
||||||
@ -255,7 +341,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
else if (partStart < end)
|
else if (partStart < end)
|
||||||
{
|
{
|
||||||
vmime::text text;
|
vmime::text text;
|
||||||
text.parse(buffer, partStart, end);
|
text.parse(parser, partStart, end);
|
||||||
|
|
||||||
m_epilogText = text.getWholeBuffer();
|
m_epilogText = text.getWholeBuffer();
|
||||||
}
|
}
|
||||||
@ -282,7 +368,13 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract the (encoded) contents
|
// Extract the (encoded) contents
|
||||||
m_contents = vmime::create <stringContentHandler>(buffer, position, end, enc);
|
const utility::stream::size_type length = end - position;
|
||||||
|
|
||||||
|
ref <utility::inputStream> contentStream =
|
||||||
|
vmime::create <utility::seekableInputStreamRegionAdapter>
|
||||||
|
(parser->getUnderlyingStream(), position, length);
|
||||||
|
|
||||||
|
m_contents = vmime::create <streamContentHandler>(contentStream, length, enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
@ -292,7 +384,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void body::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void body::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
// MIME-Multipart
|
// MIME-Multipart
|
||||||
@ -862,9 +954,9 @@ const std::vector <ref <bodyPart> > body::getPartList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > body::getChildComponents() const
|
const std::vector <ref <component> > body::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
copy_vector(m_parts, list);
|
copy_vector(m_parts, list);
|
||||||
|
|
||||||
|
@ -46,15 +46,18 @@ bodyPart::bodyPart(weak_ref <vmime::bodyPart> parentPart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::parse(const string& buffer, const string::size_type position,
|
void bodyPart::parseImpl
|
||||||
const string::size_type end, string::size_type* newPosition)
|
(ref <utility::parserInputStreamAdapter> parser,
|
||||||
|
const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end,
|
||||||
|
utility::stream::size_type* newPosition)
|
||||||
{
|
{
|
||||||
// Parse the headers
|
// Parse the headers
|
||||||
string::size_type pos = position;
|
string::size_type pos = position;
|
||||||
m_header->parse(buffer, pos, end, &pos);
|
m_header->parse(parser, pos, end, &pos);
|
||||||
|
|
||||||
// Parse the body contents
|
// Parse the body contents
|
||||||
m_body->parse(buffer, pos, end, NULL);
|
m_body->parse(parser, pos, end, NULL);
|
||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
@ -63,7 +66,7 @@ void bodyPart::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void bodyPart::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
m_header->generate(os, maxLineLength);
|
m_header->generate(os, maxLineLength);
|
||||||
@ -142,9 +145,9 @@ ref <const bodyPart> bodyPart::getParentPart() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > bodyPart::getChildComponents() const
|
const std::vector <ref <component> > bodyPart::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
list.push_back(m_header);
|
list.push_back(m_header);
|
||||||
list.push_back(m_body);
|
list.push_back(m_body);
|
||||||
|
@ -57,7 +57,7 @@ charset::charset(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::parse(const string& buffer, const string::size_type position,
|
void charset::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_name = utility::stringUtils::trim
|
m_name = utility::stringUtils::trim
|
||||||
@ -74,7 +74,7 @@ void charset::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
void charset::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
os << m_name;
|
os << m_name;
|
||||||
@ -142,9 +142,9 @@ void charset::copyFrom(const component& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > charset::getChildComponents() const
|
const std::vector <ref <component> > charset::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
|
|
||||||
#include "vmime/component.hpp"
|
#include "vmime/component.hpp"
|
||||||
#include "vmime/base.hpp"
|
#include "vmime/base.hpp"
|
||||||
|
|
||||||
|
#include "vmime/utility/streamUtils.hpp"
|
||||||
|
#include "vmime/utility/inputStreamStringAdapter.hpp"
|
||||||
#include "vmime/utility/outputStreamAdapter.hpp"
|
#include "vmime/utility/outputStreamAdapter.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -43,9 +46,102 @@ component::~component()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::parse
|
||||||
|
(ref <utility::inputStream> inputStream, const utility::stream::size_type length)
|
||||||
|
{
|
||||||
|
parse(inputStream, 0, length, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::parse
|
||||||
|
(ref <utility::inputStream> inputStream, const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end, utility::stream::size_type* newPosition)
|
||||||
|
{
|
||||||
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
|
ref <utility::seekableInputStream> seekableStream =
|
||||||
|
inputStream.dynamicCast <utility::seekableInputStream>();
|
||||||
|
|
||||||
|
if (seekableStream == NULL || end == 0)
|
||||||
|
{
|
||||||
|
// Read the whole stream into a buffer
|
||||||
|
std::ostringstream oss;
|
||||||
|
utility::outputStreamAdapter ossAdapter(oss);
|
||||||
|
|
||||||
|
utility::bufferedStreamCopyRange(*inputStream, ossAdapter, position, end - position);
|
||||||
|
|
||||||
|
const string buffer = oss.str();
|
||||||
|
parseImpl(buffer, 0, buffer.length(), NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ref <utility::parserInputStreamAdapter> parser =
|
||||||
|
vmime::create <utility::parserInputStreamAdapter>(seekableStream);
|
||||||
|
|
||||||
|
parseImpl(parser, position, end, newPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse(const string& buffer)
|
void component::parse(const string& buffer)
|
||||||
{
|
{
|
||||||
parse(buffer, 0, buffer.length(), NULL);
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
|
parseImpl(buffer, 0, buffer.length(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::parse
|
||||||
|
(const string& buffer, const string::size_type position,
|
||||||
|
const string::size_type end, string::size_type* newPosition)
|
||||||
|
{
|
||||||
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
|
parseImpl(buffer, position, end, newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::offsetParsedBounds(const utility::stream::size_type offset)
|
||||||
|
{
|
||||||
|
// Offset parsed bounds of this component
|
||||||
|
if (m_parsedLength != 0)
|
||||||
|
m_parsedOffset += offset;
|
||||||
|
|
||||||
|
// Offset parsed bounds of our children
|
||||||
|
std::vector <ref <component> > children = getChildComponents();
|
||||||
|
|
||||||
|
for (unsigned int i = 0, n = children.size() ; i < n ; ++i)
|
||||||
|
children[i]->offsetParsedBounds(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::parseImpl
|
||||||
|
(ref <utility::parserInputStreamAdapter> parser, const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end, utility::stream::size_type* newPosition)
|
||||||
|
{
|
||||||
|
const std::string buffer = parser->extract(position, end);
|
||||||
|
parseImpl(buffer, 0, buffer.length(), newPosition);
|
||||||
|
|
||||||
|
// Recursivey offset parsed bounds on children
|
||||||
|
if (position != 0)
|
||||||
|
offsetParsedBounds(position);
|
||||||
|
|
||||||
|
if (newPosition != NULL)
|
||||||
|
*newPosition += position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::parseImpl
|
||||||
|
(const string& buffer, const string::size_type position,
|
||||||
|
const string::size_type end, string::size_type* newPosition)
|
||||||
|
{
|
||||||
|
ref <utility::seekableInputStream> stream =
|
||||||
|
vmime::create <utility::inputStreamStringAdapter>(buffer);
|
||||||
|
|
||||||
|
ref <utility::parserInputStreamAdapter> parser =
|
||||||
|
vmime::create <utility::parserInputStreamAdapter>(stream);
|
||||||
|
|
||||||
|
parseImpl(parser, position, end, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -61,6 +157,26 @@ const string component::generate(const string::size_type maxLineLength,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::generate
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength,
|
||||||
|
const string::size_type curLinePos,
|
||||||
|
string::size_type* newLinePos) const
|
||||||
|
{
|
||||||
|
generateImpl(os, maxLineLength, curLinePos, newLinePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void component::generate
|
||||||
|
(ref <utility::outputStream> os,
|
||||||
|
const string::size_type maxLineLength,
|
||||||
|
const string::size_type curLinePos,
|
||||||
|
string::size_type* newLinePos) const
|
||||||
|
{
|
||||||
|
generateImpl(*os, maxLineLength, curLinePos, newLinePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string::size_type component::getParsedOffset() const
|
string::size_type component::getParsedOffset() const
|
||||||
{
|
{
|
||||||
return (m_parsedOffset);
|
return (m_parsedOffset);
|
||||||
@ -80,22 +196,5 @@ void component::setParsedBounds(const string::size_type start, const string::siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <component> > component::getChildComponents()
|
} // vmime
|
||||||
{
|
|
||||||
const std::vector <ref <const component> > constList =
|
|
||||||
const_cast <const component*>(this)->getChildComponents();
|
|
||||||
|
|
||||||
std::vector <ref <component> > list;
|
|
||||||
|
|
||||||
const std::vector <ref <const component> >::size_type count = constList.size();
|
|
||||||
|
|
||||||
list.resize(count);
|
|
||||||
|
|
||||||
for (std::vector <ref <const component> >::size_type i = 0 ; i < count ; ++i)
|
|
||||||
list[i] = constList[i].constCast <component>();
|
|
||||||
|
|
||||||
return (list);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -47,7 +47,7 @@ contentDisposition::contentDisposition(const contentDisposition& type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDisposition::parse(const string& buffer, const string::size_type position,
|
void contentDisposition::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_name = utility::stringUtils::trim(utility::stringUtils::toLower
|
m_name = utility::stringUtils::trim(utility::stringUtils::toLower
|
||||||
@ -60,7 +60,7 @@ void contentDisposition::parse(const string& buffer, const string::size_type pos
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDisposition::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
void contentDisposition::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
os << m_name;
|
os << m_name;
|
||||||
@ -122,9 +122,9 @@ void contentDisposition::setName(const string& name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > contentDisposition::getChildComponents() const
|
const std::vector <ref <component> > contentDisposition::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ zone = "UT" / "GMT" ; Universal Time
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void datetime::parse(const string& buffer, const string::size_type position,
|
void datetime::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -588,7 +588,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
void datetime::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
static const string::value_type* dayNames[] =
|
static const string::value_type* dayNames[] =
|
||||||
@ -784,9 +784,9 @@ ref <component> datetime::clone() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > datetime::getChildComponents() const
|
const std::vector <ref <component> > datetime::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,9 +79,9 @@ disposition& disposition::operator=(const disposition& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > disposition::getChildComponents() const
|
const std::vector <ref <component> > disposition::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ const std::vector <string> disposition::getModifierList() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::parse(const string& buffer, const string::size_type position,
|
void disposition::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
// disposition-mode ";" disposition-type
|
// disposition-mode ";" disposition-type
|
||||||
@ -276,7 +276,7 @@ void disposition::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void disposition::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
string::size_type pos = curLinePos;
|
string::size_type pos = curLinePos;
|
||||||
|
@ -61,7 +61,7 @@ encoding::encoding(const encoding& enc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::parse(const string& buffer, const string::size_type position,
|
void encoding::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_usage = USAGE_UNKNOWN;
|
m_usage = USAGE_UNKNOWN;
|
||||||
@ -80,7 +80,7 @@ void encoding::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
void encoding::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
os << m_name;
|
os << m_name;
|
||||||
@ -268,9 +268,9 @@ void encoding::setUsage(const EncodingUsage usage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > encoding::getChildComponents() const
|
const std::vector <ref <component> > encoding::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ field-body-contents =
|
|||||||
specials tokens, or else consisting of texts>
|
specials tokens, or else consisting of texts>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void header::parse(const string& buffer, const string::size_type position,
|
void header::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
string::size_type pos = position;
|
string::size_type pos = position;
|
||||||
@ -83,7 +83,7 @@ void header::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void header::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void header::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
// Generate the fields
|
// Generate the fields
|
||||||
@ -337,9 +337,9 @@ const std::vector <ref <headerField> > header::getFieldList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > header::getChildComponents() const
|
const std::vector <ref <component> > header::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
copy_vector(m_fields, list);
|
copy_vector(m_fields, list);
|
||||||
|
|
||||||
|
@ -262,14 +262,14 @@ ref <headerField> headerField::parseNext(const string& buffer, const string::siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void headerField::parse(const string& buffer, const string::size_type position, const string::size_type end,
|
void headerField::parseImpl(const string& buffer, const string::size_type position, const string::size_type end,
|
||||||
string::size_type* newPosition)
|
string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_value->parse(buffer, position, end, newPosition);
|
m_value->parse(buffer, position, end, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void headerField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void headerField::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
os << m_name + ": ";
|
os << m_name + ": ";
|
||||||
@ -296,9 +296,9 @@ bool headerField::isCustom() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > headerField::getChildComponents() const
|
const std::vector <ref <component> > headerField::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
if (m_value)
|
if (m_value)
|
||||||
list.push_back(m_value);
|
list.push_back(m_value);
|
||||||
|
@ -65,7 +65,7 @@ angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mailbox::parse(const string& buffer, const string::size_type position,
|
void mailbox::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -343,7 +343,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailbox::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void mailbox::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
if (m_name.isEmpty())
|
if (m_name.isEmpty())
|
||||||
@ -514,9 +514,9 @@ void mailbox::setEmail(const string& email)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > mailbox::getChildComponents() const
|
const std::vector <ref <component> > mailbox::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ mailboxGroup::~mailboxGroup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxGroup::parse(const string& buffer, const string::size_type position,
|
void mailboxGroup::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -111,7 +111,7 @@ void mailboxGroup::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxGroup::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void mailboxGroup::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
// We have to encode the name:
|
// We have to encode the name:
|
||||||
@ -348,9 +348,9 @@ const std::vector <ref <mailbox> > mailboxGroup::getMailboxList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > mailboxGroup::getChildComponents() const
|
const std::vector <ref <component> > mailboxGroup::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
copy_vector(m_list, list);
|
copy_vector(m_list, list);
|
||||||
|
|
||||||
|
@ -190,20 +190,20 @@ mailboxList& mailboxList::operator=(const mailboxList& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > mailboxList::getChildComponents() const
|
const std::vector <ref <component> > mailboxList::getChildComponents()
|
||||||
{
|
{
|
||||||
return (m_list.getChildComponents());
|
return (m_list.getChildComponents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxList::parse(const string& buffer, const string::size_type position,
|
void mailboxList::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_list.parse(buffer, position, end, newPosition);
|
m_list.parse(buffer, position, end, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxList::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void mailboxList::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
m_list.generate(os, maxLineLength, curLinePos, newLinePos);
|
m_list.generate(os, maxLineLength, curLinePos, newLinePos);
|
||||||
|
@ -48,7 +48,7 @@ mediaType::mediaType(const string& type, const string& subType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mediaType::parse(const string& buffer, const string::size_type position,
|
void mediaType::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -82,7 +82,7 @@ void mediaType::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mediaType::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void mediaType::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
const string value = m_type + "/" + m_subType;
|
const string value = m_type + "/" + m_subType;
|
||||||
@ -176,9 +176,9 @@ void mediaType::setFromString(const string& type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > mediaType::getChildComponents() const
|
const std::vector <ref <component> > mediaType::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,9 +61,14 @@ const string message::generate(const string::size_type maxLineLength,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void message::parse(const string& buffer)
|
|
||||||
|
void message::generate
|
||||||
|
(ref <utility::outputStream> os,
|
||||||
|
const string::size_type maxLineLength,
|
||||||
|
const string::size_type curLinePos,
|
||||||
|
string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
bodyPart::parse(buffer);
|
bodyPart::generate(os, maxLineLength, curLinePos, newLinePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ messageId::messageId(const string& left, const string& right)
|
|||||||
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
|
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void messageId::parse(const string& buffer, const string::size_type position,
|
void messageId::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -185,7 +185,7 @@ const string messageId::getId() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void messageId::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void messageId::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
string::size_type pos = curLinePos;
|
string::size_type pos = curLinePos;
|
||||||
@ -288,9 +288,9 @@ void messageId::setRight(const string& right)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > messageId::getChildComponents() const
|
const std::vector <ref <component> > messageId::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ messageIdSequence& messageIdSequence::operator=(const messageIdSequence& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > messageIdSequence::getChildComponents() const
|
const std::vector <ref <component> > messageIdSequence::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > res;
|
std::vector <ref <component> > res;
|
||||||
|
|
||||||
copy_vector(m_list, res);
|
copy_vector(m_list, res);
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ const std::vector <ref <const component> > messageIdSequence::getChildComponents
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void messageIdSequence::parse(const string& buffer, const string::size_type position,
|
void messageIdSequence::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
removeAllMessageIds();
|
removeAllMessageIds();
|
||||||
@ -106,7 +106,7 @@ void messageIdSequence::parse(const string& buffer, const string::size_type posi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void messageIdSequence::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void messageIdSequence::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
string::size_type pos = curLinePos;
|
string::size_type pos = curLinePos;
|
||||||
|
@ -36,19 +36,19 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
parameter::parameter(const string& name)
|
parameter::parameter(const string& name)
|
||||||
: m_name(name)
|
: m_name(name), m_value(vmime::create <word>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
parameter::parameter(const string& name, const word& value)
|
parameter::parameter(const string& name, const word& value)
|
||||||
: m_name(name), m_value(value)
|
: m_name(name), m_value(vmime::create <word>(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
parameter::parameter(const string& name, const string& value)
|
parameter::parameter(const string& name, const string& value)
|
||||||
: m_name(name), m_value(value)
|
: m_name(name), m_value(vmime::create <word>(value))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ void parameter::copyFrom(const component& other)
|
|||||||
const parameter& param = dynamic_cast <const parameter&>(other);
|
const parameter& param = dynamic_cast <const parameter&>(other);
|
||||||
|
|
||||||
m_name = param.m_name;
|
m_name = param.m_name;
|
||||||
m_value.copyFrom(param.m_value);
|
m_value->copyFrom(*param.m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ const string& parameter::getName() const
|
|||||||
|
|
||||||
const word& parameter::getValue() const
|
const word& parameter::getValue() const
|
||||||
{
|
{
|
||||||
return m_value;
|
return *m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,15 +109,15 @@ void parameter::setValue(const component& value)
|
|||||||
|
|
||||||
void parameter::setValue(const word& value)
|
void parameter::setValue(const word& value)
|
||||||
{
|
{
|
||||||
m_value = value;
|
*m_value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parameter::parse(const string& buffer, const string::size_type position,
|
void parameter::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_value.setBuffer(string(buffer.begin() + position, buffer.begin() + end));
|
m_value->setBuffer(string(buffer.begin() + position, buffer.begin() + end));
|
||||||
m_value.setCharset(charset(charsets::US_ASCII));
|
m_value->setCharset(charset(charsets::US_ASCII));
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition)
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
@ -248,16 +248,16 @@ void parameter::parse(const std::vector <valueChunk>& chunks)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_value.setBuffer(value.str());
|
m_value->setBuffer(value.str());
|
||||||
m_value.setCharset(ch);
|
m_value->setCharset(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parameter::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void parameter::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
const string& name = m_name;
|
const string& name = m_name;
|
||||||
const string& value = m_value.getBuffer();
|
const string& value = m_value->getBuffer();
|
||||||
|
|
||||||
// For compatibility with implementations that do not understand RFC-2231,
|
// For compatibility with implementations that do not understand RFC-2231,
|
||||||
// also generate a normal "7bit/us-ascii" parameter
|
// also generate a normal "7bit/us-ascii" parameter
|
||||||
@ -344,7 +344,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|||||||
// 7-bit (ASCII) bytes in the input will be used to determine if
|
// 7-bit (ASCII) bytes in the input will be used to determine if
|
||||||
// we need to encode the whole buffer.
|
// we need to encode the whole buffer.
|
||||||
encoding recommendedEnc;
|
encoding recommendedEnc;
|
||||||
const bool alwaysEncode = m_value.getCharset().getRecommendedEncoding(recommendedEnc);
|
const bool alwaysEncode = m_value->getCharset().getRecommendedEncoding(recommendedEnc);
|
||||||
bool extended = alwaysEncode;
|
bool extended = alwaysEncode;
|
||||||
|
|
||||||
if (needQuotedPrintable)
|
if (needQuotedPrintable)
|
||||||
@ -352,7 +352,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|||||||
// Send the name in quoted-printable, so outlook express et.al.
|
// Send the name in quoted-printable, so outlook express et.al.
|
||||||
// will understand the real filename
|
// will understand the real filename
|
||||||
size_t oldLen = sevenBitBuffer.length();
|
size_t oldLen = sevenBitBuffer.length();
|
||||||
m_value.generate(sevenBitStream);
|
m_value->generate(sevenBitStream);
|
||||||
pos += sevenBitBuffer.length() - oldLen;
|
pos += sevenBitBuffer.length() - oldLen;
|
||||||
extended = true; // also send with RFC-2231 encoding
|
extended = true; // also send with RFC-2231 encoding
|
||||||
}
|
}
|
||||||
@ -429,7 +429,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|||||||
// + at least 5 characters for the value
|
// + at least 5 characters for the value
|
||||||
const string::size_type firstSectionLength =
|
const string::size_type firstSectionLength =
|
||||||
name.length() + 4 /* *0*= */ + 2 /* '' */
|
name.length() + 4 /* *0*= */ + 2 /* '' */
|
||||||
+ m_value.getCharset().getName().length();
|
+ m_value->getCharset().getName().length();
|
||||||
|
|
||||||
if (pos + firstSectionLength + 5 >= maxLineLength)
|
if (pos + firstSectionLength + 5 >= maxLineLength)
|
||||||
{
|
{
|
||||||
@ -539,7 +539,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|||||||
|
|
||||||
if (sectionNumber == 0)
|
if (sectionNumber == 0)
|
||||||
{
|
{
|
||||||
os << m_value.getCharset().getName();
|
os << m_value->getCharset().getName();
|
||||||
os << '\'' << /* No language */ '\'';
|
os << '\'' << /* No language */ '\'';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,11 +570,11 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > parameter::getChildComponents() const
|
const std::vector <ref <component> > parameter::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
list.push_back(ref <const component>::fromPtr(&m_value));
|
list.push_back(m_value);
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ struct paramInfo
|
|||||||
#endif // VMIME_BUILDING_DOC
|
#endif // VMIME_BUILDING_DOC
|
||||||
|
|
||||||
|
|
||||||
void parameterizedHeaderField::parse(const string& buffer, const string::size_type position,
|
void parameterizedHeaderField::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -328,13 +328,13 @@ void parameterizedHeaderField::parse(const string& buffer, const string::size_ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void parameterizedHeaderField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void parameterizedHeaderField::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
string::size_type pos = curLinePos;
|
string::size_type pos = curLinePos;
|
||||||
|
|
||||||
// Parent header field
|
// Parent header field
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
headerField::generateImpl(os, maxLineLength, pos, &pos);
|
||||||
|
|
||||||
// Parameters
|
// Parameters
|
||||||
for (std::vector <ref <parameter> >::const_iterator
|
for (std::vector <ref <parameter> >::const_iterator
|
||||||
@ -552,11 +552,11 @@ const std::vector <ref <parameter> > parameterizedHeaderField::getParameterList(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > parameterizedHeaderField::getChildComponents() const
|
const std::vector <ref <component> > parameterizedHeaderField::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list = headerField::getChildComponents();
|
std::vector <ref <component> > list = headerField::getChildComponents();
|
||||||
|
|
||||||
for (std::vector <ref <parameter> >::const_iterator it = m_params.begin() ;
|
for (std::vector <ref <parameter> >::iterator it = m_params.begin() ;
|
||||||
it != m_params.end() ; ++it)
|
it != m_params.end() ; ++it)
|
||||||
{
|
{
|
||||||
list.push_back(*it);
|
list.push_back(*it);
|
||||||
|
@ -106,13 +106,13 @@ path& path::operator=(const path& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > path::getChildComponents() const
|
const std::vector <ref <component> > path::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void path::parse(const string& buffer, const string::size_type position,
|
void path::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
string::size_type pos = position;
|
string::size_type pos = position;
|
||||||
@ -165,7 +165,7 @@ void path::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void path::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
void path::generateImpl(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
if (m_localPart.empty() && m_domain.empty())
|
if (m_localPart.empty() && m_domain.empty())
|
||||||
|
@ -224,6 +224,26 @@ vmime::utility::stream::size_type posixFileReaderInputStream::skip(const size_ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vmime::utility::stream::size_type posixFileReaderInputStream::getPosition() const
|
||||||
|
{
|
||||||
|
const off_t curPos = ::lseek(m_fd, 0, SEEK_CUR);
|
||||||
|
|
||||||
|
if (curPos == off_t(-1))
|
||||||
|
posixFileSystemFactory::reportError(m_path, errno);
|
||||||
|
|
||||||
|
return static_cast <size_type>(curPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void posixFileReaderInputStream::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
const off_t newPos = ::lseek(m_fd, pos, SEEK_SET);
|
||||||
|
|
||||||
|
if (newPos == off_t(-1))
|
||||||
|
posixFileSystemFactory::reportError(m_path, errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// posixFileWriter
|
// posixFileWriter
|
||||||
|
@ -479,6 +479,24 @@ vmime::utility::stream::size_type windowsFileReaderInputStream::skip(const size_
|
|||||||
return (dwNewPos - dwCurPos);
|
return (dwNewPos - dwCurPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vmime::utility::stream::size_type windowsFileReaderInputStream::getPosition() const
|
||||||
|
{
|
||||||
|
DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT);
|
||||||
|
|
||||||
|
if (dwCurPos == INVALID_SET_FILE_POINTER)
|
||||||
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
||||||
|
|
||||||
|
return static_cast <size_type>(dwCurPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void windowsFileReaderInputStream::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)pos, NULL, FILE_BEGIN);
|
||||||
|
|
||||||
|
if (dwNewPos == INVALID_SET_FILE_POINTER)
|
||||||
|
windowsFileSystemFactory::reportError(m_path, GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath)
|
windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath)
|
||||||
: m_path(path), m_nativePath(nativePath)
|
: m_path(path), m_nativePath(nativePath)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +57,7 @@ relay::relay(const relay& r)
|
|||||||
["for" addr-spec] ; initial form
|
["for" addr-spec] ; initial form
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void relay::parse(const string& buffer, const string::size_type position,
|
void relay::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
const string::value_type* const pend = buffer.data() + end;
|
const string::value_type* const pend = buffer.data() + end;
|
||||||
@ -198,7 +198,7 @@ void relay::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void relay::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void relay::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -338,10 +338,10 @@ std::vector <string>& relay::getWithList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > relay::getChildComponents() const
|
const std::vector <ref <component> > relay::getChildComponents()
|
||||||
{
|
{
|
||||||
// TODO: should fields inherit from 'component'? (using typeAdapter)
|
// TODO: should fields inherit from 'component'? (using typeAdapter)
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "vmime/utility/outputStreamAdapter.hpp"
|
#include "vmime/utility/outputStreamAdapter.hpp"
|
||||||
#include "vmime/utility/inputStreamStringAdapter.hpp"
|
#include "vmime/utility/inputStreamStringAdapter.hpp"
|
||||||
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
#include "vmime/utility/streamUtils.hpp"
|
#include "vmime/utility/streamUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -207,6 +208,9 @@ const vmime::encoding& streamContentHandler::getEncoding() const
|
|||||||
|
|
||||||
bool streamContentHandler::isBuffered() const
|
bool streamContentHandler::isBuffered() const
|
||||||
{
|
{
|
||||||
|
if (m_stream.dynamicCast <utility::seekableInputStream>() != NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
// FIXME: some streams can be resetted
|
// FIXME: some streams can be resetted
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ text::~text()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void text::parse(const string& buffer, const string::size_type position,
|
void text::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
removeAllWords();
|
removeAllWords();
|
||||||
@ -85,7 +85,7 @@ void text::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void text::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void text::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
encodeAndFold(os, maxLineLength, curLinePos, newLinePos, 0);
|
encodeAndFold(os, maxLineLength, curLinePos, newLinePos, 0);
|
||||||
@ -389,9 +389,9 @@ text* text::decodeAndUnfold(const string& in, text* generateInExisting)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > text::getChildComponents() const
|
const std::vector <ref <component> > text::getChildComponents()
|
||||||
{
|
{
|
||||||
std::vector <ref <const component> > list;
|
std::vector <ref <component> > list;
|
||||||
|
|
||||||
copy_vector(m_words, list);
|
copy_vector(m_words, list);
|
||||||
|
|
||||||
|
@ -65,6 +65,18 @@ stream::size_type inputStreamAdapter::skip(const size_type count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type inputStreamAdapter::getPosition() const
|
||||||
|
{
|
||||||
|
return m_stream.tellg();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void inputStreamAdapter::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
m_stream.seekg(pos, std::ios_base::beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // utility
|
} // utility
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -85,6 +85,19 @@ stream::size_type inputStreamByteBufferAdapter::skip(const size_type count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type inputStreamByteBufferAdapter::getPosition() const
|
||||||
|
{
|
||||||
|
return m_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void inputStreamByteBufferAdapter::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
if (pos <= m_length)
|
||||||
|
m_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // utility
|
} // utility
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -89,6 +89,19 @@ stream::size_type inputStreamStringAdapter::skip(const size_type count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type inputStreamStringAdapter::getPosition() const
|
||||||
|
{
|
||||||
|
return m_pos - m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void inputStreamStringAdapter::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
if (m_begin + pos <= m_end)
|
||||||
|
m_pos = m_begin + pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // utility
|
} // utility
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -84,6 +84,19 @@ stream::size_type inputStreamStringProxyAdapter::skip(const size_type count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type inputStreamStringProxyAdapter::getPosition() const
|
||||||
|
{
|
||||||
|
return m_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void inputStreamStringProxyAdapter::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
if (pos <= m_buffer.length())
|
||||||
|
m_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // utility
|
} // utility
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
162
src/utility/parserInputStreamAdapter.cpp
Normal file
162
src/utility/parserInputStreamAdapter.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "vmime/utility/parserInputStreamAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
|
parserInputStreamAdapter::parserInputStreamAdapter(ref <seekableInputStream> stream)
|
||||||
|
: m_stream(stream)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool parserInputStreamAdapter::eof() const
|
||||||
|
{
|
||||||
|
return m_stream->eof();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void parserInputStreamAdapter::reset()
|
||||||
|
{
|
||||||
|
m_stream->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type parserInputStreamAdapter::read
|
||||||
|
(value_type* const data, const size_type count)
|
||||||
|
{
|
||||||
|
return m_stream->read(data, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ref <seekableInputStream> parserInputStreamAdapter::getUnderlyingStream()
|
||||||
|
{
|
||||||
|
return m_stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string parserInputStreamAdapter::extract(const size_type begin, const size_type end) const
|
||||||
|
{
|
||||||
|
const size_type initialPos = m_stream->getPosition();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value_type *buffer = new value_type[end - begin + 1];
|
||||||
|
|
||||||
|
m_stream->seek(begin);
|
||||||
|
|
||||||
|
const size_type readBytes = m_stream->read(buffer, end - begin);
|
||||||
|
buffer[readBytes] = '\0';
|
||||||
|
|
||||||
|
m_stream->seek(initialPos);
|
||||||
|
|
||||||
|
string str(buffer, buffer + readBytes);
|
||||||
|
delete [] buffer;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
m_stream->seek(initialPos);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type parserInputStreamAdapter::findNext
|
||||||
|
(const std::string& token, const size_type startPosition)
|
||||||
|
{
|
||||||
|
static const unsigned int BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
|
// Token must not be longer than BUFFER_SIZE/2
|
||||||
|
if (token.empty() || token.length() > BUFFER_SIZE / 2)
|
||||||
|
return npos;
|
||||||
|
|
||||||
|
const size_type initialPos = getPosition();
|
||||||
|
|
||||||
|
seek(startPosition);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value_type findBuffer[BUFFER_SIZE];
|
||||||
|
value_type* findBuffer1 = findBuffer;
|
||||||
|
value_type* findBuffer2 = findBuffer + (BUFFER_SIZE / 2) * sizeof(value_type);
|
||||||
|
|
||||||
|
size_type findBufferLen = 0;
|
||||||
|
size_type findBufferOffset = 0;
|
||||||
|
|
||||||
|
// Fill in initial buffer
|
||||||
|
findBufferLen = read(findBuffer, BUFFER_SIZE * sizeof(value_type));
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
// Find token
|
||||||
|
for (value_type *begin = findBuffer, *end = findBuffer + findBufferLen - token.length() ;
|
||||||
|
begin <= end ; ++begin)
|
||||||
|
{
|
||||||
|
if (begin[0] == token[0] &&
|
||||||
|
(token.length() == 1 ||
|
||||||
|
memcmp(static_cast <const void *>(&begin[1]),
|
||||||
|
static_cast <const void *>(token.data() + 1),
|
||||||
|
token.length() - 1) == 0))
|
||||||
|
{
|
||||||
|
seek(initialPos);
|
||||||
|
return startPosition + findBufferOffset + (begin - findBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate buffer
|
||||||
|
memcpy(findBuffer1, findBuffer2, (BUFFER_SIZE / 2) * sizeof(value_type));
|
||||||
|
|
||||||
|
// Read more bytes
|
||||||
|
if (findBufferLen < BUFFER_SIZE && eof())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_type bytesRead = read(findBuffer2, (BUFFER_SIZE / 2) * sizeof(value_type));
|
||||||
|
findBufferLen = (BUFFER_SIZE / 2) + bytesRead;
|
||||||
|
findBufferOffset += (BUFFER_SIZE / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
seek(initialPos);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
seek(initialPos);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // utility
|
||||||
|
} // vmime
|
||||||
|
|
95
src/utility/seekableInputStreamRegionAdapter.cpp
Normal file
95
src/utility/seekableInputStreamRegionAdapter.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "vmime/utility/seekableInputStreamRegionAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
|
seekableInputStreamRegionAdapter::seekableInputStreamRegionAdapter
|
||||||
|
(ref <seekableInputStream> stream, const size_type begin, const size_type length)
|
||||||
|
: m_stream(stream), m_begin(begin), m_length(length)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool seekableInputStreamRegionAdapter::eof() const
|
||||||
|
{
|
||||||
|
return getPosition() >= m_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void seekableInputStreamRegionAdapter::reset()
|
||||||
|
{
|
||||||
|
m_stream->seek(m_begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type seekableInputStreamRegionAdapter::read
|
||||||
|
(value_type* const data, const size_type count)
|
||||||
|
{
|
||||||
|
if (getPosition() + count >= m_length)
|
||||||
|
{
|
||||||
|
const size_type remaining = m_length - getPosition();
|
||||||
|
return m_stream->read(data, remaining);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return m_stream->read(data, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type seekableInputStreamRegionAdapter::skip(const size_type count)
|
||||||
|
{
|
||||||
|
if (getPosition() + count >= m_length)
|
||||||
|
{
|
||||||
|
const size_type remaining = m_length - getPosition();
|
||||||
|
m_stream->skip(remaining);
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_stream->skip(count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type seekableInputStreamRegionAdapter::getPosition() const
|
||||||
|
{
|
||||||
|
return m_stream->getPosition() - m_begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void seekableInputStreamRegionAdapter::seek(const size_type pos)
|
||||||
|
{
|
||||||
|
m_stream->seek(m_begin + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // utility
|
||||||
|
} // vmime
|
||||||
|
|
@ -29,6 +29,9 @@ namespace vmime {
|
|||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
|
const stream::size_type stream::npos = static_cast <size_type>(vmime::string::npos);
|
||||||
|
|
||||||
|
|
||||||
stream::size_type stream::getBlockSize()
|
stream::size_type stream::getBlockSize()
|
||||||
{
|
{
|
||||||
return 32768; // 32 KB
|
return 32768; // 32 KB
|
||||||
@ -37,3 +40,4 @@ stream::size_type stream::getBlockSize()
|
|||||||
|
|
||||||
} // utility
|
} // utility
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -52,6 +52,35 @@ stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stream::size_type bufferedStreamCopyRange(inputStream& is, outputStream& os,
|
||||||
|
const stream::size_type start, const stream::size_type length)
|
||||||
|
{
|
||||||
|
const stream::size_type blockSize =
|
||||||
|
std::min(is.getBlockSize(), os.getBlockSize());
|
||||||
|
|
||||||
|
is.skip(start);
|
||||||
|
|
||||||
|
std::vector <stream::value_type> vbuffer(blockSize);
|
||||||
|
|
||||||
|
stream::value_type* buffer = &vbuffer.front();
|
||||||
|
stream::size_type total = 0;
|
||||||
|
|
||||||
|
while (!is.eof() && total < length)
|
||||||
|
{
|
||||||
|
const stream::size_type remaining = std::min(length - total, blockSize);
|
||||||
|
const stream::size_type read = is.read(buffer, blockSize);
|
||||||
|
|
||||||
|
if (read != 0)
|
||||||
|
{
|
||||||
|
os.write(buffer, read);
|
||||||
|
total += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os,
|
||||||
const stream::size_type length, progressListener* progress)
|
const stream::size_type length, progressListener* progress)
|
||||||
{
|
{
|
||||||
|
@ -241,7 +241,7 @@ const std::vector <ref <word> > word::parseMultiple(const string& buffer, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void word::parse(const string& buffer, const string::size_type position,
|
void word::parseImpl(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
if (position + 6 < end && // 6 = "=?(.+)?(.*)?="
|
if (position + 6 < end && // 6 = "=?(.+)?(.*)?="
|
||||||
@ -324,7 +324,7 @@ void word::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void word::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void word::generateImpl(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
generate(os, maxLineLength, curLinePos, newLinePos, 0, NULL);
|
generate(os, maxLineLength, curLinePos, newLinePos, 0, NULL);
|
||||||
@ -743,9 +743,9 @@ void word::setBuffer(const string& buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <ref <const component> > word::getChildComponents() const
|
const std::vector <ref <component> > word::getChildComponents()
|
||||||
{
|
{
|
||||||
return std::vector <ref <const component> >();
|
return std::vector <ref <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,12 +33,14 @@ VMIME_TEST_SUITE_BEGIN
|
|||||||
VMIME_TEST_LIST_BEGIN
|
VMIME_TEST_LIST_BEGIN
|
||||||
VMIME_TEST(testParse)
|
VMIME_TEST(testParse)
|
||||||
VMIME_TEST(testGenerate)
|
VMIME_TEST(testGenerate)
|
||||||
|
VMIME_TEST(testParseGuessBoundary)
|
||||||
VMIME_TEST(testParseMissingLastBoundary)
|
VMIME_TEST(testParseMissingLastBoundary)
|
||||||
VMIME_TEST(testPrologEpilog)
|
VMIME_TEST(testPrologEpilog)
|
||||||
VMIME_TEST(testPrologEncoding)
|
VMIME_TEST(testPrologEncoding)
|
||||||
VMIME_TEST(testSuccessiveBoundaries)
|
VMIME_TEST(testSuccessiveBoundaries)
|
||||||
VMIME_TEST(testGenerate7bit)
|
VMIME_TEST(testGenerate7bit)
|
||||||
VMIME_TEST(testTextUsageForQPEncoding)
|
VMIME_TEST(testTextUsageForQPEncoding)
|
||||||
|
VMIME_TEST(testParseVeryBigMessage)
|
||||||
VMIME_TEST_LIST_END
|
VMIME_TEST_LIST_END
|
||||||
|
|
||||||
|
|
||||||
@ -237,6 +239,93 @@ VMIME_TEST_SUITE_BEGIN
|
|||||||
VASSERT_EQ("2", "Part1-line1\r\nPart1-line2\r\n=89", oss.str());
|
VASSERT_EQ("2", "Part1-line1\r\nPart1-line2\r\n=89", oss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testParseGuessBoundary()
|
||||||
|
{
|
||||||
|
// Boundary is not specified in "Content-Type" field
|
||||||
|
// Parser will try to guess it from message contents.
|
||||||
|
|
||||||
|
vmime::string str =
|
||||||
|
"Content-Type: multipart/mixed"
|
||||||
|
"\r\n\r\n"
|
||||||
|
"--UNKNOWN-BOUNDARY\r\nHEADER1\r\n\r\nBODY1\r\n"
|
||||||
|
"--UNKNOWN-BOUNDARY\r\nHEADER2\r\n\r\nBODY2\r\n"
|
||||||
|
"--UNKNOWN-BOUNDARY--";
|
||||||
|
|
||||||
|
vmime::bodyPart p;
|
||||||
|
p.parse(str);
|
||||||
|
|
||||||
|
VASSERT_EQ("count", 2, p.getBody()->getPartCount());
|
||||||
|
|
||||||
|
VASSERT_EQ("part1-body", "BODY1", extractContents(p.getBody()->getPartAt(0)->getBody()->getContents()));
|
||||||
|
VASSERT_EQ("part2-body", "BODY2", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testParseVeryBigMessage()
|
||||||
|
{
|
||||||
|
// When parsing from a seekable input stream, body contents should not
|
||||||
|
// be kept in memory in a "stringContentHandler" object. Instead, content
|
||||||
|
// should be accessible via a "streamContentHandler" object.
|
||||||
|
|
||||||
|
static const std::string BODY1_BEGIN = "BEGIN1BEGIN1BEGIN1";
|
||||||
|
static const std::string BODY1_LINE = "BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1BODY1";
|
||||||
|
static const std::string BODY1_END = "END1END1";
|
||||||
|
static const unsigned int BODY1_REPEAT = 35000;
|
||||||
|
static const unsigned int BODY1_LENGTH =
|
||||||
|
BODY1_BEGIN.length() + BODY1_LINE.length() * BODY1_REPEAT + BODY1_END.length();
|
||||||
|
|
||||||
|
static const std::string BODY2_LINE = "BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2BODY2";
|
||||||
|
static const unsigned int BODY2_REPEAT = 20000;
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\""
|
||||||
|
<< "\r\n\r\n"
|
||||||
|
<< "--MY-BOUNDARY\r\n"
|
||||||
|
<< "HEADER1\r\n"
|
||||||
|
<< "\r\n";
|
||||||
|
|
||||||
|
oss << BODY1_BEGIN;
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < BODY1_REPEAT ; ++i)
|
||||||
|
oss << BODY1_LINE;
|
||||||
|
|
||||||
|
oss << BODY1_END;
|
||||||
|
|
||||||
|
oss << "\r\n"
|
||||||
|
<< "--MY-BOUNDARY\r\n"
|
||||||
|
<< "HEADER2\r\n"
|
||||||
|
<< "\r\n";
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < BODY2_REPEAT ; ++i)
|
||||||
|
oss << BODY2_LINE;
|
||||||
|
|
||||||
|
oss << "\r\n"
|
||||||
|
<< "--MY-BOUNDARY--\r\n";
|
||||||
|
|
||||||
|
vmime::ref <vmime::utility::inputStreamStringAdapter> is =
|
||||||
|
vmime::create <vmime::utility::inputStreamStringAdapter>(oss.str());
|
||||||
|
|
||||||
|
vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
|
||||||
|
msg->parse(is, oss.str().length());
|
||||||
|
|
||||||
|
vmime::ref <vmime::body> body1 = msg->getBody()->getPartAt(0)->getBody();
|
||||||
|
vmime::ref <const vmime::contentHandler> body1Cts = body1->getContents();
|
||||||
|
|
||||||
|
vmime::ref <vmime::body> body2 = msg->getBody()->getPartAt(1)->getBody();
|
||||||
|
vmime::ref <const vmime::contentHandler> body2Cts = body2->getContents();
|
||||||
|
|
||||||
|
vmime::string body1CtsExtracted;
|
||||||
|
vmime::utility::outputStreamStringAdapter body1CtsExtractStream(body1CtsExtracted);
|
||||||
|
body1Cts->extract(body1CtsExtractStream);
|
||||||
|
|
||||||
|
VASSERT_EQ("1.1", BODY1_LENGTH, body1Cts->getLength());
|
||||||
|
VASSERT("1.2", body1Cts.dynamicCast <const vmime::streamContentHandler>() != NULL);
|
||||||
|
VASSERT_EQ("1.3", BODY1_LENGTH, body1CtsExtracted.length());
|
||||||
|
VASSERT_EQ("1.4", BODY1_BEGIN, body1CtsExtracted.substr(0, BODY1_BEGIN.length()));
|
||||||
|
VASSERT_EQ("1.5", BODY1_END, body1CtsExtracted.substr(BODY1_LENGTH - BODY1_END.length(), BODY1_END.length()));
|
||||||
|
|
||||||
|
VASSERT_EQ("2.1", BODY2_LINE.length() * BODY2_REPEAT, body2Cts->getLength());
|
||||||
|
VASSERT("2.2", body2Cts.dynamicCast <const vmime::streamContentHandler>() != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
VMIME_TEST_SUITE_END
|
VMIME_TEST_SUITE_END
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
addressList& operator=(const addressList& other);
|
addressList& operator=(const addressList& other);
|
||||||
addressList& operator=(const mailboxList& other);
|
addressList& operator=(const mailboxList& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
|
|
||||||
/** Add a address at the end of the list.
|
/** Add a address at the end of the list.
|
||||||
@ -163,14 +163,20 @@ private:
|
|||||||
|
|
||||||
std::vector <ref <address> > m_list;
|
std::vector <ref <address> > m_list;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
body& operator=(const body& other);
|
body& operator=(const body& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -299,14 +299,20 @@ private:
|
|||||||
|
|
||||||
void initNewPart(ref <bodyPart> part);
|
void initNewPart(ref <bodyPart> part);
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(ref <utility::parserInputStreamAdapter> parser,
|
||||||
|
const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end,
|
||||||
|
utility::stream::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
bodyPart& operator=(const bodyPart& other);
|
bodyPart& operator=(const bodyPart& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -98,14 +98,20 @@ private:
|
|||||||
|
|
||||||
weak_ref <bodyPart> m_parent;
|
weak_ref <bodyPart> m_parent;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(ref <utility::parserInputStreamAdapter> parser,
|
||||||
|
const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end,
|
||||||
|
utility::stream::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
bool operator==(const charset& value) const;
|
bool operator==(const charset& value) const;
|
||||||
bool operator!=(const charset& value) const;
|
bool operator!=(const charset& value) const;
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Gets the recommended encoding for this charset.
|
/** Gets the recommended encoding for this charset.
|
||||||
* Note: there may be no recommended encoding.
|
* Note: there may be no recommended encoding.
|
||||||
@ -117,14 +117,20 @@ private:
|
|||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "vmime/base.hpp"
|
#include "vmime/base.hpp"
|
||||||
#include "vmime/utility/inputStream.hpp"
|
#include "vmime/utility/inputStream.hpp"
|
||||||
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
#include "vmime/utility/parserInputStreamAdapter.hpp"
|
||||||
#include "vmime/utility/outputStream.hpp"
|
#include "vmime/utility/outputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -51,6 +53,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void parse(const string& buffer);
|
void parse(const string& buffer);
|
||||||
|
|
||||||
|
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
||||||
|
* or if length is not specified, entire contents of the stream will
|
||||||
|
* be loaded into memory before parsing.
|
||||||
|
*/
|
||||||
|
void parse(ref <utility::inputStream> inputStream, const utility::stream::size_type length);
|
||||||
|
|
||||||
/** Parse RFC-822/MIME data for this component.
|
/** Parse RFC-822/MIME data for this component.
|
||||||
*
|
*
|
||||||
* @param buffer input buffer
|
* @param buffer input buffer
|
||||||
@ -58,7 +66,26 @@ public:
|
|||||||
* @param end end position in the input buffer
|
* @param end end position in the input buffer
|
||||||
* @param newPosition will receive the new position in the input buffer
|
* @param newPosition will receive the new position in the input buffer
|
||||||
*/
|
*/
|
||||||
virtual void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL) = 0;
|
void parse
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
||||||
|
* or if end position is not specified, entire contents of the stream will
|
||||||
|
* be loaded into memory before parsing.
|
||||||
|
*
|
||||||
|
* @param inputStream stream from which to read data
|
||||||
|
* @param position current position in the input stream
|
||||||
|
* @param end end position in the input stream
|
||||||
|
* @param newPosition will receive the new position in the input stream
|
||||||
|
*/
|
||||||
|
void parse
|
||||||
|
(ref <utility::inputStream> inputStream,
|
||||||
|
const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end,
|
||||||
|
utility::stream::size_type* newPosition = NULL);
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component.
|
/** Generate RFC-2822/MIME data for this component.
|
||||||
*
|
*
|
||||||
@ -68,16 +95,35 @@ public:
|
|||||||
* @param curLinePos length of the current line in the output buffer
|
* @param curLinePos length of the current line in the output buffer
|
||||||
* @return generated data
|
* @return generated data
|
||||||
*/
|
*/
|
||||||
const string generate(const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0) const;
|
virtual const string generate
|
||||||
|
(const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0) const;
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component.
|
/** Generate RFC-2822/MIME data for this component.
|
||||||
*
|
*
|
||||||
* @param os output stream
|
* @param outputStream output stream
|
||||||
* @param maxLineLength maximum line length for output
|
* @param maxLineLength maximum line length for output
|
||||||
* @param curLinePos length of the current line in the output buffer
|
* @param curLinePos length of the current line in the output buffer
|
||||||
* @param newLinePos will receive the new line position (length of the last line written)
|
* @param newLinePos will receive the new line position (length of the last line written)
|
||||||
*/
|
*/
|
||||||
virtual void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const = 0;
|
virtual void generate
|
||||||
|
(utility::outputStream& outputStream,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
|
/** Generate RFC-2822/MIME data for this component.
|
||||||
|
*
|
||||||
|
* @param outputStream output stream
|
||||||
|
* @param maxLineLength maximum line length for output
|
||||||
|
* @param curLinePos length of the current line in the output buffer
|
||||||
|
* @param newLinePos will receive the new line position (length of the last line written)
|
||||||
|
*/
|
||||||
|
virtual void generate
|
||||||
|
(ref <utility::outputStream> outputStream,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
/** Clone this component.
|
/** Clone this component.
|
||||||
*
|
*
|
||||||
@ -95,41 +141,56 @@ public:
|
|||||||
virtual void copyFrom(const component& other) = 0;
|
virtual void copyFrom(const component& other) = 0;
|
||||||
|
|
||||||
/** Return the start position of this component in the
|
/** Return the start position of this component in the
|
||||||
* parsed message contents.
|
* parsed message contents. Use for debugging only.
|
||||||
*
|
*
|
||||||
* @return start position in parsed buffer
|
* @return start position in parsed buffer
|
||||||
* or 0 if this component has not been parsed
|
* or 0 if this component has not been parsed
|
||||||
*/
|
*/
|
||||||
string::size_type getParsedOffset() const;
|
utility::stream::size_type getParsedOffset() const;
|
||||||
|
|
||||||
/** Return the length of this component in the
|
/** Return the length of this component in the
|
||||||
* parsed message contents.
|
* parsed message contents. Use for debugging only.
|
||||||
*
|
*
|
||||||
* @return length of the component in parsed buffer
|
* @return length of the component in parsed buffer
|
||||||
* or 0 if this component has not been parsed
|
* or 0 if this component has not been parsed
|
||||||
*/
|
*/
|
||||||
string::size_type getParsedLength() const;
|
utility::stream::size_type getParsedLength() const;
|
||||||
|
|
||||||
/** Return the list of children of this component.
|
/** Return the list of children of this component.
|
||||||
*
|
*
|
||||||
* @return list of child components
|
* @return list of child components
|
||||||
*/
|
*/
|
||||||
const std::vector <ref <component> > getChildComponents();
|
virtual const std::vector <ref <component> > getChildComponents() = 0;
|
||||||
|
|
||||||
/** Return the list of children of this component (const version).
|
|
||||||
*
|
|
||||||
* @return list of child components
|
|
||||||
*/
|
|
||||||
virtual const std::vector <ref <const component> > getChildComponents() const = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void setParsedBounds(const string::size_type start, const string::size_type end);
|
void setParsedBounds(const utility::stream::size_type start, const utility::stream::size_type end);
|
||||||
|
|
||||||
|
// AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class
|
||||||
|
virtual void parseImpl
|
||||||
|
(ref <utility::parserInputStreamAdapter> parser,
|
||||||
|
const utility::stream::size_type position,
|
||||||
|
const utility::stream::size_type end,
|
||||||
|
utility::stream::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
virtual void parseImpl
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
virtual void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
string::size_type m_parsedOffset;
|
void offsetParsedBounds(const utility::stream::size_type offset);
|
||||||
string::size_type m_parsedLength;
|
|
||||||
|
utility::stream::size_type m_parsedOffset;
|
||||||
|
utility::stream::size_type m_parsedLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
contentDisposition& operator=(const contentDisposition& other);
|
contentDisposition& operator=(const contentDisposition& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
|
|
||||||
contentDisposition& operator=(const string& name);
|
contentDisposition& operator=(const string& name);
|
||||||
@ -75,14 +75,20 @@ private:
|
|||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,16 +237,22 @@ public:
|
|||||||
// Current date and time
|
// Current date and time
|
||||||
static const datetime now();
|
static const datetime now();
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
disposition& operator=(const disposition& other);
|
disposition& operator=(const disposition& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
|
|
||||||
/** Set the disposition action mode.
|
/** Set the disposition action mode.
|
||||||
@ -134,14 +134,20 @@ private:
|
|||||||
|
|
||||||
std::vector <string> m_modifiers;
|
std::vector <string> m_modifiers;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ public:
|
|||||||
bool operator==(const encoding& value) const;
|
bool operator==(const encoding& value) const;
|
||||||
bool operator!=(const encoding& value) const;
|
bool operator!=(const encoding& value) const;
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Decide which encoding to use based on the specified data.
|
/** Decide which encoding to use based on the specified data.
|
||||||
*
|
*
|
||||||
@ -141,14 +141,20 @@ private:
|
|||||||
*/
|
*/
|
||||||
static const encoding decideImpl(const string::const_iterator begin, const string::const_iterator end);
|
static const encoding decideImpl(const string::const_iterator begin, const string::const_iterator end);
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
header& operator=(const header& other);
|
header& operator=(const header& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -251,14 +251,20 @@ private:
|
|||||||
string m_name;
|
string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
headerField& operator=(const headerField& other);
|
headerField& operator=(const headerField& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Sets the name of this field.
|
/** Sets the name of this field.
|
||||||
*
|
*
|
||||||
@ -118,15 +118,26 @@ public:
|
|||||||
void setValue(const string& value);
|
void setValue(const string& value);
|
||||||
|
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static ref <headerField> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
|
|
||||||
|
static ref <headerField> parseNext
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
@ -85,7 +85,7 @@ public:
|
|||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
|
|
||||||
bool isGroup() const;
|
bool isGroup() const;
|
||||||
@ -101,8 +101,17 @@ public:
|
|||||||
using address::generate;
|
using address::generate;
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
ref <component> clone() const;
|
ref <component> clone() const;
|
||||||
mailboxGroup& operator=(const component& other);
|
mailboxGroup& operator=(const component& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Return the name of the group.
|
/** Return the name of the group.
|
||||||
*
|
*
|
||||||
@ -165,14 +165,20 @@ private:
|
|||||||
text m_name;
|
text m_name;
|
||||||
std::vector <ref <mailbox> > m_list;
|
std::vector <ref <mailbox> > m_list;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using address::parse;
|
|
||||||
using address::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
mailboxList& operator=(const mailboxList& other);
|
mailboxList& operator=(const mailboxList& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Add a mailbox at the end of the list.
|
/** Add a mailbox at the end of the list.
|
||||||
*
|
*
|
||||||
@ -155,14 +155,20 @@ private:
|
|||||||
|
|
||||||
addressList m_list;
|
addressList m_list;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
mediaType& operator=(const mediaType& other);
|
mediaType& operator=(const mediaType& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Return the media type.
|
/** Return the media type.
|
||||||
* See the constants in vmime::mediaTypes.
|
* See the constants in vmime::mediaTypes.
|
||||||
@ -97,14 +97,18 @@ protected:
|
|||||||
string m_type;
|
string m_type;
|
||||||
string m_subType;
|
string m_subType;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,12 +43,25 @@ public:
|
|||||||
message();
|
message();
|
||||||
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
public:
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(), const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
|
|
||||||
const string generate(const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(), const string::size_type curLinePos = 0) const;
|
// Override default generate() functions so that we can change
|
||||||
|
// the default 'maxLineLength' value
|
||||||
|
void generate
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(),
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
void parse(const string& buffer);
|
const string generate
|
||||||
|
(const string::size_type maxLineLength = options::getInstance()->message.maxLineLength(),
|
||||||
|
const string::size_type curLinePos = 0) const;
|
||||||
|
|
||||||
|
void generate
|
||||||
|
(ref <utility::outputStream> os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,23 +97,27 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
messageId& operator=(const messageId& other);
|
messageId& operator=(const messageId& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
string m_left;
|
string m_left;
|
||||||
string m_right;
|
string m_right;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
protected:
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
/** Parse a message-id from an input buffer.
|
/** Parse a message-id from an input buffer.
|
||||||
*
|
*
|
||||||
@ -123,7 +127,11 @@ protected:
|
|||||||
* @param newPosition will receive the new position in the input buffer
|
* @param newPosition will receive the new position in the input buffer
|
||||||
* @return a new message-id object, or null if no more message-id can be parsed from the input buffer
|
* @return a new message-id object, or null if no more message-id can be parsed from the input buffer
|
||||||
*/
|
*/
|
||||||
static ref <messageId> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition);
|
static ref <messageId> parseNext
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
messageIdSequence& operator=(const messageIdSequence& other);
|
messageIdSequence& operator=(const messageIdSequence& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
|
|
||||||
/** Add a message-id at the end of the list.
|
/** Add a message-id at the end of the list.
|
||||||
@ -148,14 +148,20 @@ private:
|
|||||||
|
|
||||||
std::vector <ref <messageId> > m_list;
|
std::vector <ref <messageId> > m_list;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
parameter& operator=(const parameter& other);
|
parameter& operator=(const parameter& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Return the name of this parameter.
|
/** Return the name of this parameter.
|
||||||
*
|
*
|
||||||
@ -104,7 +104,7 @@ public:
|
|||||||
const T getValueAs() const
|
const T getValueAs() const
|
||||||
{
|
{
|
||||||
T ret;
|
T ret;
|
||||||
ret.parse(m_value.getBuffer());
|
ret.parse(m_value->getBuffer());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -122,11 +122,19 @@ public:
|
|||||||
void setValue(const word& value);
|
void setValue(const word& value);
|
||||||
|
|
||||||
|
|
||||||
using component::parse;
|
protected:
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -134,7 +142,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
word m_value;
|
ref <word> m_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,19 +172,25 @@ public:
|
|||||||
*/
|
*/
|
||||||
const std::vector <ref <parameter> > getParameterList();
|
const std::vector <ref <parameter> > getParameterList();
|
||||||
|
|
||||||
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::vector <ref <parameter> > m_params;
|
std::vector <ref <parameter> > m_params;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using headerField::parse;
|
void parseImpl
|
||||||
using headerField::generate;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void generateImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ public:
|
|||||||
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
|
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isSpaceOrTab(const char_t c)
|
||||||
|
{
|
||||||
|
return (c == ' ' || c == '\t');
|
||||||
|
}
|
||||||
|
|
||||||
static bool isDigit(const char_t c)
|
static bool isDigit(const char_t c)
|
||||||
{
|
{
|
||||||
|
@ -76,21 +76,26 @@ public:
|
|||||||
ref <component> clone() const;
|
ref <component> clone() const;
|
||||||
path& operator=(const path& other);
|
path& operator=(const path& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
string m_localPart;
|
string m_localPart;
|
||||||
string m_domain;
|
string m_domain;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "vmime/utility/file.hpp"
|
#include "vmime/utility/file.hpp"
|
||||||
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
||||||
@ -57,7 +58,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class posixFileReaderInputStream : public vmime::utility::inputStream
|
class posixFileReaderInputStream : public vmime::utility::seekableInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -72,6 +73,9 @@ public:
|
|||||||
|
|
||||||
size_type skip(const size_type count);
|
size_type skip(const size_type count);
|
||||||
|
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const vmime::utility::file::path m_path;
|
const vmime::utility::file::path m_path;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "vmime/utility/file.hpp"
|
#include "vmime/utility/file.hpp"
|
||||||
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@ -157,6 +158,8 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
size_type read(value_type* const data, const size_type count);
|
size_type read(value_type* const data, const size_type count);
|
||||||
size_type skip(const size_type count);
|
size_type skip(const size_type count);
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
|||||||
void copyFrom(const component& other);
|
void copyFrom(const component& other);
|
||||||
relay& operator=(const relay& other);
|
relay& operator=(const relay& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
const string& getFrom() const;
|
const string& getFrom() const;
|
||||||
void setFrom(const string& from);
|
void setFrom(const string& from);
|
||||||
@ -85,13 +85,19 @@ private:
|
|||||||
|
|
||||||
datetime m_date;
|
datetime m_date;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
using component::parse;
|
void parseImpl
|
||||||
using component::generate;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void generateImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
text& operator=(const component& other);
|
text& operator=(const component& other);
|
||||||
text& operator=(const text& other);
|
text& operator=(const text& other);
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
/** Add a word at the end of the list.
|
/** Add a word at the end of the list.
|
||||||
*
|
*
|
||||||
@ -226,13 +226,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
static text* decodeAndUnfold(const string& in, text* generateInExisting);
|
static text* decodeAndUnfold(const string& in, text* generateInExisting);
|
||||||
|
|
||||||
|
protected:
|
||||||
using component::parse;
|
|
||||||
using component::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parseImpl
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED
|
#define VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "vmime/utility/inputStream.hpp"
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ namespace utility {
|
|||||||
/** An adapter class for C++ standard input streams.
|
/** An adapter class for C++ standard input streams.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class inputStreamAdapter : public inputStream
|
class inputStreamAdapter : public seekableInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -49,6 +49,8 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
size_type read(value_type* const data, const size_type count);
|
size_type read(value_type* const data, const size_type count);
|
||||||
size_type skip(const size_type count);
|
size_type skip(const size_type count);
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED
|
#define VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "vmime/utility/inputStream.hpp"
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
@ -35,7 +35,7 @@ namespace utility {
|
|||||||
/** An adapter class for reading from an array of bytes.
|
/** An adapter class for reading from an array of bytes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class inputStreamByteBufferAdapter : public inputStream
|
class inputStreamByteBufferAdapter : public seekableInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -45,6 +45,8 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
size_type read(value_type* const data, const size_type count);
|
size_type read(value_type* const data, const size_type count);
|
||||||
size_type skip(const size_type count);
|
size_type skip(const size_type count);
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
#define VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "vmime/utility/inputStream.hpp"
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
@ -35,7 +35,7 @@ namespace utility {
|
|||||||
/** An adapter class for string input.
|
/** An adapter class for string input.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class inputStreamStringAdapter : public inputStream
|
class inputStreamStringAdapter : public seekableInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -46,6 +46,8 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
size_type read(value_type* const data, const size_type count);
|
size_type read(value_type* const data, const size_type count);
|
||||||
size_type skip(const size_type count);
|
size_type skip(const size_type count);
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED
|
#define VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "vmime/utility/inputStream.hpp"
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime {
|
namespace vmime {
|
||||||
@ -38,7 +38,7 @@ class stringProxy;
|
|||||||
/** An adapter class for stringProxy input.
|
/** An adapter class for stringProxy input.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class inputStreamStringProxyAdapter : public inputStream
|
class inputStreamStringProxyAdapter : public seekableInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -50,6 +50,8 @@ public:
|
|||||||
void reset();
|
void reset();
|
||||||
size_type read(value_type* const data, const size_type count);
|
size_type read(value_type* const data, const size_type count);
|
||||||
size_type skip(const size_type count);
|
size_type skip(const size_type count);
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
173
vmime/utility/parserInputStreamAdapter.hpp
Normal file
173
vmime/utility/parserInputStreamAdapter.hpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED
|
||||||
|
#define VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
|
/** An adapter class used for parsing from an input stream.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class parserInputStreamAdapter : public seekableInputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** @param is input stream to wrap
|
||||||
|
*/
|
||||||
|
parserInputStreamAdapter(ref <seekableInputStream> inputStream);
|
||||||
|
|
||||||
|
ref <seekableInputStream> getUnderlyingStream();
|
||||||
|
|
||||||
|
bool eof() const;
|
||||||
|
void reset();
|
||||||
|
size_type read(value_type* const data, const size_type count);
|
||||||
|
|
||||||
|
void seek(const size_type pos)
|
||||||
|
{
|
||||||
|
m_stream->seek(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type skip(const size_type count)
|
||||||
|
{
|
||||||
|
return m_stream->skip(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type getPosition() const
|
||||||
|
{
|
||||||
|
return m_stream->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the byte at the current position without updating the
|
||||||
|
* current position.
|
||||||
|
*
|
||||||
|
* @return byte at the current position
|
||||||
|
*/
|
||||||
|
value_type peekByte() const
|
||||||
|
{
|
||||||
|
const size_type initialPos = m_stream->getPosition();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value_type buffer[1];
|
||||||
|
const size_type readBytes = m_stream->read(buffer, 1);
|
||||||
|
|
||||||
|
m_stream->seek(initialPos);
|
||||||
|
|
||||||
|
return (readBytes == 1 ? buffer[0] : 0);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
m_stream->seek(initialPos);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the byte at the current position and advance current
|
||||||
|
* position by one byte.
|
||||||
|
*
|
||||||
|
* @return byte at the current position
|
||||||
|
*/
|
||||||
|
value_type getByte()
|
||||||
|
{
|
||||||
|
value_type buffer[1];
|
||||||
|
const size_type readBytes = m_stream->read(buffer, 1);
|
||||||
|
|
||||||
|
return (readBytes == 1 ? buffer[0] : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check whether the bytes following the current position match
|
||||||
|
* the specified bytes. Position is not updated.
|
||||||
|
*
|
||||||
|
* @param bytes bytes to compare
|
||||||
|
* @param length number of bytes
|
||||||
|
* @return true if the next bytes match the pattern, false otherwise
|
||||||
|
*/
|
||||||
|
bool matchBytes(const value_type* bytes, const size_type length) const
|
||||||
|
{
|
||||||
|
const size_type initialPos = m_stream->getPosition();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value_type buffer[32];
|
||||||
|
const size_type readBytes = m_stream->read(buffer, length);
|
||||||
|
|
||||||
|
m_stream->seek(initialPos);
|
||||||
|
|
||||||
|
return readBytes == length &&
|
||||||
|
::memcmp(bytes, buffer, length) == 0;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
m_stream->seek(initialPos);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const string extract(const size_type begin, const size_type end) const;
|
||||||
|
|
||||||
|
/** Skips bytes matching a predicate from the current position.
|
||||||
|
* The current position is updated to the next following byte
|
||||||
|
* which does not match the predicate.
|
||||||
|
*
|
||||||
|
* @param pred predicate
|
||||||
|
* @param endPosition stop at this position (or at end of the stream,
|
||||||
|
* whichever comes first)
|
||||||
|
* @return number of bytes skipped
|
||||||
|
*/
|
||||||
|
template <typename PREDICATE>
|
||||||
|
size_type skipIf(PREDICATE pred, const size_type endPosition)
|
||||||
|
{
|
||||||
|
const size_type initialPos = getPosition();
|
||||||
|
size_type pos = initialPos;
|
||||||
|
|
||||||
|
while (!m_stream->eof() && pos < endPosition && pred(getByte()))
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
m_stream->seek(pos);
|
||||||
|
|
||||||
|
return pos - initialPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type findNext(const std::string& token, const size_type startPosition = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
mutable ref <seekableInputStream> m_stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // utility
|
||||||
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED
|
||||||
|
|
64
vmime/utility/seekableInputStream.hpp
Normal file
64
vmime/utility/seekableInputStream.hpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED
|
||||||
|
#define VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "vmime/utility/inputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
|
/** An input stream that allows seeking within the input.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class seekableInputStream : public inputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Returns the current position in this stream.
|
||||||
|
*
|
||||||
|
* @return the offset from the beginning of the stream, in bytes,
|
||||||
|
* at which the next read occurs
|
||||||
|
*/
|
||||||
|
virtual size_type getPosition() const = 0;
|
||||||
|
|
||||||
|
/** Sets the position, measured from the beginning of this stream,
|
||||||
|
* at which the next read occurs.
|
||||||
|
*
|
||||||
|
* @param pos the offset position, measured in bytes from the
|
||||||
|
* beginning of the stream, at which to set the stream pointer.
|
||||||
|
*/
|
||||||
|
virtual void seek(const size_type pos) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // utility
|
||||||
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED
|
||||||
|
|
71
vmime/utility/seekableInputStreamRegionAdapter.hpp
Normal file
71
vmime/utility/seekableInputStreamRegionAdapter.hpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://www.vmime.org)
|
||||||
|
// Copyright (C) 2002-2012 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 3 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License along
|
||||||
|
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Linking this library statically or dynamically with other modules is making
|
||||||
|
// a combined work based on this library. Thus, the terms and conditions of
|
||||||
|
// the GNU General Public License cover the whole combination.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED
|
||||||
|
#define VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "vmime/utility/seekableInputStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime {
|
||||||
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
|
/** An adapter for reading a limited region of a seekable input stream.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class seekableInputStreamRegionAdapter : public seekableInputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Creates a new adapter for a seekableInputStream.
|
||||||
|
*
|
||||||
|
* @param stream source stream
|
||||||
|
* @param begin start position in source stream
|
||||||
|
* @param length region length in source stream
|
||||||
|
*/
|
||||||
|
seekableInputStreamRegionAdapter(ref <seekableInputStream> stream,
|
||||||
|
const size_type begin, const size_type length);
|
||||||
|
|
||||||
|
bool eof() const;
|
||||||
|
void reset();
|
||||||
|
size_type read(value_type* const data, const size_type count);
|
||||||
|
size_type skip(const size_type count);
|
||||||
|
size_type getPosition() const;
|
||||||
|
void seek(const size_type pos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ref <seekableInputStream> m_stream;
|
||||||
|
size_type m_begin;
|
||||||
|
size_type m_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // utility
|
||||||
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED
|
||||||
|
|
@ -54,6 +54,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
typedef string::size_type size_type;
|
typedef string::size_type size_type;
|
||||||
|
|
||||||
|
/** Constant value with the greatest possible value for an element of type size_type.
|
||||||
|
*/
|
||||||
|
static const size_type npos;
|
||||||
|
|
||||||
/** Return the preferred maximum block size when reading
|
/** Return the preferred maximum block size when reading
|
||||||
* from or writing to this stream.
|
* from or writing to this stream.
|
||||||
*
|
*
|
||||||
|
@ -44,6 +44,19 @@ namespace utility {
|
|||||||
|
|
||||||
stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os);
|
stream::size_type bufferedStreamCopy(inputStream& is, outputStream& os);
|
||||||
|
|
||||||
|
/** Copy data from one stream into another stream using a buffered method
|
||||||
|
* and copying only a specified range of data.
|
||||||
|
*
|
||||||
|
* @param is input stream (source data)
|
||||||
|
* @param os output stream (destination for data)
|
||||||
|
* @param start number of bytes to ignore before starting copying
|
||||||
|
* @param length maximum number of bytes to copy
|
||||||
|
* @return number of bytes copied
|
||||||
|
*/
|
||||||
|
|
||||||
|
stream::size_type bufferedStreamCopyRange(inputStream& is, outputStream& os,
|
||||||
|
const stream::size_type start, const stream::size_type length);
|
||||||
|
|
||||||
/** Copy data from one stream into another stream using a buffered method
|
/** Copy data from one stream into another stream using a buffered method
|
||||||
* and notify progress state of the operation.
|
* and notify progress state of the operation.
|
||||||
*
|
*
|
||||||
|
@ -128,21 +128,52 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using component::parse;
|
protected:
|
||||||
|
|
||||||
|
void parseImpl
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition = NULL);
|
||||||
|
|
||||||
|
void generateImpl
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength = lineLengthLimits::infinite,
|
||||||
|
const string::size_type curLinePos = 0,
|
||||||
|
string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
using component::generate;
|
using component::generate;
|
||||||
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
#ifndef VMIME_BUILDING_DOC
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
void generate
|
||||||
|
(utility::outputStream& os,
|
||||||
|
const string::size_type maxLineLength,
|
||||||
|
const string::size_type curLinePos,
|
||||||
|
string::size_type* newLinePos,
|
||||||
|
const int flags,
|
||||||
|
generatorState* state) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos, const int flags, generatorState* state) const;
|
const std::vector <ref <component> > getChildComponents();
|
||||||
|
|
||||||
const std::vector <ref <const component> > getChildComponents() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, bool prevIsEncoded, bool* isEncoded, bool isFirst);
|
static ref <word> parseNext
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition,
|
||||||
|
bool prevIsEncoded,
|
||||||
|
bool* isEncoded,
|
||||||
|
bool isFirst);
|
||||||
|
|
||||||
static const std::vector <ref <word> > parseMultiple(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition);
|
static const std::vector <ref <word> > parseMultiple
|
||||||
|
(const string& buffer,
|
||||||
|
const string::size_type position,
|
||||||
|
const string::size_type end,
|
||||||
|
string::size_type* newPosition);
|
||||||
|
|
||||||
|
|
||||||
// The "m_buffer" of this word holds the data, and this data is encoded
|
// The "m_buffer" of this word holds the data, and this data is encoded
|
||||||
|
Loading…
Reference in New Issue
Block a user