aboutsummaryrefslogtreecommitdiff
path: root/vmime-master/src/vmime/utility
diff options
context:
space:
mode:
authorWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
committerWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
commitaa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch)
tree4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /vmime-master/src/vmime/utility
downloadsmtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.tar.gz
smtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.zip
initial/final commitHEADmaster
Diffstat (limited to 'vmime-master/src/vmime/utility')
-rw-r--r--vmime-master/src/vmime/utility/childProcess.hpp103
-rw-r--r--vmime-master/src/vmime/utility/datetimeUtils.cpp317
-rw-r--r--vmime-master/src/vmime/utility/datetimeUtils.hpp98
-rw-r--r--vmime-master/src/vmime/utility/encoder/b64Encoder.cpp350
-rw-r--r--vmime-master/src/vmime/utility/encoder/b64Encoder.hpp73
-rw-r--r--vmime-master/src/vmime/utility/encoder/binaryEncoder.cpp39
-rw-r--r--vmime-master/src/vmime/utility/encoder/binaryEncoder.hpp51
-rw-r--r--vmime-master/src/vmime/utility/encoder/eightBitEncoder.cpp39
-rw-r--r--vmime-master/src/vmime/utility/encoder/eightBitEncoder.hpp51
-rw-r--r--vmime-master/src/vmime/utility/encoder/encoder.cpp76
-rw-r--r--vmime-master/src/vmime/utility/encoder/encoder.hpp135
-rw-r--r--vmime-master/src/vmime/utility/encoder/encoderFactory.cpp149
-rw-r--r--vmime-master/src/vmime/utility/encoder/encoderFactory.hpp164
-rw-r--r--vmime-master/src/vmime/utility/encoder/noopEncoder.cpp94
-rw-r--r--vmime-master/src/vmime/utility/encoder/noopEncoder.hpp66
-rw-r--r--vmime-master/src/vmime/utility/encoder/qpEncoder.cpp568
-rw-r--r--vmime-master/src/vmime/utility/encoder/qpEncoder.hpp77
-rw-r--r--vmime-master/src/vmime/utility/encoder/sevenBitEncoder.cpp39
-rw-r--r--vmime-master/src/vmime/utility/encoder/sevenBitEncoder.hpp51
-rw-r--r--vmime-master/src/vmime/utility/encoder/uuEncoder.cpp358
-rw-r--r--vmime-master/src/vmime/utility/encoder/uuEncoder.hpp68
-rw-r--r--vmime-master/src/vmime/utility/file.hpp264
-rw-r--r--vmime-master/src/vmime/utility/filteredStream.cpp402
-rw-r--r--vmime-master/src/vmime/utility/filteredStream.hpp405
-rw-r--r--vmime-master/src/vmime/utility/inputStream.cpp33
-rw-r--r--vmime-master/src/vmime/utility/inputStream.hpp75
-rw-r--r--vmime-master/src/vmime/utility/inputStreamAdapter.cpp84
-rw-r--r--vmime-master/src/vmime/utility/inputStreamAdapter.hpp65
-rw-r--r--vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.cpp104
-rw-r--r--vmime-master/src/vmime/utility/inputStreamByteBufferAdapter.hpp63
-rw-r--r--vmime-master/src/vmime/utility/inputStreamPointerAdapter.cpp48
-rw-r--r--vmime-master/src/vmime/utility/inputStreamPointerAdapter.hpp61
-rw-r--r--vmime-master/src/vmime/utility/inputStreamSocketAdapter.cpp79
-rw-r--r--vmime-master/src/vmime/utility/inputStreamSocketAdapter.hpp75
-rw-r--r--vmime-master/src/vmime/utility/inputStreamStringAdapter.cpp119
-rw-r--r--vmime-master/src/vmime/utility/inputStreamStringAdapter.hpp66
-rw-r--r--vmime-master/src/vmime/utility/outputStream.cpp44
-rw-r--r--vmime-master/src/vmime/utility/outputStream.hpp133
-rw-r--r--vmime-master/src/vmime/utility/outputStreamAdapter.cpp52
-rw-r--r--vmime-master/src/vmime/utility/outputStreamAdapter.hpp63
-rw-r--r--vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.cpp50
-rw-r--r--vmime-master/src/vmime/utility/outputStreamByteArrayAdapter.hpp59
-rw-r--r--vmime-master/src/vmime/utility/outputStreamSocketAdapter.cpp65
-rw-r--r--vmime-master/src/vmime/utility/outputStreamSocketAdapter.hpp76
-rw-r--r--vmime-master/src/vmime/utility/outputStreamStringAdapter.cpp52
-rw-r--r--vmime-master/src/vmime/utility/outputStreamStringAdapter.hpp59
-rw-r--r--vmime-master/src/vmime/utility/parserInputStreamAdapter.cpp175
-rw-r--r--vmime-master/src/vmime/utility/parserInputStreamAdapter.hpp172
-rw-r--r--vmime-master/src/vmime/utility/path.cpp324
-rw-r--r--vmime-master/src/vmime/utility/path.hpp189
-rw-r--r--vmime-master/src/vmime/utility/progressListener.cpp78
-rw-r--r--vmime-master/src/vmime/utility/progressListener.hpp99
-rw-r--r--vmime-master/src/vmime/utility/random.cpp90
-rw-r--r--vmime-master/src/vmime/utility/random.hpp78
-rw-r--r--vmime-master/src/vmime/utility/seekableInputStream.hpp62
-rw-r--r--vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.cpp111
-rw-r--r--vmime-master/src/vmime/utility/seekableInputStreamRegionAdapter.hpp73
-rw-r--r--vmime-master/src/vmime/utility/stream.cpp39
-rw-r--r--vmime-master/src/vmime/utility/stream.hpp60
-rw-r--r--vmime-master/src/vmime/utility/streamUtils.cpp130
-rw-r--r--vmime-master/src/vmime/utility/streamUtils.hpp83
-rw-r--r--vmime-master/src/vmime/utility/stringUtils.cpp337
-rw-r--r--vmime-master/src/vmime/utility/stringUtils.hpp271
-rw-r--r--vmime-master/src/vmime/utility/sync/autoLock.hpp65
-rw-r--r--vmime-master/src/vmime/utility/sync/criticalSection.cpp44
-rw-r--r--vmime-master/src/vmime/utility/sync/criticalSection.hpp64
-rw-r--r--vmime-master/src/vmime/utility/url.cpp431
-rw-r--r--vmime-master/src/vmime/utility/url.hpp213
-rw-r--r--vmime-master/src/vmime/utility/urlUtils.cpp133
-rw-r--r--vmime-master/src/vmime/utility/urlUtils.hpp57
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