diff options
Diffstat (limited to 'src/vmime/utility/encoder')
-rw-r--r-- | src/vmime/utility/encoder/b64Encoder.cpp | 181 | ||||
-rw-r--r-- | src/vmime/utility/encoder/b64Encoder.hpp | 18 | ||||
-rw-r--r-- | src/vmime/utility/encoder/binaryEncoder.cpp | 6 | ||||
-rw-r--r-- | src/vmime/utility/encoder/binaryEncoder.hpp | 5 | ||||
-rw-r--r-- | src/vmime/utility/encoder/eightBitEncoder.cpp | 6 | ||||
-rw-r--r-- | src/vmime/utility/encoder/eightBitEncoder.hpp | 5 | ||||
-rw-r--r-- | src/vmime/utility/encoder/encoder.cpp | 40 | ||||
-rw-r--r-- | src/vmime/utility/encoder/encoder.hpp | 17 | ||||
-rw-r--r-- | src/vmime/utility/encoder/encoderFactory.cpp | 73 | ||||
-rw-r--r-- | src/vmime/utility/encoder/encoderFactory.hpp | 29 | ||||
-rw-r--r-- | src/vmime/utility/encoder/noopEncoder.cpp | 37 | ||||
-rw-r--r-- | src/vmime/utility/encoder/noopEncoder.hpp | 18 | ||||
-rw-r--r-- | src/vmime/utility/encoder/qpEncoder.cpp | 469 | ||||
-rw-r--r-- | src/vmime/utility/encoder/qpEncoder.hpp | 18 | ||||
-rw-r--r-- | src/vmime/utility/encoder/sevenBitEncoder.cpp | 6 | ||||
-rw-r--r-- | src/vmime/utility/encoder/sevenBitEncoder.hpp | 3 | ||||
-rw-r--r-- | src/vmime/utility/encoder/uuEncoder.cpp | 274 | ||||
-rw-r--r-- | src/vmime/utility/encoder/uuEncoder.hpp | 18 |
18 files changed, 655 insertions, 568 deletions
diff --git a/src/vmime/utility/encoder/b64Encoder.cpp b/src/vmime/utility/encoder/b64Encoder.cpp index ddaa62f8..ef4e581e 100644 --- a/src/vmime/utility/encoder/b64Encoder.cpp +++ b/src/vmime/utility/encoder/b64Encoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,18 +30,18 @@ namespace utility { namespace encoder { -b64Encoder::b64Encoder() -{ +b64Encoder::b64Encoder() { + } -const std::vector <string> b64Encoder::getAvailableProperties() const -{ +const std::vector <string> b64Encoder::getAvailableProperties() const { + std::vector <string> list(encoder::getAvailableProperties()); list.push_back("maxlinelength"); - return (list); + return list; } @@ -49,8 +49,7 @@ const std::vector <string> b64Encoder::getAvailableProperties() const const unsigned char b64Encoder::sm_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; -const unsigned char b64Encoder::sm_decodeMap[256] = -{ +const unsigned char b64Encoder::sm_decodeMap[256] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0x00 - 0x0f 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0x10 - 0x1f 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f, // 0x20 - 0x2f @@ -75,9 +74,12 @@ const unsigned char b64Encoder::sm_decodeMap[256] = -size_t b64Encoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t b64Encoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... const size_t propMaxLineLength = @@ -99,72 +101,77 @@ size_t b64Encoder::encode(utility::inputStream& in, size_t curCol = 0; - if (progress) + if (progress) { progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { + + if (bufferPos >= bufferLength) { - while (bufferPos < bufferLength || !in.eof()) - { - if (bufferPos >= bufferLength) - { bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // Get 3 bytes of data int count = 0; - while (count < 3 && bufferPos < bufferLength) + while (count < 3 && bufferPos < bufferLength) { bytes[count++] = buffer[bufferPos++]; + } + + while (count < 3) { - while (count < 3) - { // There may be more data in the next chunk... - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } - while (count < 3 && bufferPos < bufferLength) + while (count < 3 && bufferPos < bufferLength) { bytes[count++] = buffer[bufferPos++]; + } } // Encode data - switch (count) - { - case 1: + switch (count) { - output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; - output[1] = sm_alphabet[(bytes[0] & 0x03) << 4]; - output[2] = sm_alphabet[64]; // padding - output[3] = sm_alphabet[64]; // padding + case 1: - break; + output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; + output[1] = sm_alphabet[(bytes[0] & 0x03) << 4]; + output[2] = sm_alphabet[64]; // padding + output[3] = sm_alphabet[64]; // padding - case 2: + break; - output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; - output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; - output[2] = sm_alphabet[(bytes[1] & 0x0F) << 2]; - output[3] = sm_alphabet[64]; // padding + case 2: - break; + output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; + output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; + output[2] = sm_alphabet[(bytes[1] & 0x0F) << 2]; + output[3] = sm_alphabet[64]; // padding - default: - case 3: + break; - output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; - output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; - output[2] = sm_alphabet[((bytes[1] & 0x0F) << 2) | ((bytes[2] & 0xC0) >> 6)]; - output[3] = sm_alphabet[(bytes[2] & 0x3F)]; + default: + case 3: - break; + output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; + output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; + output[2] = sm_alphabet[((bytes[1] & 0x0F) << 2) | ((bytes[2] & 0xC0) >> 6)]; + output[3] = sm_alphabet[(bytes[2] & 0x3F)]; + + break; } // Write encoded data to output stream @@ -174,26 +181,30 @@ size_t b64Encoder::encode(utility::inputStream& in, total += 4; curCol += 4; - if (cutLines && curCol + 2 /* \r\n */ + 4 /* next bytes */ >= maxLineLength) - { + if (cutLines && curCol + 2 /* \r\n */ + 4 /* next bytes */ >= maxLineLength) { out.write("\r\n", 2); curCol = 0; } - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t b64Encoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t b64Encoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // Process the data @@ -207,73 +218,78 @@ size_t b64Encoder::decode(utility::inputStream& in, byte_t bytes[4]; byte_t output[3]; - if (progress) + if (progress) { progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { - while (bufferPos < bufferLength || !in.eof()) - { bytes[0] = '='; bytes[1] = '='; bytes[2] = '='; bytes[3] = '='; // Need to get more data? - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; // No more data - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // 4 bytes of input provide 3 bytes of output, so // get the next 4 bytes from the input stream. int count = 0; - while (count < 4 && bufferPos < bufferLength) - { + while (count < 4 && bufferPos < bufferLength) { + const byte_t c = buffer[bufferPos++]; - if (!parserHelpers::isSpace(c)) + if (!parserHelpers::isSpace(c)) { bytes[count++] = c; + } } - if (count != 4) - { - while (count < 4 && !in.eof()) - { + if (count != 4) { + + while (count < 4 && !in.eof()) { + // Data continues on the next chunk bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; - while (count < 4 && bufferPos < bufferLength) - { + while (count < 4 && bufferPos < bufferLength) { + const byte_t c = buffer[bufferPos++]; - if (!parserHelpers::isSpace(c)) + if (!parserHelpers::isSpace(c)) { bytes[count++] = c; + } } } } - if (count != 4) // input length is not a multiple of 4 bytes + if (count != 4) { // input length is not a multiple of 4 bytes break; + } // Decode the bytes byte_t c1 = bytes[0]; byte_t c2 = bytes[1]; - if (c1 == '=' || c2 == '=') // end + if (c1 == '=' || c2 == '=') { // end break; + } output[0] = static_cast <byte_t>((sm_decodeMap[c1] << 2) | ((sm_decodeMap[c2] & 0x30) >> 4)); c1 = bytes[2]; - if (c1 == '=') // end - { + if (c1 == '=') { // end B64_WRITE(out, output, 1); total += 1; break; @@ -283,8 +299,7 @@ size_t b64Encoder::decode(utility::inputStream& in, c2 = bytes[3]; - if (c2 == '=') // end - { + if (c2 == '=') { // end B64_WRITE(out, output, 2); total += 2; break; @@ -296,19 +311,21 @@ size_t b64Encoder::decode(utility::inputStream& in, total += 3; inTotal += count; - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t b64Encoder::getEncodedSize(const size_t n) const -{ +size_t b64Encoder::getEncodedSize(const size_t n) const { + const size_t propMaxLineLength = getProperties().getProperty <size_t>("maxlinelength", static_cast <size_t>(-1)); @@ -321,8 +338,8 @@ size_t b64Encoder::getEncodedSize(const size_t n) const } -size_t b64Encoder::getDecodedSize(const size_t n) const -{ +size_t b64Encoder::getDecodedSize(const size_t n) const { + // 4 bytes of input provide 3 bytes of output return (n * 3) / 4; } diff --git a/src/vmime/utility/encoder/b64Encoder.hpp b/src/vmime/utility/encoder/b64Encoder.hpp index 2d23d9e3..c5be2c38 100644 --- a/src/vmime/utility/encoder/b64Encoder.hpp +++ b/src/vmime/utility/encoder/b64Encoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** Base64 encoder. */ +class VMIME_EXPORT b64Encoder : public encoder { -class VMIME_EXPORT b64Encoder : public encoder -{ public: b64Encoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); const std::vector <string> getAvailableProperties() const; diff --git a/src/vmime/utility/encoder/binaryEncoder.cpp b/src/vmime/utility/encoder/binaryEncoder.cpp index 7d7c40d1..b30bb7bb 100644 --- a/src/vmime/utility/encoder/binaryEncoder.cpp +++ b/src/vmime/utility/encoder/binaryEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace utility { namespace encoder { -binaryEncoder::binaryEncoder() -{ +binaryEncoder::binaryEncoder() { + } diff --git a/src/vmime/utility/encoder/binaryEncoder.hpp b/src/vmime/utility/encoder/binaryEncoder.hpp index 1c831939..331014e3 100644 --- a/src/vmime/utility/encoder/binaryEncoder.hpp +++ b/src/vmime/utility/encoder/binaryEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace encoder { /** Binary encoder. */ +class VMIME_EXPORT binaryEncoder : public noopEncoder { -class VMIME_EXPORT binaryEncoder : public noopEncoder -{ public: binaryEncoder(); diff --git a/src/vmime/utility/encoder/eightBitEncoder.cpp b/src/vmime/utility/encoder/eightBitEncoder.cpp index 4ab07f06..a9669319 100644 --- a/src/vmime/utility/encoder/eightBitEncoder.cpp +++ b/src/vmime/utility/encoder/eightBitEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace utility { namespace encoder { -eightBitEncoder::eightBitEncoder() -{ +eightBitEncoder::eightBitEncoder() { + } diff --git a/src/vmime/utility/encoder/eightBitEncoder.hpp b/src/vmime/utility/encoder/eightBitEncoder.hpp index ee50ca95..c400f512 100644 --- a/src/vmime/utility/encoder/eightBitEncoder.hpp +++ b/src/vmime/utility/encoder/eightBitEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace encoder { /** 8-bit encoder. */ +class VMIME_EXPORT eightBitEncoder : public noopEncoder { -class VMIME_EXPORT eightBitEncoder : public noopEncoder -{ public: eightBitEncoder(); diff --git a/src/vmime/utility/encoder/encoder.cpp b/src/vmime/utility/encoder/encoder.cpp index b4b13249..634adf0d 100644 --- a/src/vmime/utility/encoder/encoder.cpp +++ b/src/vmime/utility/encoder/encoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,44 +30,44 @@ namespace utility { namespace encoder { -encoder::encoder() -{ +encoder::encoder() { + } -encoder::~encoder() -{ +encoder::~encoder() { + } -const propertySet& encoder::getProperties() const -{ - return (m_props); +const propertySet& encoder::getProperties() const { + + return m_props; } -propertySet& encoder::getProperties() -{ - return (m_props); +propertySet& encoder::getProperties() { + + return m_props; } -const propertySet& encoder::getResults() const -{ - return (m_results); +const propertySet& encoder::getResults() const { + + return m_results; } -propertySet& encoder::getResults() -{ - return (m_results); +propertySet& encoder::getResults() { + + return m_results; } -const std::vector <string> encoder::getAvailableProperties() const -{ +const std::vector <string> encoder::getAvailableProperties() const { + std::vector <string> list; - return (list); + return list; } diff --git a/src/vmime/utility/encoder/encoder.hpp b/src/vmime/utility/encoder/encoder.hpp index 34cd10b7..134e813e 100644 --- a/src/vmime/utility/encoder/encoder.hpp +++ b/src/vmime/utility/encoder/encoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,9 +38,8 @@ namespace encoder { /** Encode/decode data in different encodings. */ +class VMIME_EXPORT encoder : public object { -class VMIME_EXPORT encoder : public object -{ public: encoder(); @@ -54,7 +53,11 @@ public: * want to receive progress notifications * @return number of bytes written into output stream */ - virtual size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL) = 0; + virtual size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ) = 0; /** Decode data. * @@ -64,7 +67,11 @@ public: * want to receive progress notifications * @return number of bytes written into output stream */ - virtual size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL) = 0; + virtual size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ) = 0; /** Return the properties of the encoder. * diff --git a/src/vmime/utility/encoder/encoderFactory.cpp b/src/vmime/utility/encoder/encoderFactory.cpp index 01ac7753..df655ae0 100644 --- a/src/vmime/utility/encoder/encoderFactory.cpp +++ b/src/vmime/utility/encoder/encoderFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,8 +37,8 @@ namespace utility { namespace encoder { -encoderFactory::encoderFactory() -{ +encoderFactory::encoderFactory() { + // Register some default encoders registerName <b64Encoder>("base64"); registerName <qpEncoder>("quoted-printable"); @@ -58,83 +58,88 @@ encoderFactory::encoderFactory() } -encoderFactory::~encoderFactory() -{ +encoderFactory::~encoderFactory() { + } -shared_ptr <encoderFactory> encoderFactory::getInstance() -{ +shared_ptr <encoderFactory> encoderFactory::getInstance() { + static encoderFactory instance; return shared_ptr <encoderFactory>(&instance, noop_shared_ptr_deleter <encoderFactory>()); } -shared_ptr <encoder> encoderFactory::create(const string& name) -{ - try - { +shared_ptr <encoder> encoderFactory::create(const string& name) { + + try { + return (getEncoderByName(name)->create()); - } - catch (exceptions::no_encoder_available &) { - if (m_defaultEncoder) + } catch (exceptions::no_encoder_available &) { + + if (m_defaultEncoder) { return m_defaultEncoder; + } throw; } } -const shared_ptr <const encoderFactory::registeredEncoder> encoderFactory::getEncoderByName(const string& name) const -{ +const shared_ptr <const encoderFactory::registeredEncoder> + encoderFactory::getEncoderByName(const string& name) const { + const string lcName(utility::stringUtils::toLower(name)); for (std::vector <shared_ptr <registeredEncoder> >::const_iterator it = m_encoders.begin() ; - it != m_encoders.end() ; ++it) - { - if ((*it)->getName() == lcName) + it != m_encoders.end() ; ++it) { + + if ((*it)->getName() == lcName) { return (*it); + } } throw exceptions::no_encoder_available(name); } -size_t encoderFactory::getEncoderCount() const -{ - return (m_encoders.size()); +size_t encoderFactory::getEncoderCount() const { + + return m_encoders.size(); } -const shared_ptr <const encoderFactory::registeredEncoder> encoderFactory::getEncoderAt(const size_t pos) const -{ - return (m_encoders[pos]); +const shared_ptr <const encoderFactory::registeredEncoder> + encoderFactory::getEncoderAt(const size_t pos) const { + + return m_encoders[pos]; } -const std::vector <shared_ptr <const encoderFactory::registeredEncoder> > encoderFactory::getEncoderList() const -{ +const std::vector <shared_ptr <const encoderFactory::registeredEncoder> > + encoderFactory::getEncoderList() const { + std::vector <shared_ptr <const registeredEncoder> > res; for (std::vector <shared_ptr <registeredEncoder> >::const_iterator it = m_encoders.begin() ; - it != m_encoders.end() ; ++it) - { + it != m_encoders.end() ; ++it) { + res.push_back(*it); } - return (res); + return res; } -void encoderFactory::setDefaultEncoder(const shared_ptr <encoder>& enc) -{ +void encoderFactory::setDefaultEncoder(const shared_ptr <encoder>& enc) { + m_defaultEncoder = enc; } -shared_ptr <encoder> encoderFactory::getDefaultEncoder() const -{ +shared_ptr <encoder> encoderFactory::getDefaultEncoder() const { + return m_defaultEncoder; } diff --git a/src/vmime/utility/encoder/encoderFactory.hpp b/src/vmime/utility/encoder/encoderFactory.hpp index 91121ad5..e475f8e8 100644 --- a/src/vmime/utility/encoder/encoderFactory.hpp +++ b/src/vmime/utility/encoder/encoderFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,7 +36,6 @@ namespace encoder { /** A factory to create 'encoder' objects for the specified encoding. */ - class VMIME_EXPORT encoderFactory { private: @@ -49,8 +48,8 @@ public: static shared_ptr <encoderFactory> getInstance(); /** Information about a registered encoder. */ - class VMIME_EXPORT registeredEncoder : public object - { + class VMIME_EXPORT registeredEncoder : public object { + protected: virtual ~registeredEncoder() { } @@ -65,20 +64,20 @@ public: private: template <class E> - class registeredEncoderImpl : public registeredEncoder - { + class registeredEncoderImpl : public registeredEncoder { + public: registeredEncoderImpl(const string& name) : m_name(name) { } - shared_ptr <encoder> create() const - { + shared_ptr <encoder> create() const { + return vmime::make_shared <E>(); } - const string& getName() const - { - return (m_name); + const string& getName() const { + + return m_name; } private: @@ -97,9 +96,11 @@ public: * @param name encoding name */ template <class E> - void registerName(const string& name) - { - m_encoders.push_back(vmime::make_shared <registeredEncoderImpl <E> >(utility::stringUtils::toLower(name))); + void registerName(const string& name) { + + m_encoders.push_back( + vmime::make_shared <registeredEncoderImpl <E> >(utility::stringUtils::toLower(name)) + ); } /** Create a new encoder instance from an encoding name. diff --git a/src/vmime/utility/encoder/noopEncoder.cpp b/src/vmime/utility/encoder/noopEncoder.cpp index 3d991b5d..30cc6c16 100644 --- a/src/vmime/utility/encoder/noopEncoder.cpp +++ b/src/vmime/utility/encoder/noopEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,14 +31,17 @@ namespace utility { namespace encoder { -noopEncoder::noopEncoder() -{ +noopEncoder::noopEncoder() { + } -size_t noopEncoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t noopEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // No encoding performed @@ -53,31 +56,35 @@ size_t noopEncoder::encode(utility::inputStream& in, } -size_t noopEncoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t noopEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // No decoding performed size_t res = 0; - if (progress) + if (progress) { res = utility::bufferedStreamCopy(in, out, 0, progress); - else + } else { res = utility::bufferedStreamCopy(in, out); + } return res; } -size_t noopEncoder::getEncodedSize(const size_t n) const -{ +size_t noopEncoder::getEncodedSize(const size_t n) const { + return n; } -size_t noopEncoder::getDecodedSize(const size_t n) const -{ +size_t noopEncoder::getDecodedSize(const size_t n) const { + return n; } diff --git a/src/vmime/utility/encoder/noopEncoder.hpp b/src/vmime/utility/encoder/noopEncoder.hpp index 6314812b..91944dee 100644 --- a/src/vmime/utility/encoder/noopEncoder.hpp +++ b/src/vmime/utility/encoder/noopEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** Default, no-op encoder (simple copy, no encoding/decoding is performed). */ +class VMIME_EXPORT noopEncoder : public encoder { -class VMIME_EXPORT noopEncoder : public encoder -{ public: noopEncoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); size_t getEncodedSize(const size_t n) const; size_t getDecodedSize(const size_t n) const; diff --git a/src/vmime/utility/encoder/qpEncoder.cpp b/src/vmime/utility/encoder/qpEncoder.cpp index fe252c89..4aeb6400 100644 --- a/src/vmime/utility/encoder/qpEncoder.cpp +++ b/src/vmime/utility/encoder/qpEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,13 +30,13 @@ namespace utility { namespace encoder { -qpEncoder::qpEncoder() -{ +qpEncoder::qpEncoder() { + } -const std::vector <string> qpEncoder::getAvailableProperties() const -{ +const std::vector <string> qpEncoder::getAvailableProperties() const { + std::vector <string> list(encoder::getAvailableProperties()); list.push_back("maxlinelength"); @@ -46,7 +46,7 @@ const std::vector <string> qpEncoder::getAvailableProperties() const list.push_back("rfc2047"); // for header fields encoding (RFC #2047) - return (list); + return list; } @@ -69,8 +69,7 @@ const unsigned char qpEncoder::sm_hexDigits[] = "0123456789ABCDEF"; // This is a quick lookup table: // '1' means "encode", '0' means "no encoding" // -const vmime_uint8 qpEncoder::sm_RFC2047EncodeTable[] = -{ +const vmime_uint8 qpEncoder::sm_RFC2047EncodeTable[] = { /* 0 NUL */ 1, /* 1 SOH */ 1, /* 2 STX */ 1, /* 3 ETX */ 1, /* 4 EOT */ 1, /* 5 ENQ */ 1, /* 6 ACK */ 1, /* 7 BEL */ 1, /* 8 BS */ 1, /* 9 TAB */ 1, /* 10 LF */ 1, /* 11 VT */ 1, /* 12 FF */ 1, /* 13 CR */ 1, /* 14 SO */ 1, /* 15 SI */ 1, /* 16 DLE */ 1, /* 17 DC1 */ 1, @@ -97,8 +96,7 @@ const vmime_uint8 qpEncoder::sm_RFC2047EncodeTable[] = // Hex-decoding table -const vmime_uint8 qpEncoder::sm_hexDecodeTable[256] = -{ +const vmime_uint8 qpEncoder::sm_hexDecodeTable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -119,30 +117,30 @@ const vmime_uint8 qpEncoder::sm_hexDecodeTable[256] = // static -bool qpEncoder::RFC2047_isEncodingNeededForChar(const byte_t c) -{ - return (c >= 128 || sm_RFC2047EncodeTable[c] != 0); +bool qpEncoder::RFC2047_isEncodingNeededForChar(const byte_t c) { + + return c >= 128 || sm_RFC2047EncodeTable[c] != 0; } // static -int qpEncoder::RFC2047_getEncodedLength(const byte_t c) -{ - if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) - { - if (c == 32) // space - { +int qpEncoder::RFC2047_getEncodedLength(const byte_t c) { + + if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) { + + if (c == 32) { // space + // Encoded as "_" return 1; - } - else - { + + } else { + // Hex encoding return 3; } - } - else - { + + } else { + return 1; // no encoding } } @@ -162,9 +160,12 @@ int qpEncoder::RFC2047_getEncodedLength(const byte_t c) #endif // VMIME_BUILDING_DOC -size_t qpEncoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t qpEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... const size_t propMaxLineLength = @@ -189,14 +190,15 @@ size_t qpEncoder::encode(utility::inputStream& in, size_t total = 0; size_t inTotal = 0; - if (progress) + if (progress) { progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { - while (bufferPos < bufferLength || !in.eof()) - { // Flush current output buffer - if (outBufferPos + 6 >= static_cast <int>(sizeof(outBuffer))) - { + if (outBufferPos + 6 >= static_cast <int>(sizeof(outBuffer))) { + QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; @@ -204,146 +206,146 @@ size_t qpEncoder::encode(utility::inputStream& in, } // Need to get more data? - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; // No more data - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // Get the next char and encode it const byte_t c = buffer[bufferPos++]; - if (rfc2047) - { - if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) - { - if (c == 32) // space - { + if (rfc2047) { + + if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) { + + if (c == 32) { // space + // RFC-2047, Page 5, 4.2. The "Q" encoding: // << The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be // represented as "_" (underscore, ASCII 95.). >> outBuffer[outBufferPos++] = '_'; ++curCol; - } - else - { + + } else { + // Other characters: '=' + hexadecimal encoding QP_ENCODE_HEX(c); } - } - else - { + + } else { + // No encoding outBuffer[outBufferPos++] = c; ++curCol; } - } - else - { - switch (c) - { - case 46: // . - { - if (curCol == 0) - { - // If a '.' appears at the beginning of a line, we encode it to - // to avoid problems with SMTP servers... ("\r\n.\r\n" means the - // end of data transmission). - QP_ENCODE_HEX('.'); - continue; - } - outBuffer[outBufferPos++] = '.'; - ++curCol; - break; - } - case 32: // space - { - // Need to get more data? - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } + } else { - // Spaces cannot appear at the end of a line. So, encode the space. - if (bufferPos >= bufferLength || - (buffer[bufferPos] == '\r' || buffer[bufferPos] == '\n')) - { - QP_ENCODE_HEX(' '); - } - else - { - outBuffer[outBufferPos++] = ' '; + switch (c) { + + case 46: { // . + + if (curCol == 0) { + // If a '.' appears at the beginning of a line, we encode it to + // to avoid problems with SMTP servers... ("\r\n.\r\n" means the + // end of data transmission). + QP_ENCODE_HEX('.'); + continue; + } + + outBuffer[outBufferPos++] = '.'; ++curCol; + break; } + case 32: { // space - break; - } - case 9: // TAB - { - QP_ENCODE_HEX(c); - break; - } - case 13: // CR - case 10: // LF - { - // RFC-2045/6.7(4) - - // Text data - if (text && !rfc2047) - { - outBuffer[outBufferPos++] = c; - ++curCol; + // Need to get more data? + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } + + // Spaces cannot appear at the end of a line. So, encode the space. + if (bufferPos >= bufferLength || + (buffer[bufferPos] == '\r' || buffer[bufferPos] == '\n')) { + + QP_ENCODE_HEX(' '); - if (c == 10) - curCol = 0; // reset current line length + } else { + + outBuffer[outBufferPos++] = ' '; + ++curCol; + } + + break; } - // Binary data - else - { + case 9: { // TAB + QP_ENCODE_HEX(c); + break; } + case 13: // CR + case 10: { // LF - break; - } - case 61: // = - { - QP_ENCODE_HEX('='); - break; - } - /* - Rule #2: (Literal representation) Octets with decimal values of 33 - through 60 inclusive, and 62 through 126, inclusive, MAY be - represented as the ASCII characters which correspond to those - octets (EXCLAMATION POINT through LESS THAN, and GREATER THAN - through TILDE, respectively). - */ - default: - - //if ((c >= 33 && c <= 60) || (c >= 62 && c <= 126)) - if (c >= 33 && c <= 126 && c != 61 && c != 63) - { - outBuffer[outBufferPos++] = c; - ++curCol; + // RFC-2045/6.7(4) + + // Text data + if (text && !rfc2047) { + + outBuffer[outBufferPos++] = c; + ++curCol; + + if (c == 10) { + curCol = 0; // reset current line length + } + + // Binary data + } else { + + QP_ENCODE_HEX(c); + } + + break; } - // Other characters: '=' + hexadecimal encoding - else - { - QP_ENCODE_HEX(c); + case 61: { // = + + QP_ENCODE_HEX('='); + break; } + /* + Rule #2: (Literal representation) Octets with decimal values of 33 + through 60 inclusive, and 62 through 126, inclusive, MAY be + represented as the ASCII characters which correspond to those + octets (EXCLAMATION POINT through LESS THAN, and GREATER THAN + through TILDE, respectively). + */ + default: - break; + //if ((c >= 33 && c <= 60) || (c >= 62 && c <= 126)) + if (c >= 33 && c <= 126 && c != 61 && c != 63) { + + outBuffer[outBufferPos++] = c; + ++curCol; + + // Other characters: '=' + hexadecimal encoding + } else { + + QP_ENCODE_HEX(c); + } + + break; } // switch (c) // Soft line break : "=\r\n" - if (cutLines && curCol >= maxLineLength - 1) - { + if (cutLines && curCol >= maxLineLength - 1) { + outBuffer[outBufferPos] = '='; outBuffer[outBufferPos + 1] = '\r'; outBuffer[outBufferPos + 2] = '\n'; @@ -356,27 +358,31 @@ size_t qpEncoder::encode(utility::inputStream& in, ++inTotal; - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } // Flush remaining output buffer - if (outBufferPos != 0) - { + if (outBufferPos != 0) { QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t qpEncoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t qpEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // Process the data @@ -392,11 +398,11 @@ size_t qpEncoder::decode(utility::inputStream& in, size_t total = 0; size_t inTotal = 0; - while (bufferPos < bufferLength || !in.eof()) - { + while (bufferPos < bufferLength || !in.eof()) { + // Flush current output buffer - if (outBufferPos >= sizeof(outBuffer)) - { + if (outBufferPos >= sizeof(outBuffer)) { + QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; @@ -404,14 +410,15 @@ size_t qpEncoder::decode(utility::inputStream& in, } // Need to get more data? - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; // No more data - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // Decode the next sequence (hex-encoded byte or printable character) @@ -419,124 +426,124 @@ size_t qpEncoder::decode(utility::inputStream& in, ++inTotal; - switch (c) - { - case '=': - { - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } + switch (c) { - if (bufferPos < bufferLength) - { - c = buffer[bufferPos++]; + case '=': { - ++inTotal; + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } - switch (c) - { - // Ignore soft line break ("=\r\n" or "=\n") - case '\r': + if (bufferPos < bufferLength) { - // Read one byte more - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } + c = buffer[bufferPos++]; - if (bufferPos < bufferLength) - { - ++bufferPos; - ++inTotal; - } + ++inTotal; - break; + switch (c) { - case '\n': + // Ignore soft line break ("=\r\n" or "=\n") + case '\r': - break; + // Read one byte more + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } - // Hex-encoded char - default: - { - // We need another byte... - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } + if (bufferPos < bufferLength) { + ++bufferPos; + ++inTotal; + } - if (bufferPos < bufferLength) - { - const byte_t next = buffer[bufferPos++]; + break; - ++inTotal; + case '\n': - const byte_t value = static_cast <byte_t> - (sm_hexDecodeTable[c] * 16 + sm_hexDecodeTable[next]); + break; + + // Hex-encoded char + default: + { + // We need another byte... + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } + + if (bufferPos < bufferLength) { + + const byte_t next = buffer[bufferPos++]; + + ++inTotal; + + const byte_t value = static_cast <byte_t>( + sm_hexDecodeTable[c] * 16 + sm_hexDecodeTable[next] + ); + + outBuffer[outBufferPos++] = value; + + } else { + + // Premature end-of-data + } + + break; + } - outBuffer[outBufferPos++] = value; - } - else - { - // Premature end-of-data } - break; - } + } else { + // Premature end-of-data } + + break; } - else - { - // Premature end-of-data - } + case '_': { - break; - } - case '_': - { - if (rfc2047) - { - // RFC-2047, Page 5, 4.2. The "Q" encoding: - // << Note that the "_" always represents hexadecimal 20, even if the SPACE - // character occupies a different code position in the character set in use. >> - outBuffer[outBufferPos++] = 0x20; + if (rfc2047) { + + // RFC-2047, Page 5, 4.2. The "Q" encoding: + // << Note that the "_" always represents hexadecimal 20, even if the SPACE + // character occupies a different code position in the character set in use. >> + outBuffer[outBufferPos++] = 0x20; + break; + } + + outBuffer[outBufferPos++] = c; break; } + default: { - // no break here... - } - default: - { - outBuffer[outBufferPos++] = c; - } + outBuffer[outBufferPos++] = c; + break; + } } - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } // Flush remaining output buffer - if (outBufferPos != 0) - { + if (outBufferPos != 0) { QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t qpEncoder::getEncodedSize(const size_t n) const -{ +size_t qpEncoder::getEncodedSize(const size_t n) const { + const size_t propMaxLineLength = getProperties().getProperty <size_t>("maxlinelength", static_cast <size_t>(-1)); @@ -549,8 +556,8 @@ size_t qpEncoder::getEncodedSize(const size_t n) const } -size_t qpEncoder::getDecodedSize(const size_t n) const -{ +size_t qpEncoder::getDecodedSize(const size_t n) const { + // Worst case: 1 byte of input equals 1 byte of output return n; } diff --git a/src/vmime/utility/encoder/qpEncoder.hpp b/src/vmime/utility/encoder/qpEncoder.hpp index c666795b..21263a6b 100644 --- a/src/vmime/utility/encoder/qpEncoder.hpp +++ b/src/vmime/utility/encoder/qpEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** Quoted-printable encoder. */ +class VMIME_EXPORT qpEncoder : public encoder { -class VMIME_EXPORT qpEncoder : public encoder -{ public: qpEncoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); const std::vector <string> getAvailableProperties() const; diff --git a/src/vmime/utility/encoder/sevenBitEncoder.cpp b/src/vmime/utility/encoder/sevenBitEncoder.cpp index 7c76d73f..999b11e5 100644 --- a/src/vmime/utility/encoder/sevenBitEncoder.cpp +++ b/src/vmime/utility/encoder/sevenBitEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace utility { namespace encoder { -sevenBitEncoder::sevenBitEncoder() -{ +sevenBitEncoder::sevenBitEncoder() { + } diff --git a/src/vmime/utility/encoder/sevenBitEncoder.hpp b/src/vmime/utility/encoder/sevenBitEncoder.hpp index d260cc7b..37f84a61 100644 --- a/src/vmime/utility/encoder/sevenBitEncoder.hpp +++ b/src/vmime/utility/encoder/sevenBitEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,7 +35,6 @@ namespace encoder { /** 7-bit encoder. */ - class VMIME_EXPORT sevenBitEncoder : public noopEncoder { public: diff --git a/src/vmime/utility/encoder/uuEncoder.cpp b/src/vmime/utility/encoder/uuEncoder.cpp index 0375a397..24dcdc8b 100644 --- a/src/vmime/utility/encoder/uuEncoder.cpp +++ b/src/vmime/utility/encoder/uuEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,16 +30,16 @@ namespace utility { namespace encoder { -uuEncoder::uuEncoder() -{ +uuEncoder::uuEncoder() { + getProperties()["mode"] = 644; getProperties()["filename"] = "no_name"; getProperties()["maxlinelength"] = 46; } -const std::vector <string> uuEncoder::getAvailableProperties() const -{ +const std::vector <string> uuEncoder::getAvailableProperties() const { + std::vector <string> list(encoder::getAvailableProperties()); list.push_back("maxlinelength"); @@ -47,26 +47,29 @@ const std::vector <string> uuEncoder::getAvailableProperties() const list.push_back("mode"); list.push_back("filename"); - return (list); + return list; } // This is the character encoding function to make a character printable -static inline byte_t UUENCODE(const unsigned int c) -{ +static inline byte_t UUENCODE(const unsigned int c) { + return static_cast <byte_t>((c & 077) + ' '); } // Single character decoding -static inline unsigned int UUDECODE(const unsigned int c) -{ +static inline unsigned int UUDECODE(const unsigned int c) { + return (c - ' ') & 077; } -size_t uuEncoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t uuEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... const string propFilename = getProperties().getProperty <string>("filename", ""); @@ -81,8 +84,7 @@ size_t uuEncoder::encode(utility::inputStream& in, // Output the prelude text ("begin [mode] [filename]") out << "begin"; - if (!propFilename.empty()) - { + if (!propFilename.empty()) { out << " " << propMode << " " << propFilename; total += 2 + propMode.length() + propFilename.length(); } @@ -94,11 +96,12 @@ size_t uuEncoder::encode(utility::inputStream& in, byte_t inBuffer[64]; byte_t outBuffer[64]; - if (progress) + if (progress) { progress->start(0); + } + + while (!in.eof()) { - while (!in.eof()) - { // Process up to 45 characters per line std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); @@ -108,8 +111,8 @@ size_t uuEncoder::encode(utility::inputStream& in, size_t j = 1; - for (size_t i = 0 ; i < inLength ; i += 3, j += 4) - { + for (size_t i = 0 ; i < inLength ; i += 3, j += 4) { + const byte_t c1 = inBuffer[i]; const byte_t c2 = inBuffer[i + 1]; const byte_t c3 = inBuffer[i + 2]; @@ -128,23 +131,28 @@ size_t uuEncoder::encode(utility::inputStream& in, total += j + 2; inTotal += inLength; - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } out << "end\r\n"; total += 5; - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t uuEncoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t uuEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // Process the data @@ -158,128 +166,131 @@ size_t uuEncoder::decode(utility::inputStream& in, std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); - if (progress) + if (progress) { progress->start(0); + } + + while (!stop && !in.eof()) { - while (!stop && !in.eof()) - { // Get the line length byte_t lengthChar; - if (in.read(&lengthChar, 1) == 0) + if (in.read(&lengthChar, 1) == 0) { break; + } const size_t outLength = UUDECODE(lengthChar); const size_t inLength = std::min((outLength * 4) / 3, static_cast <size_t>(64)); size_t inPos = 0; - switch (lengthChar) - { - case ' ': - case '\t': - case '\r': - case '\n': - { - // Ignore - continue; - } - case 'b': - { - // Read 5 characters more to check for begin ("begin ...\r\n" or "begin ...\n") - inPos = in.read(inBuffer, 5); - - if (inPos == 5 && - inBuffer[0] == 'e' && - inBuffer[1] == 'g' && - inBuffer[2] == 'i' && - inBuffer[3] == 'n' && - parserHelpers::isSpace(inBuffer[4])) - { - inTotal += 5; - - byte_t c = 0; - - size_t count = 0; - byte_t buffer[512]; - - while (count < sizeof(buffer) - 1 && in.read(&c, 1) == 1) - { - if (c == '\n') - break; - - buffer[count++] = c; - } + switch (lengthChar) { - inTotal += count; + case ' ': + case '\t': + case '\r': + case '\n': { - if (c != '\n') - { - // OOPS! Weird line. Don't try to decode more... + // Ignore + continue; + } + case 'b': { - if (progress) - progress->stop(inTotal); + // Read 5 characters more to check for begin ("begin ...\r\n" or "begin ...\n") + inPos = in.read(inBuffer, 5); - return (total); - } + if (inPos == 5 && + inBuffer[0] == 'e' && + inBuffer[1] == 'g' && + inBuffer[2] == 'i' && + inBuffer[3] == 'n' && + parserHelpers::isSpace(inBuffer[4])) { - // Parse filename and mode - if (count > 0) - { - buffer[count] = '\0'; + inTotal += 5; - byte_t* p = buffer; + byte_t c = 0; - while (*p && parserHelpers::isSpace(*p)) ++p; + size_t count = 0; + byte_t buffer[512]; - byte_t* modeStart = buffer; + while (count < sizeof(buffer) - 1 && in.read(&c, 1) == 1) { - while (*p && !parserHelpers::isSpace(*p)) ++p; + if (c == '\n') { + break; + } - getResults()["mode"] = string(modeStart, p); + buffer[count++] = c; + } - while (*p && parserHelpers::isSpace(*p)) ++p; + inTotal += count; - byte_t* filenameStart = buffer; + if (c != '\n') { - while (*p && !(*p == '\r' || *p == '\n')) ++p; + // OOPS! Weird line. Don't try to decode more... - getResults()["filename"] = string(filenameStart, p); - } - // No filename or mode specified - else - { - getResults()["filename"] = "untitled"; - getResults()["mode"] = 644; + if (progress) { + progress->stop(inTotal); + } + + return total; + } + + // Parse filename and mode + if (count > 0) { + + buffer[count] = '\0'; + + byte_t* p = buffer; + + while (*p && parserHelpers::isSpace(*p)) ++p; + + byte_t* modeStart = buffer; + + while (*p && !parserHelpers::isSpace(*p)) ++p; + + getResults()["mode"] = string(modeStart, p); + + while (*p && parserHelpers::isSpace(*p)) ++p; + + byte_t* filenameStart = buffer; + + while (*p && !(*p == '\r' || *p == '\n')) ++p; + + getResults()["filename"] = string(filenameStart, p); + + // No filename or mode specified + } else { + + getResults()["filename"] = "untitled"; + getResults()["mode"] = 644; + } + + continue; } - continue; + break; } + case 'e': { - break; - } - case 'e': - { - // Read 3 characters more to check for end ("end\r\n" or "end\n") - inPos = in.read(inBuffer, 3); - - if (inPos == 3 && - inBuffer[0] == 'n' && - inBuffer[1] == 'd' && - (inBuffer[2] == '\r' || inBuffer[2] == '\n')) - { - stop = true; - inTotal += 3; - continue; - } + // Read 3 characters more to check for end ("end\r\n" or "end\n") + inPos = in.read(inBuffer, 3); - break; - } + if (inPos == 3 && + inBuffer[0] == 'n' && + inBuffer[1] == 'd' && + (inBuffer[2] == '\r' || inBuffer[2] == '\n')) { + + stop = true; + inTotal += 3; + continue; + } + + break; + } } // Read encoded data - if (in.read(inBuffer + inPos, inLength - inPos) != inLength - inPos) - { + if (in.read(inBuffer + inPos, inLength - inPos) != inLength - inPos) { // Premature end of data break; } @@ -287,8 +298,8 @@ size_t uuEncoder::decode(utility::inputStream& in, inTotal += (inLength - inPos); // Decode data - for (size_t i = 0, j = 0 ; i < inLength ; i += 4, j += 3) - { + for (size_t i = 0, j = 0 ; i < inLength ; i += 4, j += 3) { + const byte_t c1 = inBuffer[i]; const byte_t c2 = inBuffer[i + 1]; const byte_t c3 = inBuffer[i + 2]; @@ -296,13 +307,14 @@ size_t uuEncoder::decode(utility::inputStream& in, const size_t n = std::min(inLength - i, static_cast <size_t>(3)); - switch (n) - { - default: - case 3: outBuffer[j + 2] = static_cast <byte_t>(UUDECODE(c3) << 6 | UUDECODE(c4)); - case 2: outBuffer[j + 1] = static_cast <byte_t>(UUDECODE(c2) << 4 | UUDECODE(c3) >> 2); - case 1: outBuffer[j] = static_cast <byte_t>(UUDECODE(c1) << 2 | UUDECODE(c2) >> 4); - case 0: break; + if (n >= 3) { + outBuffer[j + 2] = static_cast <byte_t>(UUDECODE(c3) << 6 | UUDECODE(c4)); + } + if (n >= 2) { + outBuffer[j + 1] = static_cast <byte_t>(UUDECODE(c2) << 4 | UUDECODE(c3) >> 2); + } + if (n >= 1) { + outBuffer[j] = static_cast <byte_t>(UUDECODE(c1) << 2 | UUDECODE(c2) >> 4); } total += n; @@ -312,19 +324,21 @@ size_t uuEncoder::decode(utility::inputStream& in, std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t uuEncoder::getEncodedSize(const size_t n) const -{ +size_t uuEncoder::getEncodedSize(const size_t n) const { + // 3 bytes of input provide 4 bytes of output. // Count CRLF (2 bytes) for each line of 45 characters. // Also reserve some space for header and footer. @@ -332,8 +346,8 @@ size_t uuEncoder::getEncodedSize(const size_t n) const } -size_t uuEncoder::getDecodedSize(const size_t n) const -{ +size_t uuEncoder::getDecodedSize(const size_t n) const { + // 4 bytes of input provide 3 bytes of output return (n * 3) / 4; } diff --git a/src/vmime/utility/encoder/uuEncoder.hpp b/src/vmime/utility/encoder/uuEncoder.hpp index 7365263c..841cf660 100644 --- a/src/vmime/utility/encoder/uuEncoder.hpp +++ b/src/vmime/utility/encoder/uuEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// Copyright (C) 2002 Vincent Richard <[email protected]> // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** UUEncode encoder. */ +class VMIME_EXPORT uuEncoder : public encoder { -class VMIME_EXPORT uuEncoder : public encoder -{ public: uuEncoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); const std::vector <string> getAvailableProperties() const; |