aboutsummaryrefslogtreecommitdiffstats
path: root/src/component.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2012-04-16 20:32:33 +0000
committerVincent Richard <[email protected]>2012-04-16 20:32:33 +0000
commit4f33877820edee1b47d1b6f4fc800eaad273adaa (patch)
tree10d5d339f17f2561ef46993de308c2e7d8a9fd79 /src/component.cpp
parentSplit stream.hpp/.cpp into multiple source files. (diff)
downloadvmime-4f33877820edee1b47d1b6f4fc800eaad273adaa.tar.gz
vmime-4f33877820edee1b47d1b6f4fc800eaad273adaa.zip
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.
Diffstat (limited to 'src/component.cpp')
-rw-r--r--src/component.cpp137
1 files changed, 118 insertions, 19 deletions
diff --git a/src/component.cpp b/src/component.cpp
index 139cf664..e93aacf3 100644
--- a/src/component.cpp
+++ b/src/component.cpp
@@ -23,6 +23,9 @@
#include "vmime/component.hpp"
#include "vmime/base.hpp"
+
+#include "vmime/utility/streamUtils.hpp"
+#include "vmime/utility/inputStreamStringAdapter.hpp"
#include "vmime/utility/outputStreamAdapter.hpp"
#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)
{
- 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
{
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()
-{
- 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();
+} // vmime
- list.resize(count);
-
- for (std::vector <ref <const component> >::size_type i = 0 ; i < count ; ++i)
- list[i] = constList[i].constCast <component>();
-
- return (list);
-}
-
-
-}