diff --git a/ChangeLog b/ChangeLog index 70a25e5b..63a61f47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ VERSION 0.7.2cvs ================ +2005-09-03 Vincent Richard + + * encoder*, *contentHandler: added progression notifications. + 2005-08-25 Vincent Richard * Tests: moved to CppUnit for unit tests framework. diff --git a/SConstruct b/SConstruct index acd7d3ed..b3649ebe 100644 --- a/SConstruct +++ b/SConstruct @@ -153,7 +153,7 @@ libvmime_sources = [ 'utility/filteredStream.cpp', 'utility/filteredStream.hpp', 'utility/md5.cpp', 'utility/md5.hpp', 'utility/path.cpp', 'utility/path.hpp', - 'utility/progressionListener.hpp', + 'utility/progressionListener.cpp', 'utility/progressionListener.hpp', 'utility/random.cpp', 'utility/random.hpp', 'utility/smartPtr.hpp', 'utility/stream.cpp', 'utility/stream.hpp', diff --git a/src/emptyContentHandler.cpp b/src/emptyContentHandler.cpp index 57153fa9..beedb9d5 100644 --- a/src/emptyContentHandler.cpp +++ b/src/emptyContentHandler.cpp @@ -42,15 +42,29 @@ void emptyContentHandler::generate(utility::outputStream& /* os */, const vmime: } -void emptyContentHandler::extract(utility::outputStream& /* os */) const +void emptyContentHandler::extract(utility::outputStream& /* os */, + utility::progressionListener* progress) const { + if (progress) + progress->start(0); + // Nothing to do. + + if (progress) + progress->stop(0); } -void emptyContentHandler::extractRaw(utility::outputStream& /* os */) const +void emptyContentHandler::extractRaw(utility::outputStream& /* os */, + utility::progressionListener* progress) const { + if (progress) + progress->start(0); + // Nothing to do. + + if (progress) + progress->stop(0); } diff --git a/src/encoderB64.cpp b/src/encoderB64.cpp index bb78ac6a..9e290b57 100644 --- a/src/encoderB64.cpp +++ b/src/encoderB64.cpp @@ -70,7 +70,8 @@ const unsigned char encoderB64::sm_decodeMap[256] = -const utility::stream::size_type encoderB64::encode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderB64::encode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... @@ -88,9 +89,13 @@ const utility::stream::size_type encoderB64::encode(utility::inputStream& in, ut unsigned char output[4]; utility::stream::size_type total = 0; + utility::stream::size_type inTotal = 0; int curCol = 0; + if (progress) + progress->start(0); + while (bufferPos < bufferLength || !in.eof()) { if (bufferPos >= bufferLength) @@ -156,6 +161,7 @@ const utility::stream::size_type encoderB64::encode(utility::inputStream& in, ut // Write encoded data to output stream B64_WRITE(out, output, 4); + inTotal += count; total += 4; curCol += 4; @@ -164,13 +170,20 @@ const utility::stream::size_type encoderB64::encode(utility::inputStream& in, ut out.write("\r\n", 2); curCol = 0; } + + if (progress) + progress->progress(inTotal, inTotal); } + if (progress) + progress->stop(inTotal); + return (total); } -const utility::stream::size_type encoderB64::decode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderB64::decode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... @@ -180,10 +193,14 @@ const utility::stream::size_type encoderB64::decode(utility::inputStream& in, ut int bufferPos = 0; utility::stream::size_type total = 0; + utility::stream::size_type inTotal = 0; unsigned char bytes[4]; unsigned char output[3]; + if (progress) + progress->start(0); + while (bufferPos < bufferLength || !in.eof()) { bytes[0] = '='; @@ -265,8 +282,15 @@ const utility::stream::size_type encoderB64::decode(utility::inputStream& in, ut B64_WRITE(out, output, 3); total += 3; + inTotal += count; + + if (progress) + progress->progress(inTotal, inTotal); } + if (progress) + progress->stop(inTotal); + return (total); } diff --git a/src/encoderDefault.cpp b/src/encoderDefault.cpp index 26b63ba7..8a976c52 100644 --- a/src/encoderDefault.cpp +++ b/src/encoderDefault.cpp @@ -29,21 +29,37 @@ encoderDefault::encoderDefault() } -const utility::stream::size_type encoderDefault::encode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderDefault::encode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... // No encoding performed - return (utility::bufferedStreamCopy(in, out)); + utility::stream::size_type res = 0; + + if (progress) + res = utility::bufferedStreamCopy(in, out, 0, progress); + else + res = utility::bufferedStreamCopy(in, out); + + return res; } -const utility::stream::size_type encoderDefault::decode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderDefault::decode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... // No decoding performed - return (utility::bufferedStreamCopy(in, out)); + utility::stream::size_type res = 0; + + if (progress) + res = utility::bufferedStreamCopy(in, out, 0, progress); + else + res = utility::bufferedStreamCopy(in, out); + + return res; } diff --git a/src/encoderQP.cpp b/src/encoderQP.cpp index a021a051..edaf4a4a 100644 --- a/src/encoderQP.cpp +++ b/src/encoderQP.cpp @@ -85,7 +85,8 @@ const unsigned char encoderQP::sm_hexDecodeTable[256] = #endif // VMIME_BUILDING_DOC -const utility::stream::size_type encoderQP::encode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderQP::encode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... @@ -109,6 +110,10 @@ const utility::stream::size_type encoderQP::encode(utility::inputStream& in, uti int outBufferPos = 0; utility::stream::size_type total = 0; + utility::stream::size_type inTotal = 0; + + if (progress) + progress->start(0); while (bufferPos < bufferLength || !in.eof()) { @@ -267,6 +272,11 @@ const utility::stream::size_type encoderQP::encode(utility::inputStream& in, uti outBufferPos += 3; curCol = 0; } + + ++inTotal; + + if (progress) + progress->progress(inTotal, inTotal); } // Flush remaining output buffer @@ -276,11 +286,15 @@ const utility::stream::size_type encoderQP::encode(utility::inputStream& in, uti total += outBufferPos; } + if (progress) + progress->stop(inTotal); + return (total); } -const utility::stream::size_type encoderQP::decode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderQP::decode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... @@ -295,6 +309,7 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti int outBufferPos = 0; utility::stream::size_type total = 0; + utility::stream::size_type inTotal = 0; while (bufferPos < bufferLength || !in.eof()) { @@ -321,6 +336,8 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti // Decode the next sequence (hex-encoded byte or printable character) unsigned char c = static_cast (buffer[bufferPos++]); + ++inTotal; + switch (c) { case '=': @@ -335,6 +352,8 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti { c = static_cast (buffer[bufferPos++]); + ++inTotal; + switch (c) { // Ignore soft line break ("=\r\n" or "=\n") @@ -348,7 +367,10 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti } if (bufferPos < bufferLength) + { ++bufferPos; + ++inTotal; + } break; @@ -370,6 +392,8 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti { const unsigned char next = static_cast (buffer[bufferPos++]); + ++inTotal; + const unsigned char value = sm_hexDecodeTable[c] * 16 + sm_hexDecodeTable[next]; @@ -412,6 +436,9 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti } } + + if (progress) + progress->progress(inTotal, inTotal); } // Flush remaining output buffer @@ -421,6 +448,9 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti total += outBufferPos; } + if (progress) + progress->stop(inTotal); + return (total); } diff --git a/src/encoderUUE.cpp b/src/encoderUUE.cpp index 3e0ebea7..1312075f 100644 --- a/src/encoderUUE.cpp +++ b/src/encoderUUE.cpp @@ -59,7 +59,8 @@ static inline const unsigned char UUDECODE(const unsigned char c) } -const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... @@ -71,6 +72,7 @@ const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, ut static_cast (46)); utility::stream::size_type total = 0; + utility::stream::size_type inTotal = 0; // Output the prelude text ("begin [mode] [filename]") out << "begin"; @@ -88,6 +90,9 @@ const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, ut utility::stream::value_type inBuffer[64]; utility::stream::value_type outBuffer[64]; + if (progress) + progress->start(0); + while (!in.eof()) { // Process up to 45 characters per line @@ -117,16 +122,24 @@ const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, ut out.write(outBuffer, j + 2); total += j + 2; + inTotal += inLength; + + if (progress) + progress->progress(inTotal, inTotal); } out << "end\r\n"; total += 5; + if (progress) + progress->stop(inTotal); + return (total); } -const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, utility::outputStream& out) +const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, + utility::outputStream& out, utility::progressionListener* progress) { in.reset(); // may not work... @@ -135,11 +148,15 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut utility::stream::value_type outBuffer[64]; utility::stream::size_type total = 0; + utility::stream::size_type inTotal = 0; bool stop = false; std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); + if (progress) + progress->start(0); + while (!stop && !in.eof()) { // Get the line length @@ -175,6 +192,8 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut inBuffer[3] == 'n' && parserHelpers::isSpace(inBuffer[4])) { + inTotal += 5; + utility::stream::value_type c = 0; utility::stream::size_type count = 0; @@ -188,9 +207,15 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut buffer[count++] = c; } + inTotal += count; + if (c != '\n') { // OOPS! Weird line. Don't try to decode more... + + if (progress) + progress->stop(inTotal); + return (total); } @@ -240,6 +265,7 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut (inBuffer[2] == '\r' || inBuffer[2] == '\n')) { stop = true; + inTotal += 3; continue; } @@ -255,6 +281,8 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut break; } + inTotal += (inLength - inPos); + // Decode data for (utility::stream::size_type i = 0, j = 0 ; i < inLength ; i += 4, j += 3) { @@ -281,8 +309,14 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut out.write(outBuffer, outLength); std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); + + if (progress) + progress->progress(inTotal, inTotal); } + if (progress) + progress->stop(inTotal); + return (total); } diff --git a/src/streamContentHandler.cpp b/src/streamContentHandler.cpp index 0b9d33e3..bf417b6c 100644 --- a/src/streamContentHandler.cpp +++ b/src/streamContentHandler.cpp @@ -128,7 +128,8 @@ void streamContentHandler::generate(utility::outputStream& os, const vmime::enco } -void streamContentHandler::extract(utility::outputStream& os) const +void streamContentHandler::extract(utility::outputStream& os, + utility::progressionListener* progress) const { if (!m_stream) return; @@ -138,7 +139,10 @@ void streamContentHandler::extract(utility::outputStream& os) const { m_stream->reset(); // may not work... - utility::bufferedStreamCopy(*m_stream, os); + if (progress) + utility::bufferedStreamCopy(*m_stream, os, getLength(), progress); + else + utility::bufferedStreamCopy(*m_stream, os); } // Need to decode data else @@ -147,19 +151,25 @@ void streamContentHandler::extract(utility::outputStream& os) const m_stream->reset(); // may not work... - theDecoder->decode(*m_stream, os); + utility::progressionListenerSizeAdapter plsa(progress, getLength()); + + theDecoder->decode(*m_stream, os, &plsa); } } -void streamContentHandler::extractRaw(utility::outputStream& os) const +void streamContentHandler::extractRaw(utility::outputStream& os, + utility::progressionListener* progress) const { if (!m_stream) return; m_stream->reset(); // may not work... - utility::bufferedStreamCopy(*m_stream, os); + if (progress) + utility::bufferedStreamCopy(*m_stream, os, getLength(), progress); + else + utility::bufferedStreamCopy(*m_stream, os); } diff --git a/src/stringContentHandler.cpp b/src/stringContentHandler.cpp index 9c1553f4..92b7f51e 100644 --- a/src/stringContentHandler.cpp +++ b/src/stringContentHandler.cpp @@ -146,12 +146,13 @@ void stringContentHandler::generate(utility::outputStream& os, } -void stringContentHandler::extract(utility::outputStream& os) const +void stringContentHandler::extract(utility::outputStream& os, + utility::progressionListener* progress) const { // No decoding to perform if (!isEncoded()) { - m_string.extract(os); + m_string.extract(os, 0, m_string.length(), progress); } // Need to decode data else @@ -159,15 +160,17 @@ void stringContentHandler::extract(utility::outputStream& os) const ref theDecoder = m_encoding.getEncoder(); utility::inputStreamStringProxyAdapter in(m_string); + utility::progressionListenerSizeAdapter plsa(progress, getLength()); - theDecoder->decode(in, os); + theDecoder->decode(in, os, &plsa); } } -void stringContentHandler::extractRaw(utility::outputStream& os) const +void stringContentHandler::extractRaw(utility::outputStream& os, + utility::progressionListener* progress) const { - m_string.extract(os); + m_string.extract(os, 0, m_string.length(), progress); } diff --git a/src/utility/progressionListener.cpp b/src/utility/progressionListener.cpp new file mode 100644 index 00000000..9dde80da --- /dev/null +++ b/src/utility/progressionListener.cpp @@ -0,0 +1,75 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "vmime/utility/progressionListener.hpp" + + +namespace vmime { +namespace utility { + + +// progressionListenerSizeAdapter + +progressionListenerSizeAdapter::progressionListenerSizeAdapter + (progressionListener* list, const int total) + : m_wrapped(list), m_total(total) +{ +} + + +const bool progressionListenerSizeAdapter::cancel() const +{ + return (m_wrapped ? m_wrapped->cancel() : false); +} + + +void progressionListenerSizeAdapter::start(const int predictedTotal) +{ + if (m_wrapped) + m_wrapped->start(predictedTotal); +} + + +void progressionListenerSizeAdapter::progress(const int current, const int currentTotal) +{ + if (m_wrapped) + { + if (currentTotal > m_total) + m_total = currentTotal; + + m_wrapped->progress(current, m_total); + } +} + + +void progressionListenerSizeAdapter::stop(const int total) +{ + if (m_wrapped) + { + if (total > m_total) + m_total = total; + + m_wrapped->stop(m_total); + } +} + + +} // utility +} // vmime + diff --git a/src/utility/stringProxy.cpp b/src/utility/stringProxy.cpp index 798cbf1a..ef8a0cea 100644 --- a/src/utility/stringProxy.cpp +++ b/src/utility/stringProxy.cpp @@ -85,12 +85,26 @@ stringProxy& stringProxy::operator=(const string_type& s) } -void stringProxy::extract(outputStream& os, const size_type start, const size_type end) const +void stringProxy::extract(outputStream& os, const size_type start, const size_type end, + utility::progressionListener* progress) const { + size_type len = 0; + if (end == std::numeric_limits ::max()) - os.write(m_buffer.data() + m_start + start, m_end - start - m_start); - else - os.write(m_buffer.data() + m_start + start, end - start - m_start); + len = m_end - start - m_start; + else if (end > start) + len = end - start - m_start; + + if (progress) + progress->start(len); + + os.write(m_buffer.data() + m_start + start, len); + + if (progress) + { + progress->progress(len, len); + progress->stop(len); + } } diff --git a/vmime/contentHandler.hpp b/vmime/contentHandler.hpp index bdc2fde0..e680fce3 100644 --- a/vmime/contentHandler.hpp +++ b/vmime/contentHandler.hpp @@ -26,6 +26,7 @@ #include "vmime/base.hpp" #include "vmime/utility/stringProxy.hpp" #include "vmime/utility/smartPtr.hpp" +#include "vmime/utility/progressionListener.hpp" #include "vmime/encoding.hpp" @@ -66,16 +67,20 @@ public: * @throw exceptions::no_encoder_available if the encoding is * not supported * @param os output stream + * @param progress progression listener, or NULL if you do not + * want to receive progression notifications */ - virtual void extract(utility::outputStream& os) const = 0; + virtual void extract(utility::outputStream& os, utility::progressionListener* progress = NULL) const = 0; /** Extract the contents into the specified stream, without * decoding it. It may be useful in case the encoding is not * supported and you want to extract raw data. * * @param os output stream + * @param progress progression listener, or NULL if you do not + * want to receive progression notifications */ - virtual void extractRaw(utility::outputStream& os) const = 0; + virtual void extractRaw(utility::outputStream& os, utility::progressionListener* progress = NULL) const = 0; /** Returns the actual length of data. WARNING: this can return 0 if no * length was specified when setting data of this object. diff --git a/vmime/emptyContentHandler.hpp b/vmime/emptyContentHandler.hpp index 636bb691..00c1b97e 100644 --- a/vmime/emptyContentHandler.hpp +++ b/vmime/emptyContentHandler.hpp @@ -38,8 +38,8 @@ public: void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const; - void extract(utility::outputStream& os) const; - void extractRaw(utility::outputStream& os) const; + void extract(utility::outputStream& os, utility::progressionListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressionListener* progress = NULL) const; const string::size_type getLength() const; diff --git a/vmime/encoder.hpp b/vmime/encoder.hpp index a093b48d..689d1ce8 100644 --- a/vmime/encoder.hpp +++ b/vmime/encoder.hpp @@ -24,6 +24,7 @@ #include "vmime/base.hpp" #include "vmime/propertySet.hpp" #include "vmime/exception.hpp" +#include "vmime/utility/progressionListener.hpp" namespace vmime @@ -44,17 +45,21 @@ public: * * @param in input data (decoded) * @param out output stream for encoded data + * @param progress progression listener, or NULL if you do not + * want to receive progression notifications * @return number of bytes written into output stream */ - virtual const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out) = 0; + virtual const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL) = 0; /** Decode data. * * @param in input data (encoded) * @param out output stream for decoded data + * @param progress progression listener, or NULL if you do not + * want to receive progression notifications * @return number of bytes written into output stream */ - virtual const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out) = 0; + virtual const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL) = 0; /** Return the properties of the encoder. * diff --git a/vmime/encoderB64.hpp b/vmime/encoderB64.hpp index 5643b9c2..4ee45589 100644 --- a/vmime/encoderB64.hpp +++ b/vmime/encoderB64.hpp @@ -37,8 +37,8 @@ public: encoderB64(); - const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out); - const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out); + const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); + const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); const std::vector getAvailableProperties() const; diff --git a/vmime/encoderDefault.hpp b/vmime/encoderDefault.hpp index ae37eaf2..feb576da 100644 --- a/vmime/encoderDefault.hpp +++ b/vmime/encoderDefault.hpp @@ -37,8 +37,8 @@ public: encoderDefault(); - const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out); - const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out); + const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); + const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); }; diff --git a/vmime/encoderQP.hpp b/vmime/encoderQP.hpp index b1ce2327..1461c533 100644 --- a/vmime/encoderQP.hpp +++ b/vmime/encoderQP.hpp @@ -37,8 +37,8 @@ public: encoderQP(); - const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out); - const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out); + const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); + const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); const std::vector getAvailableProperties() const; diff --git a/vmime/encoderUUE.hpp b/vmime/encoderUUE.hpp index e54c1ce1..18747b7b 100644 --- a/vmime/encoderUUE.hpp +++ b/vmime/encoderUUE.hpp @@ -37,8 +37,8 @@ public: encoderUUE(); - const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out); - const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out); + const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); + const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out, utility::progressionListener* progress = NULL); const std::vector getAvailableProperties() const; }; diff --git a/vmime/streamContentHandler.hpp b/vmime/streamContentHandler.hpp index 3e668703..d7e39076 100644 --- a/vmime/streamContentHandler.hpp +++ b/vmime/streamContentHandler.hpp @@ -47,8 +47,8 @@ public: void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const; - void extract(utility::outputStream& os) const; - void extractRaw(utility::outputStream& os) const; + void extract(utility::outputStream& os, utility::progressionListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressionListener* progress = NULL) const; const string::size_type getLength() const; diff --git a/vmime/stringContentHandler.hpp b/vmime/stringContentHandler.hpp index f66a4b41..c2b4a718 100644 --- a/vmime/stringContentHandler.hpp +++ b/vmime/stringContentHandler.hpp @@ -65,8 +65,8 @@ public: void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const; - void extract(utility::outputStream& os) const; - void extractRaw(utility::outputStream& os) const; + void extract(utility::outputStream& os, utility::progressionListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressionListener* progress = NULL) const; const string::size_type getLength() const; diff --git a/vmime/utility/progressionListener.hpp b/vmime/utility/progressionListener.hpp index 24c2f35c..f5b50469 100644 --- a/vmime/utility/progressionListener.hpp +++ b/vmime/utility/progressionListener.hpp @@ -68,6 +68,35 @@ public: }; + +/** A progression listener used when total size is known by the + * receiver, but not by the notifier. + */ + +class progressionListenerSizeAdapter : public progressionListener +{ +public: + + /** Construct a new progressionListenerSizeAdapter object. + * + * @param list wrapped progression listener (can be NULL) + * @param total predicted total + */ + progressionListenerSizeAdapter(progressionListener* list, const int total); + + const bool cancel() const; + + void start(const int predictedTotal); + void progress(const int current, const int currentTotal); + void stop(const int total); + +private: + + progressionListener* m_wrapped; + int m_total; +}; + + } // utility } // vmime diff --git a/vmime/utility/stringProxy.hpp b/vmime/utility/stringProxy.hpp index 614468f1..8f334b31 100644 --- a/vmime/utility/stringProxy.hpp +++ b/vmime/utility/stringProxy.hpp @@ -25,6 +25,7 @@ #include "vmime/types.hpp" #include "vmime/utility/stream.hpp" +#include "vmime/utility/progressionListener.hpp" namespace vmime { @@ -58,7 +59,7 @@ public: // Extract some portion (or whole) of the string // and output it into a stream. - void extract(outputStream& os, const size_type start = 0, const size_type end = std::numeric_limits ::max()) const; + void extract(outputStream& os, const size_type start = 0, const size_type end = std::numeric_limits ::max(), utility::progressionListener* progress = NULL) const; // Return the "virtual" length of the string const size_type length() const;