diff options
Diffstat (limited to 'vmime-master/src/vmime/component.cpp')
-rw-r--r-- | vmime-master/src/vmime/component.cpp | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/component.cpp b/vmime-master/src/vmime/component.cpp new file mode 100644 index 0000000..7adf8f7 --- /dev/null +++ b/vmime-master/src/vmime/component.cpp @@ -0,0 +1,275 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard <vincent@vmime.org> +// +// 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/component.hpp" +#include "vmime/base.hpp" + +#include "vmime/utility/streamUtils.hpp" +#include "vmime/utility/inputStreamStringAdapter.hpp" +#include "vmime/utility/outputStreamAdapter.hpp" + +#include <sstream> + + +namespace vmime { + + +component::component() + : m_parsedOffset(0), m_parsedLength(0) { + +} + + +component::~component() { + +} + + +void component::parse( + const shared_ptr <utility::inputStream>& inputStream, + const size_t length +) { + + parse(inputStream, 0, length, NULL); +} + + +void component::parse( + const shared_ptr <utility::inputStream>& inputStream, + const size_t position, + const size_t end, + size_t* newPosition) { + + parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition); +} + + +void component::parse( + const parsingContext& ctx, + const shared_ptr <utility::inputStream>& inputStream, + const size_t position, + const size_t end, + size_t* newPosition +) { + + m_parsedOffset = m_parsedLength = 0; + + shared_ptr <utility::seekableInputStream> seekableStream = + dynamicCast <utility::seekableInputStream>(inputStream); + + if (!seekableStream || 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(ctx, buffer, 0, buffer.length(), NULL); + + } else { + + shared_ptr <utility::parserInputStreamAdapter> parser = + make_shared <utility::parserInputStreamAdapter>(seekableStream); + + parseImpl(ctx, parser, position, end, newPosition); + } +} + + +void component::parse(const string& buffer) { + + m_parsedOffset = m_parsedLength = 0; + + parseImpl(parsingContext::getDefaultContext(), buffer, 0, buffer.length(), NULL); +} + + +void component::parse(const parsingContext& ctx, const string& buffer) { + + m_parsedOffset = m_parsedLength = 0; + + parseImpl(ctx, buffer, 0, buffer.length(), NULL); +} + + +void component::parse( + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + + m_parsedOffset = m_parsedLength = 0; + + parseImpl(parsingContext::getDefaultContext(), buffer, position, end, newPosition); +} + + +void component::parse( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, size_t* newPosition +) { + + m_parsedOffset = m_parsedLength = 0; + + parseImpl(ctx, buffer, position, end, newPosition); +} + + +void component::offsetParsedBounds(const size_t offset) { + + // Offset parsed bounds of this component + if (m_parsedLength != 0) { + m_parsedOffset += offset; + } + + // Offset parsed bounds of our children + std::vector <shared_ptr <component> > children = getChildComponents(); + + for (size_t i = 0, n = children.size() ; i < n ; ++i) { + children[i]->offsetParsedBounds(offset); + } +} + + +void component::parseImpl( + const parsingContext& ctx, + const shared_ptr <utility::parserInputStreamAdapter>& parser, + const size_t position, + const size_t end, + size_t* newPosition +) { + + // This is the default implementation for parsing from an input stream: + // actually, we extract the substring and use the "parse from string" implementation + const string buffer = parser->extract(position, end); + parseImpl(ctx, buffer, 0, buffer.length(), newPosition); + + // Recursivey offset parsed bounds on children + if (position != 0) { + offsetParsedBounds(position); + } + + if (newPosition) { + *newPosition += position; + } +} + + +void component::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition) { + + // This is the default implementation for parsing from a string: + // actually, we encapsulate the string buffer in an input stream, then use + // the "parse from input stream" implementation + shared_ptr <utility::seekableInputStream> stream = + make_shared <utility::inputStreamStringAdapter>(buffer); + + shared_ptr <utility::parserInputStreamAdapter> parser = + make_shared <utility::parserInputStreamAdapter>(stream); + + parseImpl(ctx, parser, position, end, newPosition); +} + + +const string component::generate( + const size_t maxLineLength, + const size_t curLinePos +) const { + + std::ostringstream oss; + utility::outputStreamAdapter adapter(oss); + + generationContext ctx(generationContext::getDefaultContext()); + ctx.setMaxLineLength(maxLineLength); + + generateImpl(ctx, adapter, curLinePos, NULL); + + return oss.str(); +} + + +void component::generate( + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + + generateImpl(generationContext::getDefaultContext(), os, curLinePos, newLinePos); +} + + +void component::generate( + const generationContext& ctx, + utility::outputStream& outputStream, + const size_t curLinePos, + size_t* newLinePos +) const { + + generateImpl(ctx, outputStream, curLinePos, newLinePos); +} + + +size_t component::getParsedOffset() const { + + return m_parsedOffset; +} + + +size_t component::getParsedLength() const { + + return m_parsedLength; +} + + +void component::setParsedBounds(const size_t start, const size_t end) { + + m_parsedOffset = start; + m_parsedLength = end - start; +} + + +size_t component::getGeneratedSize(const generationContext& ctx) { + + std::vector <shared_ptr <component> > children = getChildComponents(); + size_t totalSize = 0; + + for (std::vector <shared_ptr <component> >::iterator it = children.begin() ; + it != children.end() ; ++it) { + + totalSize += (*it)->getGeneratedSize(ctx); + } + + return totalSize; +} + + +} // vmime |