diff options
author | Wojtek Kosior <wk@koszkonutek-tmp.pl.eu.org> | 2021-04-30 00:33:56 +0200 |
---|---|---|
committer | Wojtek Kosior <wk@koszkonutek-tmp.pl.eu.org> | 2021-04-30 00:33:56 +0200 |
commit | aa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch) | |
tree | 4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /vmime-master/src/vmime/utility | |
download | smtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.tar.gz smtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.zip |
Diffstat (limited to 'vmime-master/src/vmime/utility')
70 files changed, 8940 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/utility/childProcess.hpp b/vmime-master/src/vmime/utility/childProcess.hpp new file mode 100644 index 0000000..b72ab85 --- /dev/null +++ b/vmime-master/src/vmime/utility/childProcess.hpp @@ -0,0 +1,103 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED +#define VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED + + +#include "vmime/utility/stream.hpp" +#include "vmime/utility/file.hpp" + +#include <vector> + + +namespace vmime { +namespace utility { + + +/** Spawn a process and redirect its standard input + * and/or standard output. + */ +class VMIME_EXPORT childProcess : public object { + +public: + + virtual ~childProcess() { } + + /** Flags used with start(). */ + enum Flags { + FLAG_REDIRECT_STDIN = (1 << 0), + FLAG_REDIRECT_STDOUT = (1 << 1) + }; + + /** Start the child process. + * + * @param args list of arguments + * @param flags one or more childProcess::Flags + * @throws exceptions::system_error if the an error occurs + * before the process can be started + */ + virtual void start(const std::vector <string>& args, const int flags = 0) = 0; + + /** Return a wrapper to the child process standard input. + * + * @return output stream wrapper for child's stdin + */ + virtual shared_ptr <utility::outputStream> getStdIn() = 0; + + /** Return a wrapper to the child process standard output. + * + * @return input stream wrapper for child's stdout + */ + virtual shared_ptr <utility::inputStream> getStdOut() = 0; + + /** Wait for the process to finish. + * + * @throws exceptions::system_error if the process does + * not exit normally + */ + virtual void waitForFinish() = 0; +}; + + +/** Create 'childProcess' objects. + */ +class childProcessFactory : public object { + +public: + + virtual ~childProcessFactory() { } + + /** Create a new child process. + * + * @param path full path of the process executable file + */ + virtual shared_ptr <childProcess> create(const utility::file::path& path) const = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/datetimeUtils.cpp b/vmime-master/src/vmime/utility/datetimeUtils.cpp new file mode 100644 index 0000000..b1a6c55 --- /dev/null +++ b/vmime-master/src/vmime/utility/datetimeUtils.cpp @@ -0,0 +1,317 @@ +// +// 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/utility/datetimeUtils.hpp" + +#include <stdexcept> + + +namespace vmime { +namespace utility { + + +#ifndef VMIME_BUILDING_DOC + +static inline void nextMonth(datetime& d) { + + if (d.getMonth() >= 12) { + d.setMonth(1); + d.setYear(d.getYear() + 1); + } else { + d.setMonth(d.getMonth() + 1); + } +} + + +static inline void prevMonth(datetime& d) { + + if (d.getMonth() <= 1) { + d.setYear(d.getYear() - 1); + d.setMonth(12); + } else { + d.setMonth(d.getMonth() - 1); + } +} + + +static inline void nextDay(datetime& d) { + + if (d.getDay() >= datetimeUtils::getDaysInMonth(d.getYear(), d.getMonth())) { + d.setDay(1); + nextMonth(d); + } else { + d.setDay(d.getDay() + 1); + } +} + + +static inline void prevDay(datetime& d) { + + if (d.getDay() <= 1) { + prevMonth(d); + d.setDay(datetimeUtils::getDaysInMonth(d.getYear(), d.getMonth())); + } else { + d.setDay(d.getDay() - 1); + } +} + + +static inline void nextHour(datetime& d) { + + if (d.getHour() >= 23) { + d.setHour(0); + nextDay(d); + } else { + d.setHour(d.getHour() + 1); + } +} + + +static inline void prevHour(datetime& d) { + + if (d.getHour() <= 0) { + d.setHour(23); + prevDay(d); + } else { + d.setHour(d.getHour() - 1); + } +} + + +static inline void addHoursAndMinutes(datetime& d, const int h, const int m) { + + d.setMinute(d.getMinute() + m); + + if (d.getMinute() >= 60) { + d.setMinute(d.getMinute() - 60); + nextHour(d); + } + + d.setHour(d.getHour() + h); + + if (d.getHour() >= 24) { + d.setHour(d.getHour() - 24); + nextDay(d); + } +} + + +static inline void substractHoursAndMinutes(datetime& d, const int h, const int m) { + + if (m > d.getMinute()) { + d.setMinute(60 - (m - d.getMinute())); + prevHour(d); + } else { + d.setMinute(d.getMinute() - m); + } + + if (h > d.getHour()) { + d.setHour(24 - (h - d.getHour())); + prevDay(d); + } else { + d.setHour(d.getHour() - h); + } +} + +#endif // VMIME_BUILDING_DOC + + +const datetime datetimeUtils::toUniversalTime(const datetime& date) { + + if (date.getZone() == datetime::GMT) { + return date; // no conversion needed + } + + datetime nd(date); + nd.setZone(datetime::GMT); + + const int z = date.getZone(); + const int h = (z < 0) ? (-z / 60) : (z / 60); + const int m = (z < 0) ? (-z - h * 60) : (z - h * 60); + + if (z < 0) { // GMT-hhmm: add hours and minutes to date + addHoursAndMinutes(nd, h, m); + } else { // GMT+hhmm: substract hours and minutes from date + substractHoursAndMinutes(nd, h, m); + } + + return nd; +} + + +const datetime datetimeUtils::toLocalTime(const datetime& date, const int zone) { + + datetime utcDate(date); + + if (utcDate.getZone() != datetime::GMT) { + utcDate = toUniversalTime(date); // convert to UT before + } + + datetime nd(utcDate); + nd.setZone(zone); + + const int h = (zone < 0) ? (-zone / 60) : (zone / 60); + const int m = (zone < 0) ? (-zone - h * 60) : (zone - h * 60); + + if (zone < 0) { // GMT+hhmm: substract hours and minutes from date + substractHoursAndMinutes(nd, h, m); + } else { // GMT-hhmm: add hours and minutes to date + addHoursAndMinutes(nd, h, m); + } + + return nd; +} + + +bool datetimeUtils::isLeapYear(const int year) { + + // From RFC 3339 - Appendix C. Leap Years: + return ((year % 4) == 0 && (year % 100 != 0 || year % 400 == 0)); +} + + +int datetimeUtils::getDaysInMonth(const int year, const int month) { + + static const int daysInMonth[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static const int daysInMonthLeapYear[12] = { + 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + + if (month < 1 || month > 12) { + throw std::out_of_range("Invalid month number"); + } + + return isLeapYear(year) ? daysInMonthLeapYear[month - 1] : daysInMonth[month - 1]; +} + + +int datetimeUtils::getDayOfWeek(const int year, const int month, const int day) { + + int y = year; + int m = month; + + if (month < 1 || month > 12) { + throw std::out_of_range("Invalid month number"); + } else if (day < 1 || day > getDaysInMonth(year, month)) { + throw std::out_of_range("Invalid day number"); + } + + // From RFC-3339 - Appendix B. Day of the Week + + // Adjust months so February is the last one + m -= 2; + + if (m < 1) { + m += 12; + --y; + } + + // Split by century + const int cent = y / 100; + y %= 100; + + return ((26 * m - 2) / 10 + day + y + (y >> 2) + (cent >> 2) + 5 * cent) % 7; +} + + +int datetimeUtils::getWeekOfYear(const int year, const int month, const int day, const bool iso) { + + // Algorithm from http://personal.ecu.edu/mccartyr/ISOwdALG.txt + + const bool leapYear = ((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0; + const bool leapYear_1 = (((year - 1) % 4) == 0 && ((year - 1) % 100) != 0) || ((year - 1) % 400) == 0; + + // 4. Find the DayOfYearNumber for Y M D + static const int DAY_OF_YEAR_NUMBER_MAP[12] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 + }; + + int DayOfYearNumber = day + DAY_OF_YEAR_NUMBER_MAP[month - 1]; + + if (leapYear && month > 2) { + DayOfYearNumber += 1; + } + + // 5. Find the Jan1Weekday for Y (Monday=1, Sunday=7) + const int YY = (year - 1) % 100; + const int C = (year - 1) - YY; + const int G = YY + YY / 4; + const int Jan1Weekday = 1 + (((((C / 100) % 4) * 5) + G) % 7); + + // 6. Find the Weekday for Y M D + const int H = DayOfYearNumber + (Jan1Weekday - 1); + const int Weekday = 1 + ((H - 1) % 7); + + // 7. Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53 + int YearNumber = 0, WeekNumber = 0; + + if (DayOfYearNumber <= (8 - Jan1Weekday) && Jan1Weekday > 4) { + + YearNumber = year - 1; + + if (Jan1Weekday == 5 || (Jan1Weekday == 6 && leapYear_1)) { + WeekNumber = 53; + } else { + WeekNumber = 52; + } + + } else { + + YearNumber = year; + } + + // 8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1 + if (YearNumber == year) { + + const int I = (leapYear ? 366 : 365); + + if ((I - DayOfYearNumber) < (4 - Weekday)) { + YearNumber = year + 1; + WeekNumber = 1; + } + } + + // 9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53 + if (YearNumber == year) { + + const int J = DayOfYearNumber + (7 - Weekday) + (Jan1Weekday - 1); + + WeekNumber = J / 7; + + if (Jan1Weekday > 4) { + WeekNumber -= 1; + } + } + + if (!iso && (WeekNumber == 1 && month == 12)) { + WeekNumber = 53; + } + + return WeekNumber; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/datetimeUtils.hpp b/vmime-master/src/vmime/utility/datetimeUtils.hpp new file mode 100644 index 0000000..b762a6e --- /dev/null +++ b/vmime-master/src/vmime/utility/datetimeUtils.hpp @@ -0,0 +1,98 @@ +// +// 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. +// + +#ifndef VMIME_DATETIMEUTILS_HPP_INCLUDED +#define VMIME_DATETIMEUTILS_HPP_INCLUDED + + +#include "vmime/dateTime.hpp" + + +namespace vmime { +namespace utility { + + +/** Miscellaneous functions related to date/time. + */ +class VMIME_EXPORT datetimeUtils { + +public: + + /** Test whether the specified year is a leap year. + * + * @param year year in 4-digit format + * @return true if year is a leap year, false otherwise + */ + static bool isLeapYear(const int year); + + /** Return the number of days in the specified month. + * + * @param year year in 4-digit format (this is needed to check + * for leap years) + * @param month month, January is 1, December is 12 (see datetime::Months enum) + * @return the number of days in the month + */ + static int getDaysInMonth(const int year, const int month); + + /** Convert the specified date/time to UT (GMT). + * + * @param date date/time to convert + * @return GMT date/time + */ + static const datetime toUniversalTime(const datetime& date); + + /** Convert the specified date/time to the specified time zone. + * + * @param date date/time to convert + * @param zone local zone to convert to (see datetime::TimeZones enum) + * @return local time and date + */ + static const datetime toLocalTime(const datetime& date, const int zone); + + /** Return the day of the week from the specified date. + * + * @param year year in 4-digit format + * @param month month (1-12), January is 1, December is 12 (see datetime::Months enum) + * @param day month day (1-31) + * @return the day of the week, Sunday is 0, Monday is 1 (see datetime::DaysOfWeek enum) + */ + static int getDayOfWeek(const int year, const int month, const int day); + + /** Return the week number in the year (ISO 8601). + * + * @param year year in 4-digit format + * @param month month (1-12), January is 1, December is 12 (see datetime::Months enum) + * @param day month day (1-31) + * @param iso if TRUE, use ISO week-numbering year (default is to use calendar year). + * For more information, read here: http://en.wikipedia.org/wiki/ISO_8601#Week_dates + * @return the week number (1 is the first week of the year) + */ + static int getWeekOfYear(const int year, const int month, const int day, const bool iso = false); +}; + + +} // utility +} // vmime + + +#endif // VMIME_DATETIMEUTILS_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/b64Encoder.cpp b/vmime-master/src/vmime/utility/encoder/b64Encoder.cpp new file mode 100644 index 0000000..ef4e581 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/b64Encoder.cpp @@ -0,0 +1,350 @@ +// +// 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/utility/encoder/b64Encoder.hpp" +#include "vmime/parserHelpers.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +b64Encoder::b64Encoder() { + +} + + +const std::vector <string> b64Encoder::getAvailableProperties() const { + + std::vector <string> list(encoder::getAvailableProperties()); + + list.push_back("maxlinelength"); + + return list; +} + + +// 7-bits alphabet used to encode binary data +const unsigned char b64Encoder::sm_alphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +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 + 0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0xff,0xff,0xff,0x3d,0xff,0xff, // 0x30 - 0x3f + 0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, // 0x40 - 0x4f + 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xff,0xff,0xff,0xff,0xff, // 0x50 - 0x5f + 0xff,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, // 0x60 - 0x6f + 0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0xff,0xff,0xff,0xff, // 0x70 - 0x7f + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0x80 - 0x8f + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0x90 - 0x9f + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0xa0 - 0xaf + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0xb0 - 0xbf + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0xc0 - 0xcf + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0xd0 - 0xdf + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0xe0 - 0xef + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0xf0 - 0xff +}; + +#ifndef VMIME_BUILDING_DOC + #define B64_WRITE(s, x, l) s.write(reinterpret_cast <byte_t*>(x), l) +#endif // VMIME_BUILDING_DOC + + + +size_t b64Encoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + + in.reset(); // may not work... + + const size_t propMaxLineLength = + getProperties().getProperty <size_t>("maxlinelength", static_cast <size_t>(-1)); + + const bool cutLines = (propMaxLineLength != static_cast <size_t>(-1)); + const size_t maxLineLength = std::min(propMaxLineLength, static_cast <size_t>(76)); + + // Process data + byte_t buffer[65536]; + size_t bufferLength = 0; + size_t bufferPos = 0; + + byte_t bytes[3]; + byte_t output[4]; + + size_t total = 0; + size_t inTotal = 0; + + size_t curCol = 0; + + if (progress) { + progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { + + if (bufferPos >= bufferLength) { + + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + + if (bufferLength == 0) { + break; + } + } + + // Get 3 bytes of data + int count = 0; + + while (count < 3 && bufferPos < bufferLength) { + bytes[count++] = buffer[bufferPos++]; + } + + while (count < 3) { + + // There may be more data in the next chunk... + if (bufferPos >= bufferLength) { + + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + + if (bufferLength == 0) { + break; + } + } + + while (count < 3 && bufferPos < bufferLength) { + bytes[count++] = buffer[bufferPos++]; + } + } + + // Encode data + switch (count) { + + case 1: + + 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 + + break; + + case 2: + + 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 + + break; + + default: + case 3: + + 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 + B64_WRITE(out, output, 4); + + inTotal += count; + total += 4; + curCol += 4; + + if (cutLines && curCol + 2 /* \r\n */ + 4 /* next bytes */ >= maxLineLength) { + out.write("\r\n", 2); + curCol = 0; + } + + if (progress) { + progress->progress(inTotal, inTotal); + } + } + + if (progress) { + progress->stop(inTotal); + } + + return total; +} + + +size_t b64Encoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + + in.reset(); // may not work... + + // Process the data + byte_t buffer[16384]; + size_t bufferLength = 0; + size_t bufferPos = 0; + + size_t total = 0; + size_t inTotal = 0; + + byte_t bytes[4]; + byte_t output[3]; + + if (progress) { + progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { + + bytes[0] = '='; + bytes[1] = '='; + bytes[2] = '='; + bytes[3] = '='; + + // Need to get more data? + if (bufferPos >= bufferLength) { + + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + + // No more data + 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) { + + const byte_t c = buffer[bufferPos++]; + + if (!parserHelpers::isSpace(c)) { + bytes[count++] = c; + } + } + + 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) { + + const byte_t c = buffer[bufferPos++]; + + if (!parserHelpers::isSpace(c)) { + bytes[count++] = c; + } + } + } + } + + 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 + break; + } + + output[0] = static_cast <byte_t>((sm_decodeMap[c1] << 2) | ((sm_decodeMap[c2] & 0x30) >> 4)); + + c1 = bytes[2]; + + if (c1 == '=') { // end + B64_WRITE(out, output, 1); + total += 1; + break; + } + + output[1] = static_cast <byte_t>(((sm_decodeMap[c2] & 0xf) << 4) | ((sm_decodeMap[c1] & 0x3c) >> 2)); + + c2 = bytes[3]; + + if (c2 == '=') { // end + B64_WRITE(out, output, 2); + total += 2; + break; + } + + output[2] = static_cast <byte_t>(((sm_decodeMap[c1] & 0x03) << 6) | sm_decodeMap[c2]); + + B64_WRITE(out, output, 3); + total += 3; + inTotal += count; + + if (progress) { + progress->progress(inTotal, inTotal); + } + } + + if (progress) { + progress->stop(inTotal); + } + + return total; +} + + +size_t b64Encoder::getEncodedSize(const size_t n) const { + + const size_t propMaxLineLength = + getProperties().getProperty <size_t>("maxlinelength", static_cast <size_t>(-1)); + + const bool cutLines = (propMaxLineLength != static_cast <size_t>(-1)); + const size_t maxLineLength = std::min(propMaxLineLength, static_cast <size_t>(76)); + + return (n * 4) / 3 // 3 bytes of input provide 4 bytes of output + + (cutLines ? (n / maxLineLength) * 2 : 0) // CRLF (2 bytes) for each line. + + 4; // padding +} + + +size_t b64Encoder::getDecodedSize(const size_t n) const { + + // 4 bytes of input provide 3 bytes of output + return (n * 3) / 4; +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/b64Encoder.hpp b/vmime-master/src/vmime/utility/encoder/b64Encoder.hpp new file mode 100644 index 0000000..c5be2c3 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/b64Encoder.hpp @@ -0,0 +1,73 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_B64ENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_B64ENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Base64 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 + ); + + const std::vector <string> getAvailableProperties() const; + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; + +protected: + + static const unsigned char sm_alphabet[]; + static const unsigned char sm_decodeMap[256]; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_B64ENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/binaryEncoder.cpp b/vmime-master/src/vmime/utility/encoder/binaryEncoder.cpp new file mode 100644 index 0000000..b30bb7b --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/binaryEncoder.cpp @@ -0,0 +1,39 @@ +// +// 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/utility/encoder/binaryEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +binaryEncoder::binaryEncoder() { + +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/binaryEncoder.hpp b/vmime-master/src/vmime/utility/encoder/binaryEncoder.hpp new file mode 100644 index 0000000..331014e --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/binaryEncoder.hpp @@ -0,0 +1,51 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_BINARYENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_BINARYENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/noopEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Binary encoder. + */ +class VMIME_EXPORT binaryEncoder : public noopEncoder { + +public: + + binaryEncoder(); +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_BINARYENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/eightBitEncoder.cpp b/vmime-master/src/vmime/utility/encoder/eightBitEncoder.cpp new file mode 100644 index 0000000..a966931 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/eightBitEncoder.cpp @@ -0,0 +1,39 @@ +// +// 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/utility/encoder/eightBitEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +eightBitEncoder::eightBitEncoder() { + +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/eightBitEncoder.hpp b/vmime-master/src/vmime/utility/encoder/eightBitEncoder.hpp new file mode 100644 index 0000000..c400f51 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/eightBitEncoder.hpp @@ -0,0 +1,51 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_EIGHTBITENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_EIGHTBITENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/noopEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** 8-bit encoder. + */ +class VMIME_EXPORT eightBitEncoder : public noopEncoder { + +public: + + eightBitEncoder(); +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_EIGHTBITENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/encoder.cpp b/vmime-master/src/vmime/utility/encoder/encoder.cpp new file mode 100644 index 0000000..634adf0 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/encoder.cpp @@ -0,0 +1,76 @@ +// +// 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/utility/encoder/encoder.hpp" +#include "vmime/exception.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +encoder::encoder() { + +} + + +encoder::~encoder() { + +} + + +const propertySet& encoder::getProperties() const { + + return m_props; +} + + +propertySet& encoder::getProperties() { + + return m_props; +} + + +const propertySet& encoder::getResults() const { + + return m_results; +} + + +propertySet& encoder::getResults() { + + return m_results; +} + + +const std::vector <string> encoder::getAvailableProperties() const { + + std::vector <string> list; + return list; +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/encoder.hpp b/vmime-master/src/vmime/utility/encoder/encoder.hpp new file mode 100644 index 0000000..134e813 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/encoder.hpp @@ -0,0 +1,135 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_ENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_ENCODER_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/propertySet.hpp" +#include "vmime/exception.hpp" +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Encode/decode data in different encodings. + */ +class VMIME_EXPORT encoder : public object { + +public: + + encoder(); + virtual ~encoder(); + + /** Encode data. + * + * @param in input data (decoded) + * @param out output stream for encoded data + * @param progress progress listener, or NULL if you do not + * 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; + + /** Decode data. + * + * @param in input data (encoded) + * @param out output stream for decoded data + * @param progress progress listener, or NULL if you do not + * 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; + + /** Return the properties of the encoder. + * + * @return properties of the encoder + */ + const propertySet& getProperties() const; + + /** Return the properties of the encoder. + * + * @return properties of the encoder + */ + propertySet& getProperties(); + + /** Return a list of property names that can be set for + * this encoder. + * + * @return list of property names + */ + virtual const std::vector <string> getAvailableProperties() const; + + /** Return the results returned by this encoder. + * + * @return results returned by the encoder + */ + const propertySet& getResults() const; + + /** Return the encoded size for the specified input (decoded) size. + * If the size is not exact, it may be an estimate which should always + * be larger than the actual encoded size. + * + * @param n count of input (decoded) bytes + * @return count of output (encoded) bytes + */ + virtual size_t getEncodedSize(const size_t n) const = 0; + + /** Return the encoded size for the specified input (encoded) size. + * If the size is not exact, it may be an estimate which should always + * be larger than the actual decoded size. + * + * @param n count of input (encoded) bytes + * @return count of output (decoded) bytes + */ + virtual size_t getDecodedSize(const size_t n) const = 0; + +protected: + + propertySet& getResults(); + +private: + + propertySet m_props; + propertySet m_results; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_ENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/encoderFactory.cpp b/vmime-master/src/vmime/utility/encoder/encoderFactory.cpp new file mode 100644 index 0000000..df655ae --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/encoderFactory.cpp @@ -0,0 +1,149 @@ +// +// 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/utility/encoder/encoderFactory.hpp" +#include "vmime/exception.hpp" + +#include "vmime/utility/encoder/b64Encoder.hpp" +#include "vmime/utility/encoder/qpEncoder.hpp" +#include "vmime/utility/encoder/uuEncoder.hpp" +#include "vmime/utility/encoder/binaryEncoder.hpp" +#include "vmime/utility/encoder/sevenBitEncoder.hpp" +#include "vmime/utility/encoder/eightBitEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +encoderFactory::encoderFactory() { + + // Register some default encoders + registerName <b64Encoder>("base64"); + registerName <qpEncoder>("quoted-printable"); + registerName <uuEncoder>("uuencode"); + registerName <uuEncoder>("x-uuencode"); + registerName <sevenBitEncoder>("7bit"); + registerName <eightBitEncoder>("8bit"); + registerName <binaryEncoder>("binary"); + + // Also register some non-standard encoding names + registerName <sevenBitEncoder>("7-bit"); + registerName <eightBitEncoder>("8-bit"); + registerName <eightBitEncoder>("8bits"); + + // Finally, register some bogus encoding names, for compatibility + registerName <qpEncoder>("bmoted-printable"); +} + + +encoderFactory::~encoderFactory() { + +} + + +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 { + + return (getEncoderByName(name)->create()); + + } 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 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) { + return (*it); + } + } + + throw exceptions::no_encoder_available(name); +} + + +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 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) { + + res.push_back(*it); + } + + return res; +} + + +void encoderFactory::setDefaultEncoder(const shared_ptr <encoder>& enc) { + + m_defaultEncoder = enc; +} + + +shared_ptr <encoder> encoderFactory::getDefaultEncoder() const { + + return m_defaultEncoder; +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/encoderFactory.hpp b/vmime-master/src/vmime/utility/encoder/encoderFactory.hpp new file mode 100644 index 0000000..e475f8e --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/encoderFactory.hpp @@ -0,0 +1,164 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_ENCODERFACTORY_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_ENCODERFACTORY_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** A factory to create 'encoder' objects for the specified encoding. + */ +class VMIME_EXPORT encoderFactory +{ +private: + + encoderFactory(); + ~encoderFactory(); + +public: + + static shared_ptr <encoderFactory> getInstance(); + + /** Information about a registered encoder. */ + class VMIME_EXPORT registeredEncoder : public object { + + protected: + + virtual ~registeredEncoder() { } + + public: + + virtual shared_ptr <encoder> create() const = 0; + + virtual const string& getName() const = 0; + }; + +private: + + template <class E> + class registeredEncoderImpl : public registeredEncoder { + + public: + + registeredEncoderImpl(const string& name) : m_name(name) { } + + shared_ptr <encoder> create() const { + + return vmime::make_shared <E>(); + } + + const string& getName() const { + + return m_name; + } + + private: + + const string m_name; + }; + + + std::vector <shared_ptr <registeredEncoder> > m_encoders; + shared_ptr <encoder> m_defaultEncoder; + +public: + + /** Register a new encoder by its encoding name. + * + * @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)) + ); + } + + /** Create a new encoder instance from an encoding name. + * + * @param name encoding name (eg. "base64") + * @return a new encoder instance for the specified encoding + * @throw exceptions::no_encoder_available if no encoder is registered + * for this encoding + */ + shared_ptr <encoder> create(const string& name); + + /** Return information about a registered encoder. + * + * @param name encoding name + * @return information about this encoder + * @throw exceptions::no_encoder_available if no encoder is registered + * for this encoding + */ + const shared_ptr <const registeredEncoder> getEncoderByName(const string& name) const; + + /** Return the number of registered encoders. + * + * @return number of registered encoders + */ + size_t getEncoderCount() const; + + /** Return the registered encoder at the specified position. + * + * @param pos position of the registered encoder to return + * @return registered encoder at the specified position + */ + const shared_ptr <const registeredEncoder> getEncoderAt(const size_t pos) const; + + /** Return a list of all registered encoders. + * + * @return list of registered encoders + */ + const std::vector <shared_ptr <const registeredEncoder> > getEncoderList() const; + + /** Set the default encoder to use when no other encoder + * is registered for an encoding (fallback). + * + * @param enc default encoder + */ + void setDefaultEncoder(const shared_ptr <encoder>& enc); + + /** Return the default encoder to use when no other encoder + * is registered for an encoding (fallback). + * + * @return default encoder + */ + shared_ptr <encoder> getDefaultEncoder() const; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_ENCODERFACTORY_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/noopEncoder.cpp b/vmime-master/src/vmime/utility/encoder/noopEncoder.cpp new file mode 100644 index 0000000..30cc6c1 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/noopEncoder.cpp @@ -0,0 +1,94 @@ +// +// 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/utility/encoder/noopEncoder.hpp" + +#include "vmime/utility/streamUtils.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +noopEncoder::noopEncoder() { + +} + + +size_t noopEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + + in.reset(); // may not work... + + // No encoding performed + size_t res = 0; + + if (progress) + res = utility::bufferedStreamCopy(in, out, 0, progress); + else + res = utility::bufferedStreamCopy(in, out); + + return res; +} + + +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) { + res = utility::bufferedStreamCopy(in, out, 0, progress); + } else { + res = utility::bufferedStreamCopy(in, out); + } + + return res; +} + + +size_t noopEncoder::getEncodedSize(const size_t n) const { + + return n; +} + + +size_t noopEncoder::getDecodedSize(const size_t n) const { + + return n; +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/noopEncoder.hpp b/vmime-master/src/vmime/utility/encoder/noopEncoder.hpp new file mode 100644 index 0000000..91944de --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/noopEncoder.hpp @@ -0,0 +1,66 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_NOOPENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_NOOPENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Default, no-op encoder (simple copy, no encoding/decoding is performed). + */ +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 getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_NOOPENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/qpEncoder.cpp b/vmime-master/src/vmime/utility/encoder/qpEncoder.cpp new file mode 100644 index 0000000..4aeb640 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/qpEncoder.cpp @@ -0,0 +1,568 @@ +// +// 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/utility/encoder/qpEncoder.hpp" +#include "vmime/parserHelpers.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +qpEncoder::qpEncoder() { + +} + + +const std::vector <string> qpEncoder::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; +} + + + +// Hex-encoding table +const unsigned char qpEncoder::sm_hexDigits[] = "0123456789ABCDEF"; + + +// RFC-2047 encoding table: we always encode RFC-2047 using the restricted +// charset, that is the one used for 'phrase' in From/To/Cc/... headers. +// +// " The set of characters that may be used in a "Q"-encoded 'encoded-word' +// is restricted to: <upper and lower case ASCII letters, decimal digits, +// "!", "*", "+", "-", "/", "=", and "_" (underscore, ASCII 95.)>. " +// +// Two special cases: +// - encode space (32) as underscore (95) +// - encode underscore as hex (=5F) +// +// This is a quick lookup table: +// '1' means "encode", '0' means "no encoding" +// +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, + /* 18 DC2 */ 1, /* 19 DC3 */ 1, /* 20 DC4 */ 1, /* 21 NAK */ 1, /* 22 SYN */ 1, /* 23 ETB */ 1, + /* 24 CAN */ 1, /* 25 EM */ 1, /* 26 SUB */ 1, /* 27 ESC */ 1, /* 28 FS */ 1, /* 29 GS */ 1, + /* 30 RS */ 1, /* 31 US */ 1, /* 32 SPACE*/ 1, /* 33 ! */ 0, /* 34 " */ 1, /* 35 # */ 1, + /* 36 $ */ 1, /* 37 % */ 1, /* 38 & */ 1, /* 39 ' */ 1, /* 40 ( */ 1, /* 41 ) */ 1, + /* 42 * */ 0, /* 43 + */ 0, /* 44 , */ 1, /* 45 - */ 0, /* 46 . */ 1, /* 47 / */ 0, + /* 48 0 */ 0, /* 49 1 */ 0, /* 50 2 */ 0, /* 51 3 */ 0, /* 52 4 */ 0, /* 53 5 */ 0, + /* 54 6 */ 0, /* 55 7 */ 0, /* 56 8 */ 0, /* 57 9 */ 0, /* 58 : */ 1, /* 59 ; */ 1, + /* 60 < */ 1, /* 61 = */ 1, /* 62 > */ 1, /* 63 ? */ 1, /* 64 @ */ 1, /* 65 A */ 0, + /* 66 B */ 0, /* 67 C */ 0, /* 68 D */ 0, /* 69 E */ 0, /* 70 F */ 0, /* 71 G */ 0, + /* 72 H */ 0, /* 73 I */ 0, /* 74 J */ 0, /* 75 K */ 0, /* 76 L */ 0, /* 77 M */ 0, + /* 78 N */ 0, /* 79 O */ 0, /* 80 P */ 0, /* 81 Q */ 0, /* 82 R */ 0, /* 83 S */ 0, + /* 84 T */ 0, /* 85 U */ 0, /* 86 V */ 0, /* 87 W */ 0, /* 88 X */ 0, /* 89 Y */ 0, + /* 90 Z */ 0, /* 91 [ */ 1, /* 92 " */ 1, /* 93 ] */ 1, /* 94 ^ */ 1, /* 95 _ */ 1, + /* 96 ` */ 1, /* 97 a */ 0, /* 98 b */ 0, /* 99 c */ 0, /* 100 d */ 0, /* 101 e */ 0, + /* 102 f */ 0, /* 103 g */ 0, /* 104 h */ 0, /* 105 i */ 0, /* 106 j */ 0, /* 107 k */ 0, + /* 108 l */ 0, /* 109 m */ 0, /* 110 n */ 0, /* 111 o */ 0, /* 112 p */ 0, /* 113 q */ 0, + /* 114 r */ 0, /* 115 s */ 0, /* 116 t */ 0, /* 117 u */ 0, /* 118 v */ 0, /* 119 w */ 0, + /* 120 x */ 0, /* 121 y */ 0, /* 122 z */ 0, /* 123 { */ 1, /* 124 | */ 1, /* 125 } */ 1, + /* 126 ~ */ 1, /* 127 DEL */ 1 +}; + + +// Hex-decoding table +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, + 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 +}; + + +// static +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 + + // Encoded as "_" + return 1; + + } else { + + // Hex encoding + return 3; + } + + } else { + + return 1; // no encoding + } +} + + +#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 <byte_t*>(x), l) + +#endif // VMIME_BUILDING_DOC + + +size_t qpEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + + in.reset(); // may not work... + + const size_t propMaxLineLength = + getProperties().getProperty <size_t>("maxlinelength", static_cast <size_t>(-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 <size_t>(-1)); + const size_t maxLineLength = std::min(propMaxLineLength, static_cast <size_t>(74)); + + // Process the data + byte_t buffer[16384]; + size_t bufferLength = 0; + size_t bufferPos = 0; + + size_t curCol = 0; + + byte_t outBuffer[16384]; + size_t outBufferPos = 0; + + size_t total = 0; + size_t 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 byte_t c = buffer[bufferPos++]; + + 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 { + + // Other characters: '=' + hexadecimal encoding + QP_ENCODE_HEX(c); + } + + } 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; + } + + // 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 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; + + if (c == 10) { + curCol = 0; // reset current line length + } + + // Binary data + } else { + + QP_ENCODE_HEX(c); + } + + 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; + + // Other characters: '=' + hexadecimal encoding + } else { + + QP_ENCODE_HEX(c); + } + + break; + + } // switch (c) + + // Soft line break : "=\r\n" + if (cutLines && curCol >= maxLineLength - 1) { + + outBuffer[outBufferPos] = '='; + outBuffer[outBufferPos + 1] = '\r'; + outBuffer[outBufferPos + 2] = '\n'; + + outBufferPos += 3; + curCol = 0; + } + + } // !rfc2047 + + ++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; +} + + +size_t qpEncoder::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); + + byte_t buffer[16384]; + size_t bufferLength = 0; + size_t bufferPos = 0; + + byte_t outBuffer[16384]; + size_t outBufferPos = 0; + + size_t total = 0; + size_t inTotal = 0; + + while (bufferPos < bufferLength || !in.eof()) { + + // Flush current output buffer + if (outBufferPos >= 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) + byte_t c = buffer[bufferPos++]; + + ++inTotal; + + switch (c) { + + case '=': { + + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } + + if (bufferPos < bufferLength) { + + c = 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 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; + } + + } + + } 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; + } + + outBuffer[outBufferPos++] = c; + break; + } + default: { + + outBuffer[outBufferPos++] = c; + break; + } + + } + + 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; +} + + +size_t qpEncoder::getEncodedSize(const size_t n) const { + + const size_t propMaxLineLength = + getProperties().getProperty <size_t>("maxlinelength", static_cast <size_t>(-1)); + + const bool cutLines = (propMaxLineLength != static_cast <size_t>(-1)); + const size_t maxLineLength = std::min(propMaxLineLength, static_cast <size_t>(74)); + + // Worst cast: 1 byte of input provide 3 bytes of output + // Count CRLF (2 bytes) for each line. + return n * 3 + (cutLines ? (n / maxLineLength) * 2 : 0); +} + + +size_t qpEncoder::getDecodedSize(const size_t n) const { + + // Worst case: 1 byte of input equals 1 byte of output + return n; +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/qpEncoder.hpp b/vmime-master/src/vmime/utility/encoder/qpEncoder.hpp new file mode 100644 index 0000000..21263a6 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/qpEncoder.hpp @@ -0,0 +1,77 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_QPENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_QPENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Quoted-printable 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 + ); + + const std::vector <string> getAvailableProperties() const; + + static bool RFC2047_isEncodingNeededForChar(const unsigned char c); + static int RFC2047_getEncodedLength(const unsigned char c); + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; + +protected: + + static const unsigned char sm_hexDigits[17]; + static const unsigned char sm_hexDecodeTable[256]; + static const unsigned char sm_RFC2047EncodeTable[128]; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_QPENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/sevenBitEncoder.cpp b/vmime-master/src/vmime/utility/encoder/sevenBitEncoder.cpp new file mode 100644 index 0000000..999b11e --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/sevenBitEncoder.cpp @@ -0,0 +1,39 @@ +// +// 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/utility/encoder/sevenBitEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +sevenBitEncoder::sevenBitEncoder() { + +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/sevenBitEncoder.hpp b/vmime-master/src/vmime/utility/encoder/sevenBitEncoder.hpp new file mode 100644 index 0000000..37f84a6 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/sevenBitEncoder.hpp @@ -0,0 +1,51 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_SEVENBITENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_SEVENBITENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/noopEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** 7-bit encoder. + */ +class VMIME_EXPORT sevenBitEncoder : public noopEncoder +{ +public: + + sevenBitEncoder(); +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_SEVENBITENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/encoder/uuEncoder.cpp b/vmime-master/src/vmime/utility/encoder/uuEncoder.cpp new file mode 100644 index 0000000..24dcdc8 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/uuEncoder.cpp @@ -0,0 +1,358 @@ +// +// 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/utility/encoder/uuEncoder.hpp" +#include "vmime/parserHelpers.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +uuEncoder::uuEncoder() { + + getProperties()["mode"] = 644; + getProperties()["filename"] = "no_name"; + getProperties()["maxlinelength"] = 46; +} + + +const std::vector <string> uuEncoder::getAvailableProperties() const { + + std::vector <string> list(encoder::getAvailableProperties()); + + list.push_back("maxlinelength"); + + list.push_back("mode"); + list.push_back("filename"); + + return list; +} + + +// This is the character encoding function to make a character printable +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) { + + return (c - ' ') & 077; +} + + +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", ""); + const string propMode = getProperties().getProperty <string>("mode", "644"); + + const size_t maxLineLength = + std::min(getProperties().getProperty <size_t>("maxlinelength", 46), static_cast <size_t>(46)); + + size_t total = 0; + size_t inTotal = 0; + + // Output the prelude text ("begin [mode] [filename]") + out << "begin"; + + if (!propFilename.empty()) { + out << " " << propMode << " " << propFilename; + total += 2 + propMode.length() + propFilename.length(); + } + + out << "\r\n"; + total += 7; + + // Process the data + byte_t inBuffer[64]; + byte_t outBuffer[64]; + + if (progress) { + progress->start(0); + } + + while (!in.eof()) { + + // Process up to 45 characters per line + std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); + + const size_t inLength = in.read(inBuffer, maxLineLength - 1); + + outBuffer[0] = UUENCODE(static_cast <unsigned int>(inLength)); // Line length + + size_t j = 1; + + 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]; + + outBuffer[j] = UUENCODE(c1 >> 2); + outBuffer[j + 1] = UUENCODE(((c1 << 4) & 060) | ((c2 >> 4) & 017)); + outBuffer[j + 2] = UUENCODE(((c2 << 2) & 074) | ((c3 >> 6) & 03)); + outBuffer[j + 3] = UUENCODE(c3 & 077); + } + + outBuffer[j] = '\r'; + outBuffer[j + 1] = '\n'; + + 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; +} + + +size_t uuEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + + in.reset(); // may not work... + + // Process the data + byte_t inBuffer[64]; + byte_t outBuffer[64]; + + size_t total = 0; + size_t 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 + byte_t lengthChar; + + 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; + } + + inTotal += count; + + if (c != '\n') { + + // OOPS! Weird line. Don't try to decode more... + + 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; + } + + 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; + } + + break; + } + + } + + // Read encoded data + if (in.read(inBuffer + inPos, inLength - inPos) != inLength - inPos) { + // Premature end of data + break; + } + + inTotal += (inLength - inPos); + + // Decode data + 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]; + const byte_t c4 = inBuffer[i + 3]; + + const size_t n = std::min(inLength - i, static_cast <size_t>(3)); + + 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; + } + + out.write(outBuffer, outLength); + + std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); + + if (progress) { + progress->progress(inTotal, inTotal); + } + } + + if (progress) { + progress->stop(inTotal); + } + + return total; +} + + +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. + return 200 + n * 3 + (n / 45) * 2; +} + + +size_t uuEncoder::getDecodedSize(const size_t n) const { + + // 4 bytes of input provide 3 bytes of output + return (n * 3) / 4; +} + + +} // encoder +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/encoder/uuEncoder.hpp b/vmime-master/src/vmime/utility/encoder/uuEncoder.hpp new file mode 100644 index 0000000..841cf66 --- /dev/null +++ b/vmime-master/src/vmime/utility/encoder/uuEncoder.hpp @@ -0,0 +1,68 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_ENCODER_UUENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_UUENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** UUEncode 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 + ); + + const std::vector <string> getAvailableProperties() const; + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_UUENCODER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/file.hpp b/vmime-master/src/vmime/utility/file.hpp new file mode 100644 index 0000000..6e0605e --- /dev/null +++ b/vmime-master/src/vmime/utility/file.hpp @@ -0,0 +1,264 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_FILE_HPP_INCLUDED +#define VMIME_UTILITY_FILE_HPP_INCLUDED + + +#include "vmime/config.hpp" + +#include "vmime/utility/path.hpp" +#include "vmime/utility/stream.hpp" + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + + +namespace vmime { +namespace utility { + + +class file; + + +/** File list iterator (see file::getFiles). + */ +class VMIME_EXPORT fileIterator : public object { + +public: + + virtual ~fileIterator() { } + + /** Check whether the cursor has reach the end of the list. + * + * @return true if you can call nextElement(), or false + * if no more file is available + */ + virtual bool hasMoreElements() const = 0; + + /** Return the next file in the list. + * + * @return next file or NULL + */ + virtual shared_ptr <file> nextElement() = 0; +}; + + +/** Write to a file. + */ +class VMIME_EXPORT fileWriter : public object { + +public: + + virtual ~fileWriter() { } + + virtual shared_ptr <utility::outputStream> getOutputStream() = 0; +}; + + +/** Read from a file. + */ +class VMIME_EXPORT fileReader : public object { + +public: + + virtual ~fileReader() { } + + virtual shared_ptr <utility::inputStream> getInputStream() = 0; +}; + + +/** Abstract representation of a file or directory. + */ +class VMIME_EXPORT file : public object { + +public: + + typedef utility::path path; + typedef unsigned long length_type; + + + virtual ~file() { } + + + /** Create the file pointed by this file object. + * + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void createFile() = 0; + + /** Create the directory pointed by this file object. + * + * @param createAll if set to true, recursively create all + * parent directories if they do not exist + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void createDirectory(const bool createAll = false) = 0; + + /** Test whether this is a file. + * + * @return true if this is a file, false otherwise + */ + virtual bool isFile() const = 0; + + /** Test whether this is a directory. + * + * @return true if this is a directory, false otherwise + */ + virtual bool isDirectory() const = 0; + + /** Test whether this file is readible. + * + * @return true if we can read this file, false otherwise + */ + virtual bool canRead() const = 0; + + /** Test whether this file is writeable. + * + * @return true if we can write to this file, false otherwise + */ + virtual bool canWrite() const = 0; + + /** Return the length of this file. + * + * @return file size (in bytes) + */ + virtual length_type getLength() = 0; + + /** Return the full path of this file/directory. + * + * @return full path of the file + */ + virtual const path& getFullPath() const = 0; + + /** Test whether this file/directory exists. + * + * @return true if the file exists, false otherwise + */ + virtual bool exists() const = 0; + + /** Return the parent directory of this file/directory. + * + * @return parent directory (or NULL if root) + */ + virtual shared_ptr <file> getParent() const = 0; + + /** Rename the file/directory. + * + * @param newName full path of the new file + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void rename(const path& newName) = 0; + + /** Deletes this file/directory. + * If this is a directory, it must be empty. + * + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void remove() = 0; + + /** Return an object capable of writing to this file. + * + * @return file writer object + */ + virtual shared_ptr <fileWriter> getFileWriter() = 0; + + /** Return an object capable of reading from this file. + * + * @return file reader object + */ + virtual shared_ptr <fileReader> getFileReader() = 0; + + /** Enumerate files contained in this directory. + * + * @return file iterator to enumerate files + * @throw exceptions::not_a_directory if this is not a directory, + * exceptions::filesystem_exception if another error occurs + */ + virtual shared_ptr <fileIterator> getFiles() const = 0; + +protected: + + file() { } + +private: + + file(const file&) : object() { } +}; + + +/** Constructs 'file' objects. + */ +class VMIME_EXPORT fileSystemFactory : public object { + +public: + + virtual ~fileSystemFactory() { } + + /** Create a new file object from the specified path. + * + * @param path full path (absolute) of the file + * @return new file object for the path + */ + virtual shared_ptr <file> create(const file::path& path) const = 0; + + /** Parse a path contained in a string. + * + * @param str string containing a path in a system-dependent representation + * @return path object (abstract representation) + */ + virtual const file::path stringToPath(const string& str) const = 0; + + /** Return the system-dependent string representation for the specified path. + * + * @param path abstract representation of the path + * @return string representation of the path + */ + virtual const string pathToString(const file::path& path) const = 0; + + /** Test whether the specified path component is syntactically + * valid (ie: does not contain any 'special' character). + * + * @param comp path component to test + * @return true if the component is valid, false otherwise + */ + virtual bool isValidPathComponent(const file::path::component& comp) const = 0; + + /** Test whether the specified path is syntactically valid + * (ie: components do not contain any 'special' character). + * + * @param path path to test + * @return true if the path is valid, false otherwise + */ + virtual bool isValidPath(const file::path& path) const = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_FILESYSTEM_FEATURES + + +#endif // VMIME_UTILITY_FILE_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/filteredStream.cpp b/vmime-master/src/vmime/utility/filteredStream.cpp new file mode 100644 index 0000000..d5ec17b --- /dev/null +++ b/vmime-master/src/vmime/utility/filteredStream.cpp @@ -0,0 +1,402 @@ +// +// 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/utility/filteredStream.hpp" + +#include <algorithm> + + +namespace vmime { +namespace utility { + + +// filteredInputStream + +size_t filteredInputStream::getBlockSize() { + + return std::min(inputStream::getBlockSize(), getPreviousInputStream().getBlockSize()); +} + + +// filteredOutputStream + +size_t filteredOutputStream::getBlockSize() { + + return std::min(outputStream::getBlockSize(), getNextOutputStream().getBlockSize()); +} + + +// dotFilteredInputStream + +dotFilteredInputStream::dotFilteredInputStream(inputStream& is) + : m_stream(is), + m_previousChar2('\0'), + m_previousChar1('\0') { + +} + + +inputStream& dotFilteredInputStream::getPreviousInputStream() { + + return m_stream; +} + + +bool dotFilteredInputStream::eof() const { + + return m_stream.eof(); +} + + +void dotFilteredInputStream::reset() { + + m_previousChar2 = '\0'; + m_previousChar1 = '\0'; + + m_stream.reset(); +} + + +size_t dotFilteredInputStream::read(byte_t* const data, const size_t count) { + + const size_t read = m_stream.read(data, count); + + const byte_t* readPtr = data; + byte_t* writePtr = data; + + const byte_t* end = data + read; + + size_t written = 0; + + byte_t prevChar2 = m_previousChar2; + byte_t prevChar1 = m_previousChar1; + + // Replace "\n.." with "\n." + while (readPtr < end) { + + if (*readPtr == '.' && prevChar2 == '\n' && prevChar1 == '.') { + + // Ignore last dot + prevChar2 = '\0'; + prevChar1 = '.'; + + } else { + + *writePtr = *readPtr; + + ++writePtr; + ++written; + + prevChar2 = prevChar1; + prevChar1 = *readPtr; + } + + ++readPtr; + } + + m_previousChar2 = prevChar2; + m_previousChar1 = prevChar1; + + return written; +} + + +size_t dotFilteredInputStream::skip(const size_t /* count */) { + + // Skipping bytes is not supported + return 0; +} + + +// dotFilteredOutputStream + +dotFilteredOutputStream::dotFilteredOutputStream(outputStream& os) + : m_stream(os), + m_previousChar('\0'), + m_start(true) { + +} + + +outputStream& dotFilteredOutputStream::getNextOutputStream() { + + return m_stream; +} + + +void dotFilteredOutputStream::writeImpl(const byte_t* const data, const size_t count) { + + if (count == 0) { + return; + } + + const byte_t* pos = data; + const byte_t* end = data + count; + const byte_t* start = data; + + if (m_previousChar == '.') { + + if (data[0] == '\n' || data[0] == '\r') { + + m_stream.write(".", 1); // extra <DOT> + m_stream.write(data, 1); + + pos = data + 1; + } + } + + // Replace "\n." with "\n.." + while ((pos = std::find(pos, end, '.')) != end) { + + const byte_t previousChar = (pos == data ? m_previousChar : *(pos - 1)); + + if (previousChar == '\n') { + + m_stream.write(start, pos - start); + m_stream.write("..", 2); + + start = pos + 1; + + } else if (pos == data && m_start) { // <DOT><CR><LF> at the beginning of content + + m_stream.write(start, pos - start); + + if (pos + 1 < end && (*(pos + 1) == '\n' || *(pos + 1) == '\r')) { + m_stream.write("..", 2); + } else { + m_stream.write(".", 1); + } + + start = pos + 1; + } + + ++pos; + } + + m_stream.write(start, end - start); + m_previousChar = data[count - 1]; + m_start = false; +} + + +void dotFilteredOutputStream::flush() { + + // Do nothing + m_stream.flush(); +} + + +size_t dotFilteredOutputStream::getBlockSize() { + + return m_stream.getBlockSize(); +} + + +// CRLFToLFFilteredOutputStream + +CRLFToLFFilteredOutputStream::CRLFToLFFilteredOutputStream(outputStream& os) + : m_stream(os), + m_previousChar('\0') { + +} + + +outputStream& CRLFToLFFilteredOutputStream::getNextOutputStream() { + + return m_stream; +} + + +void CRLFToLFFilteredOutputStream::writeImpl(const byte_t* const data, const size_t count) { + + if (count == 0) { + return; + } + + const byte_t* pos = data; + const byte_t* end = data + count; + const byte_t* start = data; + + // Warning: if the whole buffer finishes with '\r', this + // last character will not be written back if flush() is + // not called + if (m_previousChar == '\r') { + + if (*pos != '\n') { + m_stream.write("\r", 1); // write back \r + m_previousChar = *pos; + } + } + + // Replace "\r\n" (CRLF) with "\n" (LF) + while ((pos = std::find(pos, end, '\n')) != end) { + + const byte_t previousChar = (pos == data ? m_previousChar : *(pos - 1)); + + if (previousChar == '\r') { + + if (pos != start) { + m_stream.write(start, pos - 1 - start); // do not write \r + } + + m_stream.write("\n", 1); + + start = pos + 1; + } + + ++pos; + } + + if (data[count - 1] == '\r') { + + m_stream.write(start, end - start - 1); + m_previousChar = '\r'; + + } else { + + m_stream.write(start, end - start); + m_previousChar = data[count - 1]; + } +} + + +void CRLFToLFFilteredOutputStream::flush() { + + m_stream.flush(); + + // TODO +} + + +size_t CRLFToLFFilteredOutputStream::getBlockSize() { + + return m_stream.getBlockSize(); +} + + +// LFToCRLFFilteredOutputStream + +LFToCRLFFilteredOutputStream::LFToCRLFFilteredOutputStream(outputStream& os) + : m_stream(os), + m_previousChar('\0') { + +} + + +outputStream& LFToCRLFFilteredOutputStream::getNextOutputStream() { + + return m_stream; +} + + +void LFToCRLFFilteredOutputStream::writeImpl(const byte_t* const data, const size_t count) +{ + if (count == 0) { + return; + } + + string buffer; + buffer.reserve(count); + + const byte_t* pos = data; + const byte_t* end = data + count; + + byte_t previousChar = m_previousChar; + + while (pos < end) { + + switch (*pos) { + + case '\r': + + buffer.append(1, '\r'); + buffer.append(1, '\n'); + + break; + + case '\n': + + if (previousChar != '\r') { + buffer.append(1, '\r'); + buffer.append(1, '\n'); + } + + break; + + default: + + buffer.append(1, *pos); + break; + } + + previousChar = *pos; + ++pos; + } + + m_stream.write(&buffer[0], buffer.length()); + + m_previousChar = previousChar; +} + + +void LFToCRLFFilteredOutputStream::flush() { + + m_stream.flush(); +} + + +size_t LFToCRLFFilteredOutputStream::getBlockSize() { + + return m_stream.getBlockSize(); +} + + +// stopSequenceFilteredInputStream <1> + +template <> +size_t stopSequenceFilteredInputStream <1>::read(byte_t* const data, const size_t count) { + + if (eof() || m_stream.eof()) { + m_eof = true; + return 0; + } + + const size_t read = m_stream.read(data, count); + byte_t* end = data + read; + + byte_t* pos = std::find(data, end, m_sequence[0]); + + if (pos == end) { + + return read; + + } else { + + m_found = 1; + return pos - data; + } +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/filteredStream.hpp b/vmime-master/src/vmime/utility/filteredStream.hpp new file mode 100644 index 0000000..2414c54 --- /dev/null +++ b/vmime-master/src/vmime/utility/filteredStream.hpp @@ -0,0 +1,405 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_FILTEREDSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_FILTEREDSTREAM_HPP_INCLUDED + + +#include <algorithm> + +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** A stream whose input is filtered. + */ +class VMIME_EXPORT filteredInputStream : public inputStream { +public: + + virtual size_t getBlockSize(); + + /** Return a reference to the stream being filtered. + * + * @return stream being filtered + */ + virtual inputStream& getPreviousInputStream() = 0; +}; + + +/** A stream whose output is filtered. + */ +class VMIME_EXPORT filteredOutputStream : public outputStream { + +public: + + virtual size_t getBlockSize(); + + /** Return a reference to the stream being filtered. + * + * @return destination stream for filtered data + */ + virtual outputStream& getNextOutputStream() = 0; +}; + + +/** A filtered input stream which replaces "\n.." + * sequences with "\n." sequences. + */ +class VMIME_EXPORT dotFilteredInputStream : public filteredInputStream { + +public: + + /** Construct a new filter for the specified input stream. + * + * @param is stream from which to read data to be filtered + */ + dotFilteredInputStream(inputStream& is); + + inputStream& getPreviousInputStream(); + + bool eof() const; + + void reset(); + + size_t read(byte_t* const data, const size_t count); + + size_t skip(const size_t count); + +private: + + inputStream& m_stream; + + byte_t m_previousChar2; // (N - 1)th character of previous buffer + byte_t m_previousChar1; // (N)th (last) character of previous buffer +}; + + +/** A filtered output stream which replaces "\n." + * sequences with "\n.." sequences. + */ +class VMIME_EXPORT dotFilteredOutputStream : public filteredOutputStream { + +public: + + /** Construct a new filter for the specified output stream. + * + * @param os stream into which write filtered data + */ + dotFilteredOutputStream(outputStream& os); + + outputStream& getNextOutputStream(); + + void flush(); + + size_t getBlockSize(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStream& m_stream; + byte_t m_previousChar; + bool m_start; +}; + + +/** A filtered output stream which replaces CRLF sequences + * with single LF characters. + */ +class VMIME_EXPORT CRLFToLFFilteredOutputStream : public filteredOutputStream { + +public: + + /** Construct a new filter for the specified output stream. + * + * @param os stream into which write filtered data + */ + CRLFToLFFilteredOutputStream(outputStream& os); + + outputStream& getNextOutputStream(); + + void flush(); + + size_t getBlockSize(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStream& m_stream; + byte_t m_previousChar; +}; + + +/** A filtered output stream which replaces CR or LF characters + * with CRLF sequences. + */ +class VMIME_EXPORT LFToCRLFFilteredOutputStream : public filteredOutputStream { + +public: + + /** Construct a new filter for the specified output stream. + * + * @param os stream into which write filtered data + */ + LFToCRLFFilteredOutputStream(outputStream& os); + + outputStream& getNextOutputStream(); + + void flush(); + + size_t getBlockSize(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStream& m_stream; + byte_t m_previousChar; +}; + + +/** A filtered input stream which stops when a specified sequence + * is found (eof() method will return 'true'). + */ +template <int COUNT> +class VMIME_EXPORT stopSequenceFilteredInputStream : public filteredInputStream { + +public: + + /** Construct a new filter for the specified input stream. + * + * @param is stream from which to read data to be filtered + * @param sequence sequence on which to stop + */ + stopSequenceFilteredInputStream(inputStream& is, const byte_t* sequence) + : m_stream(is), + m_sequence(sequence), + m_found(0), + m_eof(false) { + + } + + /** Construct a new filter for the specified input stream. + * + * @param is stream from which to read data to be filtered + * @param sequence sequence on which to stop + */ + stopSequenceFilteredInputStream(inputStream& is, const char* sequence) + : m_stream(is), + m_sequence(reinterpret_cast <const byte_t*>(sequence)), + m_found(0), + m_eof(false) { + + } + + inputStream& getPreviousInputStream() { + + return m_stream; + } + + bool eof() const { + + return m_found == COUNT || m_eof; + } + + void reset() { + + m_found = 0; + m_stream.reset(); + } + + size_t read(byte_t* const data, const size_t count) { + + // Read buffer must be at least 'COUNT' size + 1 byte + if (eof() || count <= COUNT) { + return 0; + } + + if (m_stream.eof()) { + + if (m_found != 0) { + + const size_t found = m_found; + + for (size_t f = 0 ; f < found ; ++f) { + data[f] = m_sequence[f]; + } + + m_found = 0; + m_eof = true; + + return found; + + } else { + + m_eof = true; + return 0; + } + } + + size_t read = m_stream.read(data, count - COUNT); + + byte_t* end = data + read; + byte_t* pos = data; + + while (pos < end) { + + // Very simple case, search for the whole sequence + if (m_found == 0) { + + while (pos < end) { + + pos = std::find(pos, end, m_sequence[0]); + + if (pos == end) { + return read; + } + + m_found = 1; + ++pos; + + while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) { + ++m_found; + ++pos; + } + + // Didn't found whole sequence + if (m_found != COUNT) { + + // We reached the end of the buffer + if (pos == end) { + + return read - m_found; + + // Common prefix but not whole sequence + } else { + + m_found = 0; + } + + // Whole sequence found + } else { + + // End of stream + return pos - data - m_found; + } + } + + // More complex case: search for a sequence which has begun + // in a previous buffer + } else { + + // Search for the end of the previously started sequence + while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) { + ++m_found; + ++pos; + } + + if (m_found != COUNT) { + + // End of buffer + if (pos == end) { + + // No data: this buffer is a sub-sequence of the + // searched sequence + return 0; + + // Common prefix + } else { + + // We have to reinject the incomplete sequence into + // the stream data + + // -- shift right data + const size_t n = pos - data; + + byte_t* newEnd = data + read + m_found - n; + byte_t* oldEnd = data + read; + + for (size_t i = 0 ; i < read - n ; ++i) { + + --newEnd; + --oldEnd; + + *newEnd = *oldEnd; + } + + // -- copy the prefix just before data + for (size_t f = 0 ; f < m_found ; ++f) { + data[f] = m_sequence[f]; + } + + read += m_found - n; + end += m_found - n; + + m_found = 0; + } + + } else { + + return 0; // no more data + } + } + } + + return read; + } + + size_t skip(const size_t /* count */) { + + // Not supported + return 0; + } + +private: + + inputStream& m_stream; + + const byte_t* m_sequence; + size_t m_found; + + bool m_eof; +}; + + +template <> +size_t stopSequenceFilteredInputStream <1>::read(byte_t* const data, const size_t count); + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_FILTEREDSTREAM_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/utility/inputStream.cpp b/vmime-master/src/vmime/utility/inputStream.cpp new file mode 100644 index 0000000..916d8ba --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStream.cpp @@ -0,0 +1,33 @@ +// +// 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/utility/inputStream.hpp" + + +namespace vmime { +namespace utility { + + +} // utility +} // vmime + diff --git a/vmime-master/src/vmime/utility/inputStream.hpp b/vmime-master/src/vmime/utility/inputStream.hpp new file mode 100644 index 0000000..0e1c2df --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStream.hpp @@ -0,0 +1,75 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED + + +#include "vmime/utility/stream.hpp" + + +namespace vmime { +namespace utility { + + +/** Simple input stream. + */ +class VMIME_EXPORT inputStream : public stream { + +public: + + /** Test for end of stream (no more data to read). + * + * @return true if we have reached the end of stream, false otherwise + */ + virtual bool eof() const = 0; + + /** Set the read pointer to the beginning of the stream. + * + * @warning WARNING: this may not work for all stream types. + */ + virtual void reset() = 0; + + /** Read data from the stream. + * + * @param data will receive the data read + * @param count maximum number of bytes to read + * @return number of bytes read + */ + virtual size_t read(byte_t* const data, const size_t count) = 0; + + /** Skip a number of bytes. + * + * @param count maximum number of bytes to ignore + * @return number of bytes skipped + */ + virtual size_t skip(const size_t count) = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/utility/inputStreamAdapter.cpp b/vmime-master/src/vmime/utility/inputStreamAdapter.cpp new file mode 100644 index 0000000..28be103 --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamAdapter.cpp @@ -0,0 +1,84 @@ +// +// 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/utility/inputStreamAdapter.hpp" + + +namespace vmime { +namespace utility { + + +inputStreamAdapter::inputStreamAdapter(std::istream& is) + : m_stream(is) { + +} + + +bool inputStreamAdapter::eof() const { + + return m_stream.eof(); +} + + +void inputStreamAdapter::reset() { + + m_stream.exceptions(std::ios_base::badbit); + m_stream.seekg(0, std::ios::beg); + m_stream.clear(); +} + + +size_t inputStreamAdapter::read(byte_t* const data, const size_t count) { + + m_stream.exceptions(std::ios_base::badbit); + m_stream.read(reinterpret_cast <char*>(data), count); + + return m_stream.gcount(); +} + + +size_t inputStreamAdapter::skip(const size_t count) { + + m_stream.exceptions(std::ios_base::badbit); + m_stream.ignore(count); + + return m_stream.gcount(); +} + + +size_t inputStreamAdapter::getPosition() const { + + return m_stream.tellg(); +} + + +void inputStreamAdapter::seek(const size_t pos) { + + m_stream.clear(); + m_stream.seekg(pos, std::ios_base::beg); +} + + +} // utility +} // vmime + diff --git a/vmime-master/src/vmime/utility/inputStreamAdapter.hpp b/vmime-master/src/vmime/utility/inputStreamAdapter.hpp new file mode 100644 index 0000000..340765c --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamAdapter.hpp @@ -0,0 +1,65 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + +#include <istream> + + +namespace vmime { +namespace utility { + + +/** An adapter class for C++ standard input streams. + */ +class VMIME_EXPORT inputStreamAdapter : public seekableInputStream { + +public: + + /** @param is input stream to wrap + */ + inputStreamAdapter(std::istream& is); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + std::istream& m_stream; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.cpp b/vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.cpp new file mode 100644 index 0000000..927215c --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.cpp @@ -0,0 +1,104 @@ +// +// 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/utility/inputStreamByteBufferAdapter.hpp" + + +namespace vmime { +namespace utility { + + +inputStreamByteBufferAdapter::inputStreamByteBufferAdapter(const byte_t* buffer, const size_t length) + : m_buffer(buffer), + m_length(length), + m_pos(0) { + +} + + +bool inputStreamByteBufferAdapter::eof() const { + + return m_pos >= m_length; +} + + +void inputStreamByteBufferAdapter::reset() { + + m_pos = 0; +} + + +size_t inputStreamByteBufferAdapter::read(byte_t* const data, const size_t count) { + + const size_t remaining = m_length - m_pos; + + if (remaining < count) { + + std::copy(m_buffer + m_pos, m_buffer + m_pos + remaining, data); + m_pos += remaining; + + return remaining; + + } else { + + std::copy(m_buffer + m_pos, m_buffer + m_pos + count, data); + m_pos += count; + + return count; + } +} + + +size_t inputStreamByteBufferAdapter::skip(const size_t count) { + + const size_t remaining = m_length - m_pos; + + if (remaining < count) { + + m_pos += remaining; + return remaining; + + } else { + + m_pos += count; + return count; + } +} + + +size_t inputStreamByteBufferAdapter::getPosition() const { + + return m_pos; +} + + +void inputStreamByteBufferAdapter::seek(const size_t pos) { + + if (pos <= m_length) { + m_pos = pos; + } +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.hpp b/vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.hpp new file mode 100644 index 0000000..c9094c7 --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.hpp @@ -0,0 +1,63 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for reading from an array of bytes. + */ +class VMIME_EXPORT inputStreamByteBufferAdapter : public seekableInputStream { + +public: + + inputStreamByteBufferAdapter(const byte_t* buffer, size_t length); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + const byte_t* m_buffer; + const size_t m_length; + + size_t m_pos; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/inputStreamPointerAdapter.cpp b/vmime-master/src/vmime/utility/inputStreamPointerAdapter.cpp new file mode 100644 index 0000000..3f468d4 --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamPointerAdapter.cpp @@ -0,0 +1,48 @@ +// +// 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/utility/inputStreamPointerAdapter.hpp" + + +namespace vmime { +namespace utility { + + +inputStreamPointerAdapter::inputStreamPointerAdapter(std::istream* is, const bool own) + : inputStreamAdapter(*is), + m_stream(is), + m_own(own) { + +} + + +inputStreamPointerAdapter::~inputStreamPointerAdapter() { + + if (m_own) { + delete m_stream; + } +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/inputStreamPointerAdapter.hpp b/vmime-master/src/vmime/utility/inputStreamPointerAdapter.hpp new file mode 100644 index 0000000..e48f9ce --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamPointerAdapter.hpp @@ -0,0 +1,61 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED + + +#include "vmime/utility/inputStreamAdapter.hpp" + +#include <istream> + + +namespace vmime { +namespace utility { + + +/** An adapter class for pointer to C++ standard input stream. + */ +class VMIME_EXPORT inputStreamPointerAdapter : public inputStreamAdapter { + +public: + + /** @param is input stream to wrap + * @param own if set to 'true', the pointer will be deleted when + * this object is destroyed + */ + inputStreamPointerAdapter(std::istream* is, const bool own = true); + ~inputStreamPointerAdapter(); + +private: + + std::istream* m_stream; + const bool m_own; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/inputStreamSocketAdapter.cpp b/vmime-master/src/vmime/utility/inputStreamSocketAdapter.cpp new file mode 100644 index 0000000..515906b --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamSocketAdapter.cpp @@ -0,0 +1,79 @@ +// +// 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/utility/inputStreamSocketAdapter.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace utility { + + +inputStreamSocketAdapter::inputStreamSocketAdapter(net::socket& sok) + : m_socket(sok) { + +} + + +bool inputStreamSocketAdapter::eof() const { + + // Can't know... + return false; +} + + +void inputStreamSocketAdapter::reset() { + + // Not supported +} + + +size_t inputStreamSocketAdapter::read(byte_t* const data, const size_t count) { + + return m_socket.receiveRaw(data, count); +} + + +size_t inputStreamSocketAdapter::skip(const size_t /* count */) { + + // Not supported + return 0; +} + + +size_t inputStreamSocketAdapter::getBlockSize() { + + return m_socket.getBlockSize(); +} + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/vmime-master/src/vmime/utility/inputStreamSocketAdapter.hpp b/vmime-master/src/vmime/utility/inputStreamSocketAdapter.hpp new file mode 100644 index 0000000..1650037 --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamSocketAdapter.hpp @@ -0,0 +1,75 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED + + +#include "vmime/utility/inputStream.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +namespace vmime { +namespace net { + class socket; // forward reference +} // net +} // vmime + + +namespace vmime { +namespace utility { + + +/** An input stream that is connected to a socket. + */ +class VMIME_EXPORT inputStreamSocketAdapter : public inputStream { + +public: + + inputStreamSocketAdapter(net::socket& sok); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + + size_t getBlockSize(); + +private: + + inputStreamSocketAdapter(const inputStreamSocketAdapter&); + + net::socket& m_socket; +}; + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/inputStreamStringAdapter.cpp b/vmime-master/src/vmime/utility/inputStreamStringAdapter.cpp new file mode 100644 index 0000000..bf09a9b --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamStringAdapter.cpp @@ -0,0 +1,119 @@ +// +// 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/utility/inputStreamStringAdapter.hpp" + + +namespace vmime { +namespace utility { + + +inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer) + : m_buffer(buffer), + m_begin(0), + m_end(buffer.length()), + m_pos(0) { + +} + + +inputStreamStringAdapter::inputStreamStringAdapter( + const string& buffer, + const size_t begin, + const size_t end +) + : m_buffer(buffer), + m_begin(begin), + m_end(end), + m_pos(begin) { + +} + + +bool inputStreamStringAdapter::eof() const { + + return m_pos >= m_end; +} + + +void inputStreamStringAdapter::reset() { + + m_pos = m_begin; +} + + +size_t inputStreamStringAdapter::read(byte_t* const data, const size_t count) { + + if (m_pos + count >= m_end) { + + const size_t remaining = m_end - m_pos; + + std::copy(m_buffer.begin() + m_pos, m_buffer.end(), data); + m_pos = m_end; + + return remaining; + + } else { + + std::copy(m_buffer.begin() + m_pos, m_buffer.begin() + m_pos + count, data); + m_pos += count; + + return count; + } +} + + +size_t inputStreamStringAdapter::skip(const size_t count) { + + if (m_pos + count >= m_end) { + + const size_t remaining = m_end - m_pos; + m_pos = m_end; + + return remaining; + + } else { + + m_pos += count; + + return count; + } +} + + +size_t inputStreamStringAdapter::getPosition() const { + + return m_pos - m_begin; +} + + +void inputStreamStringAdapter::seek(const size_t pos) { + + if (m_begin + pos <= m_end) { + m_pos = m_begin + pos; + } +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/inputStreamStringAdapter.hpp b/vmime-master/src/vmime/utility/inputStreamStringAdapter.hpp new file mode 100644 index 0000000..2c2cbb8 --- /dev/null +++ b/vmime-master/src/vmime/utility/inputStreamStringAdapter.hpp @@ -0,0 +1,66 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for string input. + */ +class VMIME_EXPORT inputStreamStringAdapter : public seekableInputStream { + +public: + + inputStreamStringAdapter(const string& buffer); + inputStreamStringAdapter(const string& buffer, const size_t begin, const size_t end); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + inputStreamStringAdapter(const inputStreamStringAdapter&); + + const string m_buffer; // do _NOT_ keep a reference... + const size_t m_begin; + const size_t m_end; + size_t m_pos; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/outputStream.cpp b/vmime-master/src/vmime/utility/outputStream.cpp new file mode 100644 index 0000000..b07fb07 --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStream.cpp @@ -0,0 +1,44 @@ +// +// 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/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +void outputStream::write(const byte_t* const data, const size_t count) { + + writeImpl(data, count); +} + + +void outputStream::write(const char* const data, const size_t count) { + + writeImpl(reinterpret_cast <const byte_t*>(data), count); +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/outputStream.hpp b/vmime-master/src/vmime/utility/outputStream.hpp new file mode 100644 index 0000000..318c1dd --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStream.hpp @@ -0,0 +1,133 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED + + +#include "vmime/utility/stream.hpp" + + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC++6 +# include <cstring> +#endif + + +namespace vmime { +namespace utility { + + +/** Simple output stream. + */ +class VMIME_EXPORT outputStream : public stream { + +public: + + /** Write data to the stream. + * + * @param data buffer containing data to write + * @param count number of bytes to write + */ + void write(const byte_t* const data, const size_t count); + + /** Write data to the stream. + * + * @param data buffer containing data to write + * @param count number of bytes to write + */ + void write(const char* const data, const size_t count); + + /** Write data to the stream. + * + * @param data buffer containing data to write + * @param N number of bytes to write, including terminating + * null (value is induced by compiler) + */ + template <int N> + void write(const char (&data)[N]) { + + write(data, N - 1); + } + + /** Flush this output stream and forces any buffered output + * bytes to be written out to the stream. + */ + virtual void flush() = 0; + +protected: + + /** Write data to the stream. + * This is the method to be implemented is subclasses. + * + * @param data buffer containing data to write + * @param count number of bytes to write + */ + virtual void writeImpl(const byte_t* const data, const size_t count) = 0; +}; + + +// Helpers functions + +VMIME_EXPORT outputStream& operator<<(outputStream& os, const string& str); +VMIME_EXPORT outputStream& operator<<(outputStream& os, const byte_t c); + + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) // Internal compiler error with VC++6 + +inline outputStream& operator<<(outputStream& os, const char* str) { + + os.write(reinterpret_cast <const byte_t*>(str), ::strlen(str)); + return os; +} + +#else + +template <int N> +outputStream& operator<<(outputStream& os, const char (&str)[N]) { + + os.write(reinterpret_cast <const byte_t*>(str), N - 1); + return os; +} + +#endif // defined(_MSC_VER) && (_MSC_VER <= 1200) + + +template <typename T> +outputStream& operator<<(outputStream& os, const T& t) { + + std::ostringstream oss; + oss.imbue(std::locale::classic()); // no formatting + + oss << t; + + os << oss.str(); + + return os; +} + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/outputStreamAdapter.cpp b/vmime-master/src/vmime/utility/outputStreamAdapter.cpp new file mode 100644 index 0000000..7455691 --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamAdapter.cpp @@ -0,0 +1,52 @@ +// +// 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/utility/outputStreamAdapter.hpp" + + +namespace vmime { +namespace utility { + + +outputStreamAdapter::outputStreamAdapter(std::ostream& os) + : m_stream(os) { + +} + + +void outputStreamAdapter::writeImpl(const byte_t* const data, const size_t count) { + + m_stream.exceptions(std::ios_base::badbit); + m_stream.write(reinterpret_cast <const char*>(data), count); +} + + +void outputStreamAdapter::flush() { + + m_stream.exceptions(std::ios_base::badbit); + m_stream.flush(); +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/outputStreamAdapter.hpp b/vmime-master/src/vmime/utility/outputStreamAdapter.hpp new file mode 100644 index 0000000..35c5cde --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamAdapter.hpp @@ -0,0 +1,63 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + +#include <ostream> + + +namespace vmime { +namespace utility { + + +/** An adapter class for C++ standard output streams. + */ +class VMIME_EXPORT outputStreamAdapter : public outputStream { + +public: + + /** @param os output stream to wrap + */ + outputStreamAdapter(std::ostream& os); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + std::ostream& m_stream; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.cpp b/vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.cpp new file mode 100644 index 0000000..a38bd79 --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.cpp @@ -0,0 +1,50 @@ +// +// 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/utility/outputStreamByteArrayAdapter.hpp" + + +namespace vmime { +namespace utility { + + +outputStreamByteArrayAdapter::outputStreamByteArrayAdapter(byteArray& array) + : m_array(array) { + +} + + +void outputStreamByteArrayAdapter::writeImpl(const byte_t* const data, const size_t count) { + + m_array.insert(m_array.end(), data, data + count); +} + + +void outputStreamByteArrayAdapter::flush() { + + // Do nothing +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.hpp b/vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.hpp new file mode 100644 index 0000000..f36ff9c --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.hpp @@ -0,0 +1,59 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for byte array output. + */ +class VMIME_EXPORT outputStreamByteArrayAdapter : public outputStream { + +public: + + outputStreamByteArrayAdapter(byteArray& array); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + byteArray& m_array; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/outputStreamSocketAdapter.cpp b/vmime-master/src/vmime/utility/outputStreamSocketAdapter.cpp new file mode 100644 index 0000000..cd82c44 --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamSocketAdapter.cpp @@ -0,0 +1,65 @@ +// +// 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/utility/outputStreamSocketAdapter.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace utility { + + +outputStreamSocketAdapter::outputStreamSocketAdapter(net::socket& sok) + : m_socket(sok) { + +} + + +void outputStreamSocketAdapter::writeImpl(const byte_t* const data, const size_t count) { + + m_socket.sendRaw(data, count); +} + + +void outputStreamSocketAdapter::flush() { + + // Do nothing +} + + +size_t outputStreamSocketAdapter::getBlockSize() { + + return m_socket.getBlockSize(); +} + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/vmime-master/src/vmime/utility/outputStreamSocketAdapter.hpp b/vmime-master/src/vmime/utility/outputStreamSocketAdapter.hpp new file mode 100644 index 0000000..4fb199b --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamSocketAdapter.hpp @@ -0,0 +1,76 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +namespace vmime { +namespace net { + class socket; // forward reference +} // net +} // vmime + + +namespace vmime { +namespace utility { + + +/** An output stream that is connected to a socket. + */ +class VMIME_EXPORT outputStreamSocketAdapter : public outputStream { + +public: + + outputStreamSocketAdapter(net::socket& sok); + + void flush(); + + size_t getBlockSize(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStreamSocketAdapter(const outputStreamSocketAdapter&); + + net::socket& m_socket; +}; + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/outputStreamStringAdapter.cpp b/vmime-master/src/vmime/utility/outputStreamStringAdapter.cpp new file mode 100644 index 0000000..12c809c --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamStringAdapter.cpp @@ -0,0 +1,52 @@ +// +// 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/utility/outputStreamStringAdapter.hpp" + +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime { +namespace utility { + + +outputStreamStringAdapter::outputStreamStringAdapter(string& buffer) + : m_buffer(buffer) { + +} + + +void outputStreamStringAdapter::writeImpl(const byte_t* const data, const size_t count) { + + vmime::utility::stringUtils::appendBytesToString(m_buffer, data, count); +} + + +void outputStreamStringAdapter::flush() { + + // Do nothing +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/outputStreamStringAdapter.hpp b/vmime-master/src/vmime/utility/outputStreamStringAdapter.hpp new file mode 100644 index 0000000..a29e2cb --- /dev/null +++ b/vmime-master/src/vmime/utility/outputStreamStringAdapter.hpp @@ -0,0 +1,59 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for string output. + */ +class VMIME_EXPORT outputStreamStringAdapter : public outputStream { + +public: + + outputStreamStringAdapter(string& buffer); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + string& m_buffer; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/parserInputStreamAdapter.cpp b/vmime-master/src/vmime/utility/parserInputStreamAdapter.cpp new file mode 100644 index 0000000..98bbe60 --- /dev/null +++ b/vmime-master/src/vmime/utility/parserInputStreamAdapter.cpp @@ -0,0 +1,175 @@ +// +// 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/utility/parserInputStreamAdapter.hpp" + + +namespace vmime { +namespace utility { + + +parserInputStreamAdapter::parserInputStreamAdapter(const shared_ptr <seekableInputStream>& stream) + : m_stream(stream) { + +} + + +bool parserInputStreamAdapter::eof() const { + + return m_stream->eof(); +} + + +void parserInputStreamAdapter::reset() { + + m_stream->reset(); +} + + +size_t parserInputStreamAdapter::read(byte_t* const data, const size_t count) { + + return m_stream->read(data, count); +} + + +shared_ptr <seekableInputStream> parserInputStreamAdapter::getUnderlyingStream() { + + return m_stream; +} + + +const string parserInputStreamAdapter::extract(const size_t begin, const size_t end) const { + + const size_t initialPos = m_stream->getPosition(); + + byte_t *buffer = NULL; + + try { + + buffer = new byte_t[end - begin + 1]; + + m_stream->seek(begin); + + const size_t readBytes = m_stream->read(buffer, end - begin); + buffer[readBytes] = '\0'; + + m_stream->seek(initialPos); + + string str(buffer, buffer + readBytes); + delete [] buffer; + + return str; + + } catch (...) { + + delete [] buffer; + + m_stream->seek(initialPos); + throw; + } +} + + +size_t parserInputStreamAdapter::findNext( + const string& token, + const size_t startPosition +) { + + static const unsigned int BUFFER_SIZE = 4096; + + // Token must not be longer than BUFFER_SIZE/2 + if (token.empty() || token.length() > BUFFER_SIZE / 2) { + return npos; + } + + const size_t initialPos = getPosition(); + + seek(startPosition); + + try { + + byte_t findBuffer[BUFFER_SIZE]; + byte_t* findBuffer1 = findBuffer; + byte_t* findBuffer2 = findBuffer + (BUFFER_SIZE / 2); + + size_t findBufferLen = 0; + size_t findBufferOffset = 0; + + bool isEOF = false; + + // Fill in initial buffer + findBufferLen = read(findBuffer, BUFFER_SIZE); + + while (findBufferLen != 0) { + + // Find token + for (byte_t *begin = findBuffer, *end = findBuffer + findBufferLen - token.length() ; + begin <= end ; ++begin) { + + if (begin[0] == token[0] && + (token.length() == 1 || + memcmp(static_cast <const void *>(&begin[1]), + static_cast <const void *>(token.data() + 1), + token.length() - 1) == 0)) { + + seek(initialPos); + + return startPosition + findBufferOffset + (begin - findBuffer); + } + } + + // Rotate buffer + memcpy(findBuffer1, findBuffer2, (BUFFER_SIZE / 2)); + + // Read more bytes + if (findBufferLen < BUFFER_SIZE && (eof() || isEOF)) { + + break; + + } else { + + const size_t bytesRead = read(findBuffer2, BUFFER_SIZE / 2); + + if (bytesRead == 0) { + isEOF = true; + } + + findBufferLen = (BUFFER_SIZE / 2) + bytesRead; + findBufferOffset += (BUFFER_SIZE / 2); + } + } + + seek(initialPos); + + } catch (...) { + + seek(initialPos); + throw; + } + + return npos; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/parserInputStreamAdapter.hpp b/vmime-master/src/vmime/utility/parserInputStreamAdapter.hpp new file mode 100644 index 0000000..e448d29 --- /dev/null +++ b/vmime-master/src/vmime/utility/parserInputStreamAdapter.hpp @@ -0,0 +1,172 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + +#include <cstring> + + +namespace vmime { +namespace utility { + + +/** An adapter class used for parsing from an input stream. + */ +class VMIME_EXPORT parserInputStreamAdapter : public seekableInputStream { + +public: + + /** @param stream input stream to wrap + */ + parserInputStreamAdapter(const shared_ptr <seekableInputStream>& stream); + + shared_ptr <seekableInputStream> getUnderlyingStream(); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + + void seek(const size_t pos) { + + m_stream->seek(pos); + } + + size_t skip(const size_t count) { + + return m_stream->skip(count); + } + + size_t getPosition() const { + + return m_stream->getPosition(); + } + + /** Get the byte at the current position without updating the + * current position. + * + * @return byte at the current position + */ + byte_t peekByte() const { + + const size_t initialPos = m_stream->getPosition(); + + try { + + byte_t buffer[1]; + const size_t readBytes = m_stream->read(buffer, 1); + + m_stream->seek(initialPos); + + return (readBytes == 1 ? buffer[0] : static_cast <byte_t>(0)); + + } catch (...) { + + m_stream->seek(initialPos); + throw; + } + } + + /** Get the byte at the current position and advance current + * position by one byte. + * + * @return byte at the current position + */ + byte_t getByte() { + + byte_t buffer[1]; + const size_t readBytes = m_stream->read(buffer, 1); + + return readBytes == 1 ? buffer[0] : static_cast <byte_t>(0); + } + + /** Check whether the bytes following the current position match + * the specified bytes. Position is not updated. + * + * @param bytes bytes to compare + * @param length number of bytes + * @return true if the next bytes match the pattern, false otherwise + */ + template <typename T> + bool matchBytes(const T* bytes, const size_t length) const { + + const size_t initialPos = m_stream->getPosition(); + + try { + + byte_t buffer[32]; + const size_t readBytes = m_stream->read(buffer, length); + + m_stream->seek(initialPos); + + return readBytes == length && ::memcmp(bytes, buffer, length) == 0; + + } catch (...) { + + m_stream->seek(initialPos); + throw; + } + } + + const string extract(const size_t begin, const size_t end) const; + + /** Skips bytes matching a predicate from the current position. + * The current position is updated to the next following byte + * which does not match the predicate. + * + * @param pred predicate + * @param endPosition stop at this position (or at end of the stream, + * whichever comes first) + * @return number of bytes skipped + */ + template <typename PREDICATE> + size_t skipIf(PREDICATE pred, const size_t endPosition) { + + const size_t initialPos = getPosition(); + size_t pos = initialPos; + + while (!m_stream->eof() && pos < endPosition && pred(getByte())) { + ++pos; + } + + m_stream->seek(pos); + + return pos - initialPos; + } + + size_t findNext(const string& token, const size_t startPosition = 0); + +private: + + mutable shared_ptr <seekableInputStream> m_stream; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/path.cpp b/vmime-master/src/vmime/utility/path.cpp new file mode 100644 index 0000000..0c70f11 --- /dev/null +++ b/vmime-master/src/vmime/utility/path.cpp @@ -0,0 +1,324 @@ +// +// 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/utility/path.hpp" + +#include <algorithm> + + +namespace vmime { +namespace utility { + + +path::path() { + +} + + +path::path(const component& c) { + + m_list.push_back(c); +} + + +path::path(const path& p) + : object() { + + m_list.resize(p.m_list.size()); + std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin()); +} + + +path::path(const string& s) { + + m_list.push_back(component(s)); +} + + +path path::operator/(const path& p) const { + + path pr(*this); + pr /= p; + + return pr; +} + + +path path::operator/(const component& c) const { + + path pr(*this); + pr /= c; + + return pr; +} + + +path& path::operator/=(const path& p) { + + const list::size_type size = m_list.size(); + + m_list.resize(size + p.m_list.size()); + std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin() + size); + + return *this; +} + + +path& path::operator/=(const component& c) { + + m_list.push_back(c); + return *this; +} + + +path path::getParent() const { + + path p; + + if (!isEmpty()) { + p.m_list.resize(m_list.size() - 1); + std::copy(m_list.begin(), m_list.end() - 1, p.m_list.begin()); + } + + return p; +} + + +path& path::operator=(const path& p) { + + m_list.resize(p.m_list.size()); + std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin()); + + return *this; +} + + +path& path::operator=(const component& c) { + + m_list.resize(1); + m_list[0] = c; + + return *this; +} + + +bool path::operator==(const path& p) const { + + if (m_list.size() != p.m_list.size()) { + return (false); + } + + list::const_iterator i = m_list.begin(); + list::const_iterator j = p.m_list.begin(); + + bool equal = true; + + for ( ; equal && i != m_list.end() ; ++i, ++j) { + equal = ((*i).isEquivalent(*j)); + } + + return equal; +} + + +bool path::operator!=(const path& p) const { + + return !(*this == p); +} + + +bool path::isEmpty() const { + + return m_list.empty(); +} + + +bool path::isRoot() const { + + return m_list.empty(); +} + + +const path::component path::getLastComponent() const { + + return m_list[m_list.size() - 1]; +} + + +path::component& path::getLastComponent() { + + return m_list[m_list.size() - 1]; +} + + +size_t path::getSize() const { + + return m_list.size(); +} + + +const path::component& path::operator[](const size_t x) const { + + return m_list[x]; +} + + +path::component& path::operator[](const size_t x) { + + return m_list[x]; +} + + +bool path::isDirectParentOf(const path& p) const { + + if (p.getSize() != getSize() + 1) { + return false; + } + + bool equal = true; + + for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) { + equal = (m_list[i].isEquivalent(p.m_list[i])); + } + + return equal; +} + + +bool path::isParentOf(const path& p) const { + + if (p.getSize() < getSize() + 1) { + return false; + } + + bool equal = true; + + for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) { + equal = (m_list[i].isEquivalent(p.m_list[i])); + } + + return equal; +} + + +void path::renameParent(const path& oldPath, const path& newPath) { + + if (isEmpty() || oldPath.getSize() > getSize()) { + return; + } + + bool equal = true; + list::size_type i; + + for (i = 0 ; equal && i < oldPath.m_list.size() ; ++i) { + equal = (m_list[i].isEquivalent(oldPath.m_list[i])); + } + + if (i != oldPath.m_list.size()) + return; + + list newList; + + for (list::size_type j = 0 ; j < newPath.m_list.size() ; ++j) { + newList.push_back(newPath.m_list[j]); + } + + for (list::size_type j = i ; j < m_list.size() ; ++j) { + newList.push_back(m_list[j]); + } + + m_list.resize(newList.size()); + std::copy(newList.begin(), newList.end(), m_list.begin()); +} + + +void path::appendComponent(const path::component& c) { + + m_list.push_back(c); +} + + +const path::component& path::getComponentAt(const size_t pos) const { + + return m_list[pos]; +} + + +path::component& path::getComponentAt(const size_t pos) { + + return m_list[pos]; +} + + +// static +path path::fromString(const string& str, const string& sep, const charset& cset) { + + path p; + + size_t start = 0; + size_t end = 0; + + do { + + end = str.find(sep, start); + + string comp; + + if (end == string::npos) { + comp = str.substr(start); + } else { + comp = str.substr(start, end - start); + } + + // Skip leading or trailing separators + if (comp.length()) { + p.appendComponent(component(comp, cset)); + } + + start = end + 1; + + } while (end != string::npos); + + return p; +} + + +const string path::toString(const string& sep, const charset& cset) const { + + string str; + + for (size_t i = 0 ; i < m_list.size() ; ++i) { + + if (i != 0) { + str += sep; + } + + str += m_list[i].getConvertedText(cset); + } + + return str; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/path.hpp b/vmime-master/src/vmime/utility/path.hpp new file mode 100644 index 0000000..f1f1514 --- /dev/null +++ b/vmime-master/src/vmime/utility/path.hpp @@ -0,0 +1,189 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_PATH_HPP_INCLUDED +#define VMIME_UTILITY_PATH_HPP_INCLUDED + + +#include <vector> + +#include "vmime/types.hpp" +#include "vmime/word.hpp" + + +namespace vmime { +namespace utility { + + +/** Abstract representation of a path (filesystem, mailbox, etc). + */ +class VMIME_EXPORT path : public object { + +public: + + typedef vmime::word component; + typedef std::vector <component> list; + + // Construct a path + path(); + path(const component& c); + path(const path& p); + explicit path(const string& s); + + // Append a component to a path + path operator/(const path& p) const; + path operator/(const component& c) const; + + path& operator/=(const path& p); + path& operator/=(const component& c); + + // Return the parent path + path getParent() const; + + // Assignment + path& operator=(const path& p); + path& operator=(const component& c); + + // Path comparison + bool operator==(const path& p) const; + bool operator!=(const path& p) const; + + /** Append a component to the path. + * + * @param c component to add + */ + void appendComponent(const component& c); + + /** Return the component at the specified position. + * + * @param pos position + * @return component at position 'pos' + */ + const component& getComponentAt(const size_t pos) const; + + /** Return the component at the specified position. + * + * @param pos position + * @return component at position 'pos' + */ + component& getComponentAt(const size_t pos); + + /** Test whether this path is empty (root). + * + * @return true if the path is empty (no components = root) + */ + bool isEmpty() const; + + /** Test whether this path is the root (alias for isEmpty()). + * + * @return true if the path is the root + */ + bool isRoot() const; + + /** Return the last component of this path (const version). + * + * @return last component + */ + const component getLastComponent() const; + + /** Return the last component of this path (non-const version). + * + * @return last component + */ + component& getLastComponent(); + + /** Return the number of components in this path. + * + * @return number of components + */ + size_t getSize() const; + + /** Return the specified component of the path (const version). + * + * @param x index of the component + * @return component at the specified index + */ + const component& operator[](const size_t x) const; + + /** Return the specified component of the path (non-const version). + * + * @param x index of the component + * @return component at the specified index + */ + component& operator[](const size_t x); + + /** Test whether this path is a direct parent of another one. + * + * @param p other path + * @return true if the specified path is a child + * of this path, false otherwise + */ + bool isDirectParentOf(const path& p) const; + + /** Test whether this path is a parent of another one. + * + * @param p other path + * @return true if the specified path is a child (direct or + * indirect) of this path, false otherwise + */ + bool isParentOf(const path& p) const; + + /** Rename a parent component in the path. + * Example: path("a/b/c/d").renameParent("a/b", "x/y/z") + * will return path("x/y/z/c/d"). + * + * @param oldPath old parent path + * @param newPath new parent path + */ + void renameParent(const path& oldPath, const path& newPath); + + /** Construct a new path from a string. + * + * @param str string representation of the path + * @param sep separator string (eg: "/") + * @param cset charset in which the path is encoded (use the value returned by + * vmime::charset::getLocalCharset() to use the default charset of your system) + * @return a new path corresponding to the specified string + */ + static path fromString(const string& str, const string& sep, const charset& cset); + + /** Returns a string representation of this path. + * + * @param sep separator string (eg: "/") + * @param cset charset in which to encode the components (use the value returned by + * vmime::charset::getLocalCharset() to use the default charset of your system) + * @return a string representing this path + */ + const string toString(const string& sep, const charset& cset) const; + +private: + + list m_list; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_PATH_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/progressListener.cpp b/vmime-master/src/vmime/utility/progressListener.cpp new file mode 100644 index 0000000..cc4969c --- /dev/null +++ b/vmime-master/src/vmime/utility/progressListener.cpp @@ -0,0 +1,78 @@ +// +// 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/utility/progressListener.hpp" + + +namespace vmime { +namespace utility { + + +// progressListenerSizeAdapter + +progressListenerSizeAdapter::progressListenerSizeAdapter( + progressListener* list, + const size_t total +) + : m_wrapped(list), + m_total(total) { + +} + + +void progressListenerSizeAdapter::start(const size_t predictedTotal) { + + if (m_wrapped) { + m_wrapped->start(predictedTotal); + } +} + + +void progressListenerSizeAdapter::progress(const size_t current, const size_t currentTotal) { + + if (m_wrapped) { + + if (currentTotal > m_total) { + m_total = currentTotal; + } + + m_wrapped->progress(current, m_total); + } +} + + +void progressListenerSizeAdapter::stop(const size_t total) { + + if (m_wrapped) { + + if (total > m_total) { + m_total = total; + } + + m_wrapped->stop(m_total); + } +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/progressListener.hpp b/vmime-master/src/vmime/utility/progressListener.hpp new file mode 100644 index 0000000..18b4e4d --- /dev/null +++ b/vmime-master/src/vmime/utility/progressListener.hpp @@ -0,0 +1,99 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED +#define VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED + + +#include "vmime/config.hpp" +#include "vmime/types.hpp" + + +namespace vmime { +namespace utility { + + +/** An interface to implement if you want to be notified + * of a state of progress by some objects. + */ +class VMIME_EXPORT progressListener { + +protected: + + virtual ~progressListener() { } + +public: + + /** Called at the beginning of the operation. + * + * @param predictedTotal predicted amount of units (this has + * no concrete meaning: these are not bytes, nor percentage...) + */ + virtual void start(const size_t predictedTotal) = 0; + + /** Called during the operation (can be called several times). + * + * @param current current position + * @param currentTotal adjusted total amount of units + */ + virtual void progress(const size_t current, const size_t currentTotal) = 0; + + /** Called at the end of the operation. + * + * @param total final total amount of units + */ + virtual void stop(const size_t total) = 0; +}; + + + +/** A progress listener used when total size is known by the + * receiver, but not by the notifier. + */ +class VMIME_EXPORT progressListenerSizeAdapter : public progressListener { + +public: + + /** Construct a new progressListenerSizeAdapter object. + * + * @param list wrapped progress listener (can be NULL) + * @param total predicted total + */ + progressListenerSizeAdapter(progressListener* list, const size_t total); + + void start(const size_t predictedTotal); + void progress(const size_t current, const size_t currentTotal); + void stop(const size_t total); + +private: + + progressListener* m_wrapped; + size_t m_total; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/random.cpp b/vmime-master/src/vmime/utility/random.cpp new file mode 100644 index 0000000..055122b --- /dev/null +++ b/vmime-master/src/vmime/utility/random.cpp @@ -0,0 +1,90 @@ +// +// 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/utility/random.hpp" +#include "vmime/platform.hpp" + +#include <ctime> + + +namespace vmime { +namespace utility { + + +static unsigned int getRandomSeed() { + + unsigned int seed; + + platform::getHandler()->generateRandomBytes( + reinterpret_cast <unsigned char*>(&seed), sizeof(seed) + ); + + return seed; +} + + +unsigned int random::getNext() { + + static unsigned int next = getRandomSeed(); + + // Park and Miller's minimal standard generator: + // xn+1 = (a * xn + b) mod c + // xn+1 = (16807 * xn) mod (2^31 - 1) + next = static_cast<unsigned int>((16807 * next) % 2147483647ul); + return next; +} + + +unsigned int random::getTime() { + + return static_cast <unsigned int>((platform::getHandler()->getUnixTime())); +} + + +unsigned int random::getProcess() { + + return platform::getHandler()->getProcessId(); +} + + +const string random::getString(const size_t length, const string& randomChars) { + + string res; + res.resize(length); + + const unsigned int x = static_cast <unsigned int>(randomChars.length()); + size_t c = 0; + + while (c < length) { + + for (unsigned int n = random::getNext() ; n != 0 && c < length ; n /= x) { + res[c++] = randomChars[n % x]; + } + } + + return res; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/random.hpp b/vmime-master/src/vmime/utility/random.hpp new file mode 100644 index 0000000..21f4949 --- /dev/null +++ b/vmime-master/src/vmime/utility/random.hpp @@ -0,0 +1,78 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_RANDOM_HPP_INCLUDED +#define VMIME_UTILITY_RANDOM_HPP_INCLUDED + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace utility { + + +/** Pseudo-random number generator. + */ +class random { + +public: + + /** Return a new random number. + * + * @return random number + */ + static unsigned int getNext(); + + /** Return the current time as a number (may be used to + * build "random" strings). + * + * @return time as a number + */ + static unsigned int getTime(); + + /** Return the current process number (may be user to + * build "random" strings). + * + * @return process number + */ + static unsigned int getProcess(); + + /** Return a random character string with the specified length. + * + * @param length length of the string to generate + * @param randomChars list of characters to use + * @return random string + */ + static const string getString( + const size_t length, + const string& randomChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + ); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_RANDOM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/seekableInputStream.hpp b/vmime-master/src/vmime/utility/seekableInputStream.hpp new file mode 100644 index 0000000..181e904 --- /dev/null +++ b/vmime-master/src/vmime/utility/seekableInputStream.hpp @@ -0,0 +1,62 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED + + +#include "vmime/utility/inputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An input stream that allows seeking within the input. + */ +class VMIME_EXPORT seekableInputStream : public inputStream { + +public: + + /** Returns the current position in this stream. + * + * @return the offset from the beginning of the stream, in bytes, + * at which the next read occurs + */ + virtual size_t getPosition() const = 0; + + /** Sets the position, measured from the beginning of this stream, + * at which the next read occurs. + * + * @param pos the offset position, measured in bytes from the + * beginning of the stream, at which to set the stream pointer. + */ + virtual void seek(const size_t pos) = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.cpp b/vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.cpp new file mode 100644 index 0000000..3272366 --- /dev/null +++ b/vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.cpp @@ -0,0 +1,111 @@ +// +// 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/utility/seekableInputStreamRegionAdapter.hpp" + + +namespace vmime { +namespace utility { + + +seekableInputStreamRegionAdapter::seekableInputStreamRegionAdapter( + const shared_ptr <seekableInputStream>& stream, + const size_t begin, + const size_t length +) + : m_stream(stream), + m_begin(begin), + m_length(length), + m_position(0) { + +} + + +bool seekableInputStreamRegionAdapter::eof() const { + + return m_position >= m_length; +} + + +void seekableInputStreamRegionAdapter::reset() { + + m_position = 0; +} + + +size_t seekableInputStreamRegionAdapter::read(byte_t* const data, const size_t count) { + + m_stream->seek(m_begin + m_position); + + size_t readBytes = 0; + + if (m_position + count >= m_length) { + + const size_t remaining = m_length - m_position; + readBytes = m_stream->read(data, remaining); + + } else { + + readBytes = m_stream->read(data, count); + } + + m_position += readBytes; + + return readBytes; +} + + +size_t seekableInputStreamRegionAdapter::skip(const size_t count) { + + if (m_position + count >= m_length) { + + const size_t remaining = m_length - m_position; + m_position += remaining; + return remaining; + + } else { + + m_position += count; + return count; + } +} + + +size_t seekableInputStreamRegionAdapter::getPosition() const { + + return m_position; +} + + +void seekableInputStreamRegionAdapter::seek(const size_t pos) { + + if (pos > m_length) { + m_position = m_length; + } else { + m_position = pos; + } +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.hpp b/vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.hpp new file mode 100644 index 0000000..8406b29 --- /dev/null +++ b/vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.hpp @@ -0,0 +1,73 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter for reading a limited region of a seekable input stream. + */ +class VMIME_EXPORT seekableInputStreamRegionAdapter : public seekableInputStream { + +public: + + /** Creates a new adapter for a seekableInputStream. + * + * @param stream source stream + * @param begin start position in source stream + * @param length region length in source stream + */ + seekableInputStreamRegionAdapter( + const shared_ptr <seekableInputStream>& stream, + const size_t begin, + const size_t length + ); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + shared_ptr <seekableInputStream> m_stream; + size_t m_begin; + size_t m_length; + size_t m_position; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/stream.cpp b/vmime-master/src/vmime/utility/stream.cpp new file mode 100644 index 0000000..96f99cb --- /dev/null +++ b/vmime-master/src/vmime/utility/stream.cpp @@ -0,0 +1,39 @@ +// +// 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/utility/stream.hpp" + + + +namespace vmime { +namespace utility { + + +size_t stream::getBlockSize() { + + return 32768; // 32 KB +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/stream.hpp b/vmime-master/src/vmime/utility/stream.hpp new file mode 100644 index 0000000..9aa1392 --- /dev/null +++ b/vmime-master/src/vmime/utility/stream.hpp @@ -0,0 +1,60 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_STREAM_HPP_INCLUDED +#define VMIME_UTILITY_STREAM_HPP_INCLUDED + + +#include <sstream> + +#include "vmime/config.hpp" +#include "vmime/types.hpp" +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { + + +/** Base class for input/output stream. + */ +class VMIME_EXPORT stream : public object, private noncopyable { + +public: + + virtual ~stream() { } + + /** Return the preferred maximum block size when reading + * from or writing to this stream. + * + * @return block size, in bytes + */ + virtual size_t getBlockSize(); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STREAM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/streamUtils.cpp b/vmime-master/src/vmime/utility/streamUtils.cpp new file mode 100644 index 0000000..793973c --- /dev/null +++ b/vmime-master/src/vmime/utility/streamUtils.cpp @@ -0,0 +1,130 @@ +// +// 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/utility/streamUtils.hpp" + +#include <algorithm> // for std::copy +#include <iterator> // for std::back_inserter + + + +namespace vmime { +namespace utility { + + +outputStream& operator<<(outputStream& os, const byte_t c) { + + os.write(&c, 1); + return os; +} + + +outputStream& operator<<(outputStream& os, const string& str) { + + os.write(str.data(), str.length()); + return os; +} + + +size_t bufferedStreamCopy(inputStream& is, outputStream& os) { + + return bufferedStreamCopy(is, os, 0, NULL); +} + + +size_t bufferedStreamCopyRange( + inputStream& is, + outputStream& os, + const size_t start, + const size_t length +) { + + const size_t blockSize = + std::min(is.getBlockSize(), os.getBlockSize()); + + is.skip(start); + + std::vector <byte_t> vbuffer(blockSize); + + byte_t* buffer = &vbuffer.front(); + size_t total = 0; + + while (!is.eof() && total < length) { + + const size_t remaining = std::min(length - total, blockSize); + const size_t read = is.read(buffer, remaining); + + if (read != 0) { + os.write(buffer, read); + total += read; + } + } + + return total; +} + + +size_t bufferedStreamCopy( + inputStream& is, + outputStream& os, + const size_t length, + progressListener* progress +) { + + const size_t blockSize = + std::min(is.getBlockSize(), os.getBlockSize()); + + std::vector <byte_t> vbuffer(blockSize); + + byte_t* buffer = &vbuffer.front(); + size_t total = 0; + + if (progress != NULL) { + progress->start(length); + } + + while (!is.eof()) { + + const size_t read = is.read(buffer, blockSize); + + if (read != 0) { + + os.write(buffer, read); + total += read; + + if (progress != NULL) { + progress->progress(total, std::max(total, length)); + } + } + } + + if (progress != NULL) { + progress->stop(total); + } + + return total; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/streamUtils.hpp b/vmime-master/src/vmime/utility/streamUtils.hpp new file mode 100644 index 0000000..5d81fbe --- /dev/null +++ b/vmime-master/src/vmime/utility/streamUtils.hpp @@ -0,0 +1,83 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED +#define VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED + + +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/outputStream.hpp" + +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace utility { + + +/** Copy data from one stream into another stream using a buffered method. + * + * @param is input stream (source data) + * @param os output stream (destination for data) + * @return number of bytes copied + */ +VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os); + +/** Copy data from one stream into another stream using a buffered method + * and copying only a specified range of data. + * + * @param is input stream (source data) + * @param os output stream (destination for data) + * @param start number of bytes to ignore before starting copying + * @param length maximum number of bytes to copy + * @return number of bytes copied + */ +VMIME_EXPORT size_t bufferedStreamCopyRange( + inputStream& is, + outputStream& os, + const size_t start, + const size_t length +); + +/** Copy data from one stream into another stream using a buffered method + * and notify progress state of the operation. + * + * @param is input stream (source data) + * @param os output stream (destination for data) + * @param length predicted number of bytes to copy + * @param progress listener to notify + * @return number of bytes copied + */ +VMIME_EXPORT size_t bufferedStreamCopy( + inputStream& is, + outputStream& os, + const size_t length, + progressListener* progress +); + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/stringUtils.cpp b/vmime-master/src/vmime/utility/stringUtils.cpp new file mode 100644 index 0000000..823a3ea --- /dev/null +++ b/vmime-master/src/vmime/utility/stringUtils.cpp @@ -0,0 +1,337 @@ +// +// 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/utility/stringUtils.hpp" +#include "vmime/parserHelpers.hpp" + + +namespace vmime { +namespace utility { + + +bool stringUtils::isStringEqualNoCase(const string& s1, const char* s2, const size_t n) { + + // 'n' is the number of characters to compare + // 's2' must be in lowercase letters only + if (s1.length() < n) { + return (false); + } + + const std::ctype <char>& fac = + std::use_facet <std::ctype <char> >(std::locale::classic()); + + bool equal = true; + + for (size_t i = 0 ; equal && i < n ; ++i) { + equal = (fac.tolower(static_cast <unsigned char>(s1[i])) == s2[i]); + } + + return equal; +} + + +bool stringUtils::isStringEqualNoCase(const string& s1, const string& s2) { + + if (s1.length() != s2.length()) { + return false; + } + + const std::ctype <char>& fac = + std::use_facet <std::ctype <char> >(std::locale::classic()); + + bool equal = true; + const string::const_iterator end = s1.end(); + + for (string::const_iterator i = s1.begin(), j = s2.begin() ; equal && i != end ; ++i, ++j) { + equal = (fac.tolower(static_cast <unsigned char>(*i)) == fac.tolower(static_cast <unsigned char>(*j))); + } + + return equal; +} + + +bool stringUtils::isStringEqualNoCase( + const string::const_iterator begin, + const string::const_iterator end, + const char* s, + const size_t n +) { + + if (static_cast <size_t>(end - begin) < n) { + return false; + } + + const std::ctype <char>& fac = + std::use_facet <std::ctype <char> >(std::locale::classic()); + + bool equal = true; + char* c = const_cast<char*>(s); + size_t r = n; + + for (string::const_iterator i = begin ; equal && r && *c ; ++i, ++c, --r) { + equal = (fac.tolower(static_cast <unsigned char>(*i)) == static_cast <unsigned char>(*c)); + } + + return r == 0 && equal; +} + + +const string stringUtils::toLower(const string& str) { + + const std::ctype <char>& fac = + std::use_facet <std::ctype <char> >(std::locale::classic()); + + string out; + out.resize(str.size()); + + for (size_t i = 0, len = str.length() ; i < len ; ++i) { + out[i] = fac.tolower(static_cast <unsigned char>(str[i])); + } + + return out; +} + + +const string stringUtils::toUpper(const string& str) { + + const std::ctype <char>& fac = + std::use_facet <std::ctype <char> >(std::locale::classic()); + + string out; + out.resize(str.size()); + + for (size_t i = 0, len = str.length() ; i < len ; ++i) { + out[i] = fac.toupper(static_cast <unsigned char>(str[i])); + } + + return out; +} + + +const string stringUtils::trim(const string& str) { + + string::const_iterator b = str.begin(); + string::const_iterator e = str.end(); + + if (b != e) { + + for ( ; b != e && parserHelpers::isSpace(*b) ; ++b) {} + for ( ; e != b && parserHelpers::isSpace(*(e - 1)) ; --e) {} + } + + return string(b, e); +} + + +size_t stringUtils::countASCIIchars( + const string::const_iterator begin, + const string::const_iterator end +) { + + size_t count = 0; + + for (string::const_iterator i = begin ; i != end ; ++i) { + + if (parserHelpers::isAscii(*i)) { + + if (*i != '=' || ((i + 1) != end && *(i + 1) != '?')) { // To avoid bad behaviour... + ++count; + } + } + } + + return count; +} + + +bool stringUtils::is7bit(const string& str) { + + return countASCIIchars(str.begin(), str.end()) == str.length(); +} + + +size_t stringUtils::findFirstNonASCIIchar( + const string::const_iterator begin, + const string::const_iterator end +) { + + size_t pos = string::npos; + + for (string::const_iterator i = begin ; i != end ; ++i) { + + if (!parserHelpers::isAscii(*i)) { + pos = i - begin; + break; + } + } + + return pos; +} + + +const string stringUtils::unquote(const string& str) { + + if (str.length() < 2) { + return str; + } + + if (str[0] != '"' || str[str.length() - 1] != '"') { + return str; + } + + string res; + res.reserve(str.length()); + + bool escaped = false; + + for (string::const_iterator it = str.begin() + 1, end = str.end() - 1 ; it != end ; ++it) { + + const char c = *it; + + if (escaped) { + + res += c; + escaped = false; + + } else if (!escaped && c == '\\') { + + escaped = true; + + } else { + + res += c; + } + } + + return res; +} + + +bool stringUtils::needQuoting(const string& str, const string& specialChars) { + + return str.find_first_of(specialChars.c_str()) != string::npos; +} + + +string stringUtils::quote( + const string& str, + const string& escapeSpecialChars, + const string& escapeChar +) { + + std::ostringstream oss; + size_t lastPos = 0, pos = 0; + + while ((pos = str.find_first_of(escapeSpecialChars, lastPos)) != string::npos) { + + oss << str.substr(lastPos, pos - lastPos) + << escapeChar + << str[pos]; + + lastPos = pos + 1; + } + + oss << str.substr(lastPos); + + return oss.str(); +} + + +bool stringUtils::isValidHostname(const vmime::string& hostname) { + + short numberOfDots = 0; + return isValidFQDNImpl(hostname, &numberOfDots); +} + + +bool stringUtils::isValidFQDN(const vmime::string& fqdn) { + + short numberOfDots = 0; + return isValidFQDNImpl(fqdn, &numberOfDots) && numberOfDots >= 2; +} + + +bool stringUtils::isValidFQDNImpl(const vmime::string& fqdn, short* numberOfDots) { + + bool alphanumOnly = true; + bool invalid = false; + bool previousIsDot = true; // dot is not allowed as the first char + bool previousIsDash = true; // dash is not allowed as the first char + + *numberOfDots = 0; + + for (size_t i = 0, n = fqdn.length() ; alphanumOnly && !invalid && i < n ; ++i) { + + const char c = fqdn[i]; + + alphanumOnly = ( + (c >= '0' && c <= '9') // DIGIT + || (c >= 'a' && c <= 'z') // ALPHA + || (c >= 'A' && c <= 'Z') // ALPHA + || (c == '.') + || (c == '-') + ); + + if (c == '-') { + + if (previousIsDot) { + invalid = true; // dash is not allowed as the first char + } + + previousIsDot = false; + previousIsDash = true; + + } else if (c == '.') { + + if (previousIsDash) { + + invalid = true; // dash is not allowed as the first char + + } else if (previousIsDot) { + + invalid = true; // consecutive dots are not allowed + + } else { + + ++*numberOfDots; + previousIsDot = true; + } + + previousIsDash = false; + + } else { + + previousIsDot = false; + previousIsDash = false; + } + } + + return alphanumOnly && + !previousIsDot && + !previousIsDash && + !invalid; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/stringUtils.hpp b/vmime-master/src/vmime/utility/stringUtils.hpp new file mode 100644 index 0000000..4678940 --- /dev/null +++ b/vmime-master/src/vmime/utility/stringUtils.hpp @@ -0,0 +1,271 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED +#define VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + +#include <sstream> + + +namespace vmime { +namespace utility { + + +/** Miscellaneous functions related to strings. + */ +class VMIME_EXPORT stringUtils { + +public: + + /** Makes a string from bytes. + * + * @param data pointer to buffer containing data + * @param count number of bytes to use from buffer + * @return a string object containing a copy of the specified data + */ + static const string makeStringFromBytes(const byte_t* data, const size_t count) { + + return string(reinterpret_cast <const char*>(data), count); + } + + /** Casts a string to bytes. + * + * @param str string + * @return pointer to the first byte of the string + */ + static const byte_t* bytesFromString(const string& str) { + + return reinterpret_cast <const byte_t*>(str.data()); + } + + /** Casts a NULL-terminated string to bytes. + * + * @param str string + * @return pointer to the first byte of the string + */ + static const byte_t* bytesFromString(const char* str) { + + return reinterpret_cast <const byte_t*>(str); + } + + /** Appends bytes to a string. + * + * @param str string to which append data + * @param data pointer to buffer containing data + * @param count number of bytes to use from buffer + * @return a reference to modified string + */ + static string& appendBytesToString(string& str, const byte_t* data, const size_t count) { + + str.append(reinterpret_cast <const char*>(data), count); + return str; + } + + /** Test two strings for equality (case insensitive). + * \warning Use this with ASCII-only strings. + * + * @param s1 first string + * @param s2 second string (must be in lower-case!) + * @param n length of the second string + * @return true if the two strings compare equally, false otherwise + */ + static bool isStringEqualNoCase(const string& s1, const char* s2, const size_t n); + + /** Test two strings for equality (case insensitive). + * \warning Use this with ASCII-only strings. + * + * @param s1 first string + * @param s2 second string + * @return true if the two strings compare equally, false otherwise + */ + static bool isStringEqualNoCase(const string& s1, const string& s2); + + /** Test two strings for equality (case insensitive). + * \warning Use this with ASCII-only strings. + * + * @param begin start position of the first string + * @param end end position of the first string + * @param s second string (must be in lower-case!) + * @param n length of the second string + * @return true if the two strings compare equally, false otherwise + */ + static bool isStringEqualNoCase( + const string::const_iterator begin, + const string::const_iterator end, + const char* s, + const size_t n + ); + + /** Transform all the characters in a string to lower-case. + * \warning Use this with ASCII-only strings. + * + * @param str the string to transform + * @return a new string in lower-case + */ + static const string toLower(const string& str); + + /** Transform all the characters in a string to upper-case. + * \warning Use this with ASCII-only strings. + * + * @param str the string to transform + * @return a new string in upper-case + */ + static const string toUpper(const string& str); + + /** Strip the space characters (SPC, TAB, CR, LF) at the beginning + * and at the end of the specified string. + * + * @param str string in which to strip spaces + * @return a new string with space characters removed + */ + static const string trim(const string& str); + + /** Return the number of 7-bit US-ASCII characters in a string. + * + * @param begin start position + * @param end end position + * @return number of ASCII characters + */ + static size_t countASCIIchars( + const string::const_iterator begin, + const string::const_iterator end + ); + + /** Returns whether the specified string is composed exclusively + * of 7-bit ASCII characters. + * + * @param str string to test + * @return true if the string is ASCII-only, false otherwise + */ + static bool is7bit(const string& str); + + /** Returns the position of the first non 7-bit US-ASCII character in a string. + * + * @param begin start position + * @param end end position + * @return position since begin, or string::npos + */ + static size_t findFirstNonASCIIchar( + const string::const_iterator begin, + const string::const_iterator end + ); + + /** Convert the specified value to a string value. + * + * @param value to convert + * @return value converted from type 'TYPE' + */ + template <class TYPE> + static const string toString(const TYPE& value) { + + std::ostringstream oss; + oss.imbue(std::locale::classic()); + + oss << value; + + return oss.str(); + } + + /** Convert the specified string value to a value of + * the specified type. + * + * @param value value to convert + * @return value converted into type 'TYPE' + */ + template <class TYPE> + static const TYPE fromString(const string& value) { + + TYPE ret; + + std::istringstream iss(value); + iss.imbue(std::locale::classic()); + + iss >> ret; + + return ret; + } + + /** Unquote the specified string and transform escaped characters. + * + * @param str string from which to remove quotes + * @return unquoted string + */ + static const string unquote(const string& str); + + /** Determines whether the specified string needs to be quoted. + * + * @param str string to test + * @param specialChars list of characters that will cause the + * string to be quoted + * @return true if the string needs to be quoted, false otherwise + */ + static bool needQuoting( + const string& str, + const string& specialChars = " \t\"(),:;<>@[\\]" + ); + + /** Quotes the specified string. + * + * @param str string to quote + * @param escapeSpecialChars list of characters that will be escaped + * @param escapeChar character that will be used for escaping (eg. '\') + * @return quoted string + */ + static string quote( + const string& str, + const string& escapeSpecialChars, + const string& escapeChar + ); + + /** Return whether the specified string is a valid host name + * or domain name. + * + * @param hostname string to test + * @return true if the string is a valid host name or domain + * name, or false otherwise + */ + static bool isValidHostname(const vmime::string& hostname); + + /** Return whether the specified string is a valid fully + * qualified domain name (FQDN). + * + * @param fqdn string to test + * @return true if the string seems to be a FQDN, false otherwise + */ + static bool isValidFQDN(const vmime::string& fqdn); + +private: + + static bool isValidFQDNImpl(const vmime::string& fqdn, short* minNumberOfDots); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/sync/autoLock.hpp b/vmime-master/src/vmime/utility/sync/autoLock.hpp new file mode 100644 index 0000000..a3d3a7c --- /dev/null +++ b/vmime-master/src/vmime/utility/sync/autoLock.hpp @@ -0,0 +1,65 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_SYNC_AUTOLOCK_HPP_INCLUDED +#define VMIME_UTILITY_SYNC_AUTOLOCK_HPP_INCLUDED + + +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { +namespace sync { + + +/** Critical section wrapper class + */ +template <class M> +class VMIME_EXPORT autoLock : public object { + +public: + + autoLock(const shared_ptr <M>& mutex) + : m_mutex(mutex) { + + m_mutex->lock(); + } + + ~autoLock() { + + m_mutex->unlock(); + } + +private: + + shared_ptr <M> m_mutex; +}; + + +} // sync +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SYNC_AUTOLOCK_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/sync/criticalSection.cpp b/vmime-master/src/vmime/utility/sync/criticalSection.cpp new file mode 100644 index 0000000..a1013cd --- /dev/null +++ b/vmime-master/src/vmime/utility/sync/criticalSection.cpp @@ -0,0 +1,44 @@ +// +// 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/utility/sync/criticalSection.hpp" + + +namespace vmime { +namespace utility { +namespace sync { + + +criticalSection::criticalSection() { + +} + + +criticalSection::~criticalSection() { + +} + + +} // sync +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/sync/criticalSection.hpp b/vmime-master/src/vmime/utility/sync/criticalSection.hpp new file mode 100644 index 0000000..1e7008c --- /dev/null +++ b/vmime-master/src/vmime/utility/sync/criticalSection.hpp @@ -0,0 +1,64 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_SYNC_CRITICALSECTION_HPP_INCLUDED +#define VMIME_UTILITY_SYNC_CRITICALSECTION_HPP_INCLUDED + + +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { +namespace sync { + + +/** Critical section class. + */ +class VMIME_EXPORT criticalSection : public object { + +public: + + virtual ~criticalSection(); + + /** Enters the critical section. + */ + virtual void lock() = 0; + + /** Leaves the critical section. + */ + virtual void unlock() = 0; + +protected: + + criticalSection(); + criticalSection(criticalSection&); +}; + + +} // sync +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SYNC_CRITICALSECTION_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/url.cpp b/vmime-master/src/vmime/utility/url.cpp new file mode 100644 index 0000000..59cb1f5 --- /dev/null +++ b/vmime-master/src/vmime/utility/url.cpp @@ -0,0 +1,431 @@ +// +// 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/utility/url.hpp" + +#include "vmime/parserHelpers.hpp" +#include "vmime/utility/urlUtils.hpp" +#include "vmime/exception.hpp" + +#include <sstream> + + +namespace vmime { +namespace utility { + + +// Unspecified port +const port_t url::UNSPECIFIED_PORT = static_cast <port_t>(-1); + +// Known protocols +const string url::PROTOCOL_FILE = "file"; +const string url::PROTOCOL_HTTP = "http"; +const string url::PROTOCOL_FTP = "ftp"; + + + +url::url(const string& s) { + + parse(s); +} + + +url::url(const url& u) { + + operator=(u); +} + + +url::url( + const string& protocol, + const string& host, + const port_t port, + const string& path, + const string& username, + const string& password +) + : m_protocol(protocol), + m_username(username), + m_password(password), + m_host(host), + m_port(port), + m_path(path) { + +} + + +url& url::operator=(const url& u) { + + m_protocol = u.m_protocol; + + m_username = u.m_username; + m_password = u.m_password; + + m_host = u.m_host; + m_port = u.m_port; + + m_path = u.m_path; + + m_params = u.m_params; + + return *this; +} + + +url& url::operator=(const string& s) { + + parse(s); + + return *this; +} + + +url::operator string() const { + + return build(); +} + + +const string url::build() const { + + std::ostringstream oss; + oss.imbue(std::locale::classic()); + + oss << m_protocol << "://"; + + if (!m_username.empty()) { + + oss << urlUtils::encode(m_username); + + if (!m_password.empty()) { + + oss << ":"; + oss << urlUtils::encode(m_password); + } + + oss << "@"; + } + + oss << urlUtils::encode(m_host); + + if (m_port != UNSPECIFIED_PORT) { + + oss << ":"; + oss << m_port; + } + + if (!m_path.empty()) { + + oss << "/"; + oss << urlUtils::encode(m_path); + } + + + if (!m_params.empty()) { + + if (m_path.empty()) { + oss << "/"; + } + + oss << "?"; + + for (std::map <string, string>::const_iterator it = m_params.begin() ; + it != m_params.end() ; ++it) { + + if (it != m_params.begin()) { + oss << "&"; + } + + oss << urlUtils::encode((*it).first); + oss << "="; + oss << urlUtils::encode((*it).second); + } + } + + return oss.str(); +} + + +void url::parse(const string& str) { + + // Protocol + const size_t protoEnd = str.find("://"); + + if (protoEnd == string::npos) { + throw exceptions::malformed_url("No protocol separator"); + } + + const string proto = + utility::stringUtils::toLower(string(str.begin(), str.begin() + protoEnd)); + + // Username/password + size_t slashPos = str.find('/', protoEnd + 3); + + if (slashPos == string::npos) { + slashPos = str.length(); + } + + size_t atPos = str.rfind('@', slashPos); + string hostPart; + + string username; + string password; + + if (proto == PROTOCOL_FILE) { + + // No user name, password and host part. + slashPos = protoEnd + 3; + + } else { + + if (atPos != string::npos && atPos < slashPos) { + + const string userPart(str.begin() + protoEnd + 3, str.begin() + atPos); + const size_t colonPos = userPart.find(':'); + + if (colonPos == string::npos) { + + username = userPart; + + } else { + + username = string(userPart.begin(), userPart.begin() + colonPos); + password = string(userPart.begin() + colonPos + 1, userPart.end()); + } + + hostPart = string(str.begin() + atPos + 1, str.begin() + slashPos); + + } else { + + hostPart = string(str.begin() + protoEnd + 3, str.begin() + slashPos); + } + } + + // Host/port + const size_t colonPos = hostPart.find(':'); + + string host; + string port; + + if (colonPos == string::npos) { + + host = utility::stringUtils::trim(hostPart); + + } else { + + host = utility::stringUtils::trim(string(hostPart.begin(), hostPart.begin() + colonPos)); + port = utility::stringUtils::trim(string(hostPart.begin() + colonPos + 1, hostPart.end())); + } + + // Path + string path = utility::stringUtils::trim(string(str.begin() + slashPos, str.end())); + string params; + + size_t paramSep = path.find_first_of('?'); + + if (paramSep != string::npos) { + + params = string(path.begin() + paramSep + 1, path.end()); + path.erase(path.begin() + paramSep, path.end()); + } + + if (path == "/") { + path.clear(); + } + + // Some sanity check + if (proto.empty()) { + + throw exceptions::malformed_url("No protocol specified"); + + } else if (host.empty()) { + + // Accept empty host (eg. "file:///home/vincent/mydoc") + if (proto != PROTOCOL_FILE) { + throw exceptions::malformed_url("No host specified"); + } + } + + bool onlyDigit = true; + + for (string::const_iterator it = port.begin() ; + onlyDigit && it != port.end() ; ++it) { + + onlyDigit = parserHelpers::isDigit(*it); + } + + if (!onlyDigit) { + throw exceptions::malformed_url("Port can only contain digits"); + } + + std::istringstream iss(port); + iss.imbue(std::locale::classic()); + + port_t portNum = 0; + iss >> portNum; + + if (portNum == 0) { + portNum = UNSPECIFIED_PORT; + } + + // Extract parameters + m_params.clear(); + + if (!params.empty()) { + + size_t pos = 0; + + do { + + const size_t start = pos; + + pos = params.find_first_of('&', pos); + + const size_t equal = params.find_first_of('=', start); + const size_t end = (pos == string::npos ? params.length() : pos); + + string name; + string value; + + if (equal == string::npos || equal > pos) { // no value + + name = string(params.begin() + start, params.begin() + end); + value = name; + + } else { + + name = string(params.begin() + start, params.begin() + equal); + value = string(params.begin() + equal + 1, params.begin() + end); + } + + name = urlUtils::decode(name); + value = urlUtils::decode(value); + + m_params[name] = value; + + if (pos != string::npos) { + ++pos; + } + + } while (pos != string::npos); + } + + // Now, save URL parts + m_protocol = proto; + + m_username = urlUtils::decode(username); + m_password = urlUtils::decode(password); + + m_host = urlUtils::decode(host); + m_port = portNum; + + m_path = urlUtils::decode(path); +} + + +const string& url::getProtocol() const { + + return m_protocol; +} + + +void url::setProtocol(const string& protocol) { + + m_protocol = protocol; +} + + +const string& url::getUsername() const { + + return m_username; +} + + +void url::setUsername(const string& username) { + + m_username = username; +} + + +const string& url::getPassword() const { + + return m_password; +} + + +void url::setPassword(const string& password) { + + m_password = password; +} + + +const string& url::getHost() const { + + return m_host; +} + + +void url::setHost(const string& host) { + + m_host = host; +} + + +port_t url::getPort() const { + + return m_port; +} + + +void url::setPort(const port_t port) { + + m_port = port; +} + + +const string& url::getPath() const { + + return m_path; +} + + +void url::setPath(const string& path) { + + m_path = path; +} + + +const std::map <string, string>& url::getParams() const { + + return m_params; +} + + +std::map <string, string>& url::getParams() { + + return m_params; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/url.hpp b/vmime-master/src/vmime/utility/url.hpp new file mode 100644 index 0000000..8dfa3c4 --- /dev/null +++ b/vmime-master/src/vmime/utility/url.hpp @@ -0,0 +1,213 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_URL_HPP_INCLUDED +#define VMIME_UTILITY_URL_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" +#include "vmime/propertySet.hpp" + + +namespace vmime { +namespace utility { + + +/** This class represents a Uniform Resource Locator (a pointer + * to a "resource" on the World Wide Web). + * + * Format: + * "protocol://[username[:password]@]host[:port][/path]" + */ +class VMIME_EXPORT url { + +public: + + /** Means "port not specified" (use default port). */ + static const port_t UNSPECIFIED_PORT; + + /** Standard name for FILE protocol (local file-system). */ + static const string PROTOCOL_FILE; + + /** Standard name for HTTP protocol. */ + static const string PROTOCOL_HTTP; + + /** Standard name for FTP protocol. */ + static const string PROTOCOL_FTP; + + + /** Construct an URL from a string (parse the URL components). + * + * @param s full URL string (eg. http://www.vmime.org:80/download.html) + * @throw exceptions::malformed_url if URL is malformed + */ + url(const string& s); + + /** Construct an URL from another URL object. + * + * @param u other URL object + */ + url(const url& u); + + /** Construct an URL from the components. + * + * @param protocol protocol (eg. "http", "ftp"...) + * @param host host name (eg. "www.vmime.org", "123.45.67.89") + * @param port optional port number (eg. 80, 110 or UNSPECIFIED_PORT to mean "default") + * @param path optional full path (eg. "download.html") + * @param username optional user name + * @param password optional user password + */ + url( + const string& protocol, + const string& host, + const port_t port = UNSPECIFIED_PORT, + const string& path = "", + const string& username = "", + const string& password = "" + ); + + + /** Return the protocol of the URL (eg: "http"). + * + * @return protocol of the URL + */ + const string& getProtocol() const; + + /** Set the protocol of the URL. + * + * @param protocol new protocol (eg: "http") + */ + void setProtocol(const string& protocol); + + /** Return the username specified in the URL + * or empty if not specified. + * + * @return user name + */ + const string& getUsername() const; + + /** Set the username of the URL. + * + * @param username user name + */ + void setUsername(const string& username); + + /** Return the password specified in the URL + * or empty if not specified. + * + * @return user password + */ + const string& getPassword() const; + + /** Set the password of the URL. + * + * @param password user password + */ + void setPassword(const string& password); + + /** Return the host name of the URL (server name or IP address). + * + * @return host name + */ + const string& getHost() const; + + /** Set the host name of the URL. + * + * @param host server name or IP address + */ + void setHost(const string& host); + + /** Return the port of the URL, or url::UNSPECIFIED_PORT if + * the default port if used. + * + * @return server port + */ + port_t getPort() const; + + /** Set the port of the URL. + * + * @param port server port or url::UNSPECIFIED_PORT to + * use the default port of the protocol + */ + void setPort(const port_t port); + + /** Return the path portion of the URL, + * or empty if not specified. + * + * @return path + */ + const string& getPath() const; + + /** Set the part portion of the URL. + * + * @param path path + */ + void setPath(const string& path); + + /** Return the parameters of the URL (read-only). + * + * @return parameters + */ + const std::map <string, string>& getParams() const; + + /** Return the parameters of the URL. + * + * @return parameters + */ + std::map <string, string>& getParams(); + + /** Build a string URL from this object. + */ + operator string() const; + + url& operator=(const url& u); + url& operator=(const string& s); + +private: + + const string build() const; + void parse(const string& str); + + + string m_protocol; + + string m_username; + string m_password; + + string m_host; + + port_t m_port; + + string m_path; + + std::map <string, string> m_params; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_URL_HPP_INCLUDED diff --git a/vmime-master/src/vmime/utility/urlUtils.cpp b/vmime-master/src/vmime/utility/urlUtils.cpp new file mode 100644 index 0000000..cf51a50 --- /dev/null +++ b/vmime-master/src/vmime/utility/urlUtils.cpp @@ -0,0 +1,133 @@ +// +// 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/utility/urlUtils.hpp" +#include "vmime/parserHelpers.hpp" + + +namespace vmime { +namespace utility { + + +const string urlUtils::encode(const string& s) { + + static const string RESERVED_CHARS = + /* reserved */ "$&+,/:;=?@" + /* unsafe */ "<>#%{}[]|\\^\"~`"; + + string result; + result.reserve(s.length()); + + for (string::const_iterator it = s.begin() ; it != s.end() ; ++it) { + + const char c = *it; + + if (parserHelpers::isPrint(c) && !parserHelpers::isSpace(c) && + static_cast <unsigned char>(c) <= 127 && + RESERVED_CHARS.find(c) == string::npos) { + + result += c; + + } else { + + char hex[4]; + const unsigned char k = static_cast <unsigned char>(c); + + hex[0] = '%'; + hex[1] = "0123456789ABCDEF"[k / 16]; + hex[2] = "0123456789ABCDEF"[k % 16]; + hex[3] = 0; + + result += hex; + } + } + + return result; +} + + +const string urlUtils::decode(const string& s) { + + string result; + result.reserve(s.length()); + + for (string::const_iterator it = s.begin() ; it != s.end() ; ) { + + const char c = *it; + + switch (c) { + + case '%': { + + ++it; // skip '%' + + const char_t p = (it != s.end() ? *(it++) : 0); + const char_t q = (it != s.end() ? *(it++) : 0); + + unsigned int r = 0; + + switch (p) { + + case 0: r = '%'; break; + case 'a': case 'A': r = 10; break; + case 'b': case 'B': r = 11; break; + case 'c': case 'C': r = 12; break; + case 'd': case 'D': r = 13; break; + case 'e': case 'E': r = 14; break; + case 'f': case 'F': r = 15; break; + default: r = p - '0'; break; + } + + if (q != 0) { + + r *= 16; + + switch (q) { + + case 'a': case 'A': r += 10; break; + case 'b': case 'B': r += 11; break; + case 'c': case 'C': r += 12; break; + case 'd': case 'D': r += 13; break; + case 'e': case 'E': r += 14; break; + case 'f': case 'F': r += 15; break; + default: r += q - '0'; break; + } + } + + result += static_cast <char>(r); + break; + } + default: + + result += c; + ++it; + break; + } + } + + return result; +} + + +} // utility +} // vmime diff --git a/vmime-master/src/vmime/utility/urlUtils.hpp b/vmime-master/src/vmime/utility/urlUtils.hpp new file mode 100644 index 0000000..54ffa2a --- /dev/null +++ b/vmime-master/src/vmime/utility/urlUtils.hpp @@ -0,0 +1,57 @@ +// +// 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. +// + +#ifndef VMIME_UTILITY_URLUTILS_HPP_INCLUDED +#define VMIME_UTILITY_URLUTILS_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { + + +/** Miscellaneous functions related to URLs. + */ +class VMIME_EXPORT urlUtils { + +public: + + /** Encode extended characters in a URL string (ASCII characters + * are unmodified, other are encoded as '%' followed by hex code). + */ + static const string encode(const string& s); + + /** Decode an hex-encoded URL (see encode()). + */ + static const string decode(const string& s); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_URLUTILS_HPP_INCLUDED |