diff options
Diffstat (limited to 'src/encoderQP.cpp')
| -rw-r--r-- | src/encoderQP.cpp | 469 |
1 files changed, 0 insertions, 469 deletions
diff --git a/src/encoderQP.cpp b/src/encoderQP.cpp deleted file mode 100644 index 95ca331c..00000000 --- a/src/encoderQP.cpp +++ /dev/null @@ -1,469 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2008 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 -// 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., -// 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/encoderQP.hpp" -#include "vmime/parserHelpers.hpp" - - -namespace vmime -{ - - -encoderQP::encoderQP() -{ -} - - -const std::vector <string> encoderQP::getAvailableProperties() const -{ - std::vector <string> list(encoder::getAvailableProperties()); - - list.push_back("maxlinelength"); - - list.push_back("text"); // if set, '\r' and '\n' are not hex-encoded. - // WARNING! You should not use this for binary data! - - list.push_back("rfc2047"); // for header fields encoding (RFC #2047) - - return (list); -} - - - -// Encoding table -const unsigned char encoderQP::sm_hexDigits[] = "0123456789ABCDEF"; - -// Decoding table -const unsigned char encoderQP::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, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 15, 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, 10, 11, 12, 13, 14, 15, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -#ifndef VMIME_BUILDING_DOC - -#define QP_ENCODE_HEX(x) \ - outBuffer[outBufferPos] = '='; \ - outBuffer[outBufferPos + 1] = sm_hexDigits[x >> 4]; \ - outBuffer[outBufferPos + 2] = sm_hexDigits[x & 0xF]; \ - outBufferPos += 3; \ - curCol += 3; - -#define QP_WRITE(s, x, l) s.write(reinterpret_cast <utility::stream::value_type*>(x), l) - -#endif // VMIME_BUILDING_DOC - - -utility::stream::size_type encoderQP::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ - in.reset(); // may not work... - - const string::size_type propMaxLineLength = - getProperties().getProperty <string::size_type>("maxlinelength", static_cast <string::size_type>(-1)); - - const bool rfc2047 = getProperties().getProperty <bool>("rfc2047", false); - const bool text = getProperties().getProperty <bool>("text", false); // binary mode by default - - const bool cutLines = (propMaxLineLength != static_cast <string::size_type>(-1)); - const string::size_type maxLineLength = std::min(propMaxLineLength, static_cast <string::size_type>(74)); - - // Process the data - char buffer[16384]; - int bufferLength = 0; - int bufferPos = 0; - - string::size_type curCol = 0; - - unsigned char outBuffer[16384]; - 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()) - { - // Flush current output buffer - if (outBufferPos + 6 >= static_cast <int>(sizeof(outBuffer))) - { - QP_WRITE(out, outBuffer, outBufferPos); - - total += outBufferPos; - outBufferPos = 0; - } - - // Need to get more data? - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - - // No more data - if (bufferLength == 0) - break; - } - - // Get the next char and encode it - const unsigned char c = static_cast <unsigned char>(buffer[bufferPos++]); - - switch (c) - { - case '.': - { - if (!rfc2047 && 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 ' ': - { - // 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.). >> - if (rfc2047) - { - outBuffer[outBufferPos++] = '_'; - ++curCol; - } - else - { - // 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(' '); - } - else - { - outBuffer[outBufferPos++] = ' '; - ++curCol; - } - } - - break; - } - case '\t': - { - QP_ENCODE_HEX(c) - break; - } - case '\r': - case '\n': - { - // Text mode (where using CRLF or LF or ... does not - // care for a new line...) - if (text) - { - outBuffer[outBufferPos++] = c; - ++curCol; - } - // Binary mode (where CR and LF bytes are important!) - else - { - QP_ENCODE_HEX(c) - } - - break; - } - case '=': - { - QP_ENCODE_HEX('=') - break; - } - // RFC-2047 'especials' characters - case ',': - case ';': - case ':': - case '_': - case '@': - case '(': - case ')': - case '<': - case '>': - case '[': - case ']': - { - if (rfc2047) - { - QP_ENCODE_HEX(c) - } - else - { - outBuffer[outBufferPos++] = c; - ++curCol; - } - - 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; - } - // Other characters: '=' + hexadecimal encoding - else - { - QP_ENCODE_HEX(c) - } - - break; - } - - } - - // Soft line break : "=\r\n" - if (cutLines && curCol >= maxLineLength - 1) - { - outBuffer[outBufferPos] = '='; - outBuffer[outBufferPos + 1] = '\r'; - outBuffer[outBufferPos + 2] = '\n'; - - outBufferPos += 3; - curCol = 0; - } - - ++inTotal; - - if (progress) - progress->progress(inTotal, inTotal); - } - - // Flush remaining output buffer - if (outBufferPos != 0) - { - QP_WRITE(out, outBuffer, outBufferPos); - total += outBufferPos; - } - - if (progress) - progress->stop(inTotal); - - return (total); -} - - -utility::stream::size_type encoderQP::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ - in.reset(); // may not work... - - // Process the data - const bool rfc2047 = getProperties().getProperty <bool>("rfc2047", false); - - char buffer[16384]; - int bufferLength = 0; - int bufferPos = 0; - - unsigned char outBuffer[16384]; - int outBufferPos = 0; - - utility::stream::size_type total = 0; - utility::stream::size_type inTotal = 0; - - while (bufferPos < bufferLength || !in.eof()) - { - // Flush current output buffer - if (outBufferPos >= static_cast <int>(sizeof(outBuffer))) - { - QP_WRITE(out, outBuffer, outBufferPos); - - total += outBufferPos; - outBufferPos = 0; - } - - // Need to get more data? - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - - // No more data - if (bufferLength == 0) - break; - } - - // Decode the next sequence (hex-encoded byte or printable character) - unsigned char c = static_cast <unsigned char>(buffer[bufferPos++]); - - ++inTotal; - - switch (c) - { - case '=': - { - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } - - if (bufferPos < bufferLength) - { - c = static_cast <unsigned char>(buffer[bufferPos++]); - - ++inTotal; - - switch (c) - { - // Ignore soft line break ("=\r\n" or "=\n") - case '\r': - - // Read one byte more - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } - - if (bufferPos < bufferLength) - { - ++bufferPos; - ++inTotal; - } - - break; - - case '\n': - - break; - - // Hex-encoded char - default: - { - // We need another byte... - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } - - if (bufferPos < bufferLength) - { - const unsigned char next = static_cast <unsigned char>(buffer[bufferPos++]); - - ++inTotal; - - const unsigned char value = static_cast <unsigned char> - (sm_hexDecodeTable[c] * 16 + sm_hexDecodeTable[next]); - - outBuffer[outBufferPos++] = value; - } - else - { - // Premature end-of-data - } - - break; - } - - } - } - else - { - // Premature end-of-data - } - - 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; - break; - } - - // no break here... - } - default: - { - outBuffer[outBufferPos++] = c; - } - - } - - if (progress) - progress->progress(inTotal, inTotal); - } - - // Flush remaining output buffer - if (outBufferPos != 0) - { - QP_WRITE(out, outBuffer, outBufferPos); - total += outBufferPos; - } - - if (progress) - progress->stop(inTotal); - - return (total); -} - - -} // vmime |
