diff --git a/ChangeLog b/ChangeLog index 92c84c32..8e18f1ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,10 @@ VERSION 0.6.2-cvs * Added unit tests for utility::path and bodyPart. + * Added 'utility::datetimeUtils' to provide some time-related functions. + + * Fixed 'stringUtils' not in namespace 'utility'. + 2005-01-01 Vincent Richard * Converted all C-style casts to C++-style casts. diff --git a/SConstruct b/SConstruct index 178ccc88..fa155ba7 100644 --- a/SConstruct +++ b/SConstruct @@ -140,6 +140,7 @@ libvmime_sources = [ 'word.cpp', 'word.hpp', 'vmime.hpp', 'utility/file.hpp', + 'utility/datetimeUtils.cpp', 'utility/datetimeUtils.hpp', 'utility/md5.cpp', 'utility/md5.hpp', 'utility/path.cpp', 'utility/path.hpp', 'utility/random.cpp', 'utility/random.hpp', diff --git a/src/charset.cpp b/src/charset.cpp index f8c8c50e..ac144b0f 100644 --- a/src/charset.cpp +++ b/src/charset.cpp @@ -270,7 +270,7 @@ charset& charset::operator=(const string& name) const bool charset::operator==(const charset& value) const { - return (stringUtils::isStringEqualNoCase(m_name, value.m_name)); + return (utility::stringUtils::isStringEqualNoCase(m_name, value.m_name)); } diff --git a/src/contentDisposition.cpp b/src/contentDisposition.cpp index 3eb8aad8..45282025 100644 --- a/src/contentDisposition.cpp +++ b/src/contentDisposition.cpp @@ -32,7 +32,7 @@ contentDisposition::contentDisposition() contentDisposition::contentDisposition(const string& name) - : m_name(stringUtils::toLower(name)) + : m_name(utility::stringUtils::toLower(name)) { } @@ -46,7 +46,8 @@ contentDisposition::contentDisposition(const contentDisposition& type) void contentDisposition::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { - m_name = stringUtils::toLower(string(buffer.begin() + position, buffer.begin() + end)); + m_name = utility::stringUtils::toLower + (string(buffer.begin() + position, buffer.begin() + end)); setParsedBounds(position, end); @@ -67,14 +68,14 @@ void contentDisposition::generate(utility::outputStream& os, const string::size_ contentDisposition& contentDisposition::operator=(const string& name) { - m_name = stringUtils::toLower(name); + m_name = utility::stringUtils::toLower(name); return (*this); } const bool contentDisposition::operator==(const contentDisposition& value) const { - return (stringUtils::toLower(m_name) == value.m_name); + return (utility::stringUtils::toLower(m_name) == value.m_name); } diff --git a/src/encoderFactory.cpp b/src/encoderFactory.cpp index f73421eb..ef6474c2 100644 --- a/src/encoderFactory.cpp +++ b/src/encoderFactory.cpp @@ -62,7 +62,7 @@ encoder* encoderFactory::create(const string& name) const encoderFactory::registeredEncoder* encoderFactory::getEncoderByName(const string& name) const { - const string lcName(stringUtils::toLower(name)); + const string lcName(utility::stringUtils::toLower(name)); for (std::vector ::const_iterator it = m_encoders.begin() ; it != m_encoders.end() ; ++it) diff --git a/src/encoding.cpp b/src/encoding.cpp index 2ccded09..3e499ecc 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -35,7 +35,7 @@ encoding::encoding() encoding::encoding(const string& name) - : m_name(stringUtils::toLower(name)) + : m_name(utility::stringUtils::toLower(name)) { } @@ -49,7 +49,8 @@ encoding::encoding(const encoding& enc) void encoding::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { - m_name = stringUtils::toLower(string(buffer.begin() + position, buffer.begin() + end)); + m_name = utility::stringUtils::toLower + (string(buffer.begin() + position, buffer.begin() + end)); setParsedBounds(position, end); @@ -83,14 +84,14 @@ encoding& encoding::operator=(const encoding& other) encoding& encoding::operator=(const string& name) { - m_name = stringUtils::toLower(name); + m_name = utility::stringUtils::toLower(name); return (*this); } const bool encoding::operator==(const encoding& value) const { - return (stringUtils::toLower(m_name) == value.m_name); + return (utility::stringUtils::toLower(m_name) == value.m_name); } diff --git a/src/fileAttachment.cpp b/src/fileAttachment.cpp index 04e85123..08397350 100644 --- a/src/fileAttachment.cpp +++ b/src/fileAttachment.cpp @@ -72,7 +72,7 @@ void fileAttachment::generatePart(bodyPart& part) const contentDispositionField& cdf = part.getHeader()->ContentDisposition(); - if (m_fileInfo.hasSize()) cdf.setSize(stringUtils::toString(m_fileInfo.getSize())); + if (m_fileInfo.hasSize()) cdf.setSize(utility::stringUtils::toString(m_fileInfo.getSize())); if (m_fileInfo.hasFilename()) cdf.setFilename(m_fileInfo.getFilename()); if (m_fileInfo.hasCreationDate()) cdf.setCreationDate(m_fileInfo.getCreationDate()); if (m_fileInfo.hasModificationDate()) cdf.setModificationDate(m_fileInfo.getModificationDate()); diff --git a/src/header.cpp b/src/header.cpp index 67435241..c798d107 100644 --- a/src/header.cpp +++ b/src/header.cpp @@ -300,12 +300,12 @@ header& header::operator=(const header& other) const bool header::hasField(const string& fieldName) const { - const string name = stringUtils::toLower(fieldName); + const string name = utility::stringUtils::toLower(fieldName); std::vector ::const_iterator pos = m_fields.begin(); const std::vector ::const_iterator end = m_fields.end(); - for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos); return (pos != end); } @@ -313,13 +313,13 @@ const bool header::hasField(const string& fieldName) const headerField* header::findField(const string& fieldName) const { - const string name = stringUtils::toLower(fieldName); + const string name = utility::stringUtils::toLower(fieldName); // Find the first field that matches the specified name std::vector ::const_iterator pos = m_fields.begin(); const std::vector ::const_iterator end = m_fields.end(); - for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos); // No field with this name can be found if (pos == end) @@ -336,7 +336,7 @@ headerField* header::findField(const string& fieldName) const std::vector header::findAllFields(const string& fieldName) { - const string name = stringUtils::toLower(fieldName); + const string name = utility::stringUtils::toLower(fieldName); std::vector result; @@ -346,7 +346,7 @@ std::vector header::findAllFields(const string& fieldName) for ( ; pos != end ; ++pos) { // Add the header if it matches the specified type - if (stringUtils::toLower((*pos)->getName()) == name) + if (utility::stringUtils::toLower((*pos)->getName()) == name) { result.push_back(*pos); } @@ -358,13 +358,13 @@ std::vector header::findAllFields(const string& fieldName) headerField* header::getField(const string& fieldName) { - const string name = stringUtils::toLower(fieldName); + const string name = utility::stringUtils::toLower(fieldName); // Find the first field that matches the specified name std::vector ::const_iterator pos = m_fields.begin(); const std::vector ::const_iterator end = m_fields.end(); - for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos); // If no field with this name can be found, create a new one if (pos == end) diff --git a/src/headerFieldFactory.cpp b/src/headerFieldFactory.cpp index 9f6916e4..1bffc51a 100644 --- a/src/headerFieldFactory.cpp +++ b/src/headerFieldFactory.cpp @@ -66,7 +66,7 @@ headerFieldFactory::~headerFieldFactory() headerField* headerFieldFactory::create (const string& name, const string& body) { - NameMap::const_iterator pos = m_nameMap.find(stringUtils::toLower(name)); + NameMap::const_iterator pos = m_nameMap.find(utility::stringUtils::toLower(name)); headerField* field = NULL; if (pos != m_nameMap.end()) diff --git a/src/mediaType.cpp b/src/mediaType.cpp index 1c350dac..565fc691 100644 --- a/src/mediaType.cpp +++ b/src/mediaType.cpp @@ -38,7 +38,8 @@ mediaType::mediaType(const string& type) mediaType::mediaType(const string& type, const string& subType) - : m_type(stringUtils::toLower(type)), m_subType(stringUtils::toLower(subType)) + : m_type(utility::stringUtils::toLower(type)), + m_subType(utility::stringUtils::toLower(subType)) { } @@ -55,8 +56,9 @@ void mediaType::parse(const string& buffer, const string::size_type position, while (p < pend && *p != '/') ++p; - m_type = stringUtils::toLower(string(buffer.begin() + typeStart, - buffer.begin() + position + (p - pstart))); + m_type = utility::stringUtils::toLower( + string(buffer.begin() + typeStart, + buffer.begin() + position + (p - pstart))); if (p < pend) { @@ -64,8 +66,9 @@ void mediaType::parse(const string& buffer, const string::size_type position, ++p; // Extract the sub-type - m_subType = stringUtils::toLower(string(buffer.begin() + position + (p - pstart), - buffer.begin() + end)); + m_subType = utility::stringUtils::toLower( + string(buffer.begin() + position + (p - pstart), + buffer.begin() + end)); } setParsedBounds(position, end); @@ -147,7 +150,7 @@ const string& mediaType::getType() const void mediaType::setType(const string& type) { - m_type = stringUtils::toLower(type); + m_type = utility::stringUtils::toLower(type); } @@ -159,7 +162,7 @@ const string& mediaType::getSubType() const void mediaType::setSubType(const string& subType) { - m_subType = stringUtils::toLower(subType); + m_subType = utility::stringUtils::toLower(subType); } diff --git a/src/messaging/maildirStore.cpp b/src/messaging/maildirStore.cpp index 5f1ebb6c..2a180085 100644 --- a/src/messaging/maildirStore.cpp +++ b/src/messaging/maildirStore.cpp @@ -85,7 +85,7 @@ const bool maildirStore::isValidFolderName(const folder::path::component& name) const string& buf = name.getBuffer(); // Name cannot start/end with spaces - if (stringUtils::trim(buf) != name.getBuffer()) + if (utility::stringUtils::trim(buf) != name.getBuffer()) return false; // Name cannot start with '.' diff --git a/src/messaging/serviceFactory.cpp b/src/messaging/serviceFactory.cpp index a444ac1a..d046b03c 100644 --- a/src/messaging/serviceFactory.cpp +++ b/src/messaging/serviceFactory.cpp @@ -79,7 +79,7 @@ service* serviceFactory::create const serviceFactory::registeredService* serviceFactory::getServiceByProtocol(const string& protocol) const { - const string name(stringUtils::toLower(protocol)); + const string name(utility::stringUtils::toLower(protocol)); for (std::vector ::const_iterator it = m_services.begin() ; it != m_services.end() ; ++it) diff --git a/src/messaging/url.cpp b/src/messaging/url.cpp index 9d6ba0dd..1c83a4d4 100644 --- a/src/messaging/url.cpp +++ b/src/messaging/url.cpp @@ -131,7 +131,7 @@ void url::parse(const string& str) if (protoEnd == string::npos) throw exceptions::malformed_url("No protocol separator"); const string proto = - stringUtils::toLower(string(str.begin(), str.begin() + protoEnd)); + utility::stringUtils::toLower(string(str.begin(), str.begin() + protoEnd)); // Username/password string::size_type slashPos = str.find('/', protoEnd + 3); @@ -190,7 +190,7 @@ void url::parse(const string& str) } // Path - string path = stringUtils::trim(string(str.begin() + slashPos, str.end())); + string path = utility::stringUtils::trim(string(str.begin() + slashPos, str.end())); if (path == "/") path.clear(); diff --git a/src/parameterFactory.cpp b/src/parameterFactory.cpp index f1fbd0a3..6b3bde81 100644 --- a/src/parameterFactory.cpp +++ b/src/parameterFactory.cpp @@ -45,7 +45,7 @@ parameterFactory::~parameterFactory() parameter* parameterFactory::create (const string& name, const string& value) { - const string lcName = stringUtils::toLower(name); + const string lcName = utility::stringUtils::toLower(name); NameMap::const_iterator pos = m_nameMap.find(lcName); parameter* param = NULL; diff --git a/src/parameterizedHeaderField.cpp b/src/parameterizedHeaderField.cpp index f824fe11..fa7d70bc 100644 --- a/src/parameterizedHeaderField.cpp +++ b/src/parameterizedHeaderField.cpp @@ -248,12 +248,12 @@ parameterizedHeaderField& parameterizedHeaderField::operator=(const parameterize const bool parameterizedHeaderField::hasParameter(const string& paramName) const { - const string name = stringUtils::toLower(paramName); + const string name = utility::stringUtils::toLower(paramName); std::vector ::const_iterator pos = m_params.begin(); const std::vector ::const_iterator end = m_params.end(); - for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos); return (pos != end); } @@ -261,13 +261,13 @@ const bool parameterizedHeaderField::hasParameter(const string& paramName) const parameter* parameterizedHeaderField::findParameter(const string& paramName) const { - const string name = stringUtils::toLower(paramName); + const string name = utility::stringUtils::toLower(paramName); // Find the first parameter that matches the specified name std::vector ::const_iterator pos = m_params.begin(); const std::vector ::const_iterator end = m_params.end(); - for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos); // No parameter with this name can be found if (pos == end) @@ -284,13 +284,13 @@ parameter* parameterizedHeaderField::findParameter(const string& paramName) cons parameter* parameterizedHeaderField::getParameter(const string& paramName) { - const string name = stringUtils::toLower(paramName); + const string name = utility::stringUtils::toLower(paramName); // Find the first parameter that matches the specified name std::vector ::const_iterator pos = m_params.begin(); const std::vector ::const_iterator end = m_params.end(); - for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos); // If no parameter with this name can be found, create a new one if (pos == end) diff --git a/src/propertySet.cpp b/src/propertySet.cpp index 317a5add..edfaf8ff 100644 --- a/src/propertySet.cpp +++ b/src/propertySet.cpp @@ -308,7 +308,7 @@ const string propertySet::property::getValue() const template <> const bool propertySet::property::getValue() const { - if (stringUtils::toLower(m_value) == "true") + if (utility::stringUtils::toLower(m_value) == "true") return true; else { diff --git a/src/relay.cpp b/src/relay.cpp index 14521b38..43da65b2 100644 --- a/src/relay.cpp +++ b/src/relay.cpp @@ -115,32 +115,32 @@ void relay::parse(const string& buffer, const string::size_type position, if (!inComment) { - if (stringUtils::isStringEqualNoCase(word, "from", 4)) + if (utility::stringUtils::isStringEqualNoCase(word, "from", 4)) { newPart = Part_From; keyword = true; } - else if (stringUtils::isStringEqualNoCase(word, "by", 2)) + else if (utility::stringUtils::isStringEqualNoCase(word, "by", 2)) { newPart = Part_By; keyword = true; } - else if (stringUtils::isStringEqualNoCase(word, "via", 2)) + else if (utility::stringUtils::isStringEqualNoCase(word, "via", 2)) { newPart = Part_Via; keyword = true; } - else if (stringUtils::isStringEqualNoCase(word, "with", 2)) + else if (utility::stringUtils::isStringEqualNoCase(word, "with", 2)) { newPart = Part_With; keyword = true; } - else if (stringUtils::isStringEqualNoCase(word, "id", 2)) + else if (utility::stringUtils::isStringEqualNoCase(word, "id", 2)) { newPart = Part_Id; keyword = true; } - else if (stringUtils::isStringEqualNoCase(word, "for", 2)) + else if (utility::stringUtils::isStringEqualNoCase(word, "for", 2)) { newPart = Part_For; keyword = true; diff --git a/src/text.cpp b/src/text.cpp index fd210bab..d1cc8364 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -336,7 +336,7 @@ void text::encodeAndFold(utility::outputStream& os, const string::size_type maxL // Calculate the number of ASCII chars to check whether encoding is needed // and _which_ encoding to use. const string::size_type asciiCount = - stringUtils::countASCIIchars(buffer.begin(), buffer.end()); + utility::stringUtils::countASCIIchars(buffer.begin(), buffer.end()); bool noEncoding = (flags & FORCE_NO_ENCODING) || (!(flags & FORCE_ENCODING) && asciiCount == buffer.length()); diff --git a/src/utility/datetimeUtils.cpp b/src/utility/datetimeUtils.cpp new file mode 100644 index 00000000..2c9d6d08 --- /dev/null +++ b/src/utility/datetimeUtils.cpp @@ -0,0 +1,221 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "vmime/utility/datetimeUtils.hpp" + + +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::localTimeToUniversalTime(const datetime& date) +{ + if (date.getZone() == datetime::GMT) + return (date); + + 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::universalTimeToLocalTime(const datetime& date, const int zone) +{ + if (zone == 0) + return (date); + + datetime nd(date); + nd.setZone(zone); + + const int z = zone; + 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: 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); +} + + +const bool datetimeUtils::isLeapYear(const int year) +{ + // From RFC 3339 - Appendix C. Leap Years: + return ((year % 4) == 0 && (year % 100 != 0 || year % 400 == 0)); +} + + +const 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 }; + + return (isLeapYear(year) ? daysInMonthLeapYear[month - 1] : daysInMonth[month - 1]); +} + + +} // utility +} // vmime diff --git a/src/utility/stringUtils.cpp b/src/utility/stringUtils.cpp index eeb6f5a6..c087e032 100644 --- a/src/utility/stringUtils.cpp +++ b/src/utility/stringUtils.cpp @@ -20,8 +20,8 @@ #include "vmime/utility/stringUtils.hpp" -namespace vmime -{ +namespace vmime { +namespace utility { const bool stringUtils::isStringEqualNoCase @@ -119,4 +119,5 @@ const string::size_type stringUtils::countASCIIchars } +} // utility } // vmime diff --git a/tests/utility/stringUtilsTest.cpp b/tests/utility/stringUtilsTest.cpp index 76f9f36d..158eec22 100644 --- a/tests/utility/stringUtilsTest.cpp +++ b/tests/utility/stringUtilsTest.cpp @@ -33,75 +33,78 @@ namespace { class stringUtilsTest : public suite { + typedef vmime::utility::stringUtils stringUtils; + + void testIsStringEqualNoCase1() { - assert_eq("1", true, vmime::stringUtils::isStringEqualNoCase(vmime::string("foo"), "foo", 3)); - assert_eq("2", true, vmime::stringUtils::isStringEqualNoCase(vmime::string("FOo"), "foo", 3)); + assert_eq("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), "foo", 3)); + assert_eq("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), "foo", 3)); - assert_eq("3", false, vmime::stringUtils::isStringEqualNoCase(vmime::string("foo"), "FOo", 3)); - assert_eq("4", false, vmime::stringUtils::isStringEqualNoCase(vmime::string("foo"), "bar", 3)); + assert_eq("3", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "FOo", 3)); + assert_eq("4", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "bar", 3)); } void testIsStringEqualNoCase2() { - assert_eq("1", true, vmime::stringUtils::isStringEqualNoCase(vmime::string("foo"), vmime::string("foo"))); - assert_eq("2", true, vmime::stringUtils::isStringEqualNoCase(vmime::string("FOo"), vmime::string("foo"))); - assert_eq("3", true, vmime::stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("FOo"))); + assert_eq("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), vmime::string("foo"))); + assert_eq("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), vmime::string("foo"))); + assert_eq("3", true, stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("FOo"))); } void testIsStringEqualNoCase3() { vmime::string str1("FooBar"); - assert_eq("1", true, vmime::stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "foobar", 6)); - assert_eq("2", false, vmime::stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "FooBar", 6)); - assert_eq("3", true, vmime::stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "fooBar", 3)); - assert_eq("4", false, vmime::stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "fooBar", 6)); + assert_eq("1", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "foobar", 6)); + assert_eq("2", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "FooBar", 6)); + assert_eq("3", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "fooBar", 3)); + assert_eq("4", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "fooBar", 6)); } void testToLower() { - assert_eq("1", "foo", vmime::stringUtils::toLower("FOO")); - assert_eq("2", "foo", vmime::stringUtils::toLower("foO")); - assert_eq("3", "foo", vmime::stringUtils::toLower("foo")); + assert_eq("1", "foo", stringUtils::toLower("FOO")); + assert_eq("2", "foo", stringUtils::toLower("foO")); + assert_eq("3", "foo", stringUtils::toLower("foo")); } void testTrim() { - assert_eq("1", "foo", vmime::stringUtils::trim(" foo")); - assert_eq("2", "foo", vmime::stringUtils::trim("\t\tfoo")); - assert_eq("3", "foo", vmime::stringUtils::trim(" \t \tfoo")); - assert_eq("4", "foo", vmime::stringUtils::trim(" \r\n\tfoo")); + assert_eq("1", "foo", stringUtils::trim(" foo")); + assert_eq("2", "foo", stringUtils::trim("\t\tfoo")); + assert_eq("3", "foo", stringUtils::trim(" \t \tfoo")); + assert_eq("4", "foo", stringUtils::trim(" \r\n\tfoo")); - assert_eq("5", "foo", vmime::stringUtils::trim("foo ")); - assert_eq("6", "foo", vmime::stringUtils::trim("foo\t\t")); - assert_eq("7", "foo", vmime::stringUtils::trim("foo \t \t")); - assert_eq("8", "foo", vmime::stringUtils::trim("foo \r\n\t")); + assert_eq("5", "foo", stringUtils::trim("foo ")); + assert_eq("6", "foo", stringUtils::trim("foo\t\t")); + assert_eq("7", "foo", stringUtils::trim("foo \t \t")); + assert_eq("8", "foo", stringUtils::trim("foo \r\n\t")); - assert_eq( "9", "foo", vmime::stringUtils::trim("foo ")); - assert_eq("10", "foo", vmime::stringUtils::trim(" foo ")); - assert_eq("11", "foo", vmime::stringUtils::trim(" foo\t\t")); - assert_eq("12", "foo", vmime::stringUtils::trim("\tfoo \r \t")); - assert_eq("13", "foo", vmime::stringUtils::trim("\r \tfoo \n\t")); + assert_eq( "9", "foo", stringUtils::trim("foo ")); + assert_eq("10", "foo", stringUtils::trim(" foo ")); + assert_eq("11", "foo", stringUtils::trim(" foo\t\t")); + assert_eq("12", "foo", stringUtils::trim("\tfoo \r \t")); + assert_eq("13", "foo", stringUtils::trim("\r \tfoo \n\t")); } void testCountASCIIChars() { vmime::string str1("foo"); assert_eq("1", static_cast (3), - vmime::stringUtils::countASCIIchars(str1.begin(), str1.end())); + stringUtils::countASCIIchars(str1.begin(), str1.end())); vmime::string str2("f=?oo"); assert_eq("2", static_cast (3 + 1), - vmime::stringUtils::countASCIIchars(str2.begin(), str2.end())); + stringUtils::countASCIIchars(str2.begin(), str2.end())); vmime::string str3("foo\x7f"); assert_eq("3", static_cast (4), - vmime::stringUtils::countASCIIchars(str3.begin(), str3.end())); + stringUtils::countASCIIchars(str3.begin(), str3.end())); vmime::string str4("foo\x80"); assert_eq("4", static_cast (3), - vmime::stringUtils::countASCIIchars(str4.begin(), str4.end())); + stringUtils::countASCIIchars(str4.begin(), str4.end())); } public: diff --git a/vmime/encoderFactory.hpp b/vmime/encoderFactory.hpp index 7efbed70..a0f9614e 100644 --- a/vmime/encoderFactory.hpp +++ b/vmime/encoderFactory.hpp @@ -100,7 +100,7 @@ public: template void registerName(const string& name) { - m_encoders.push_back(new registeredEncoderImpl (stringUtils::toLower(name))); + m_encoders.push_back(new registeredEncoderImpl (utility::stringUtils::toLower(name))); } /** Create a new encoder instance from an encoding name. diff --git a/vmime/headerFieldFactory.hpp b/vmime/headerFieldFactory.hpp index a3bb4d26..b3e1f8bd 100644 --- a/vmime/headerFieldFactory.hpp +++ b/vmime/headerFieldFactory.hpp @@ -64,7 +64,8 @@ public: template void registerName(const string& name) { - m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), ®isterer::creator)); + m_nameMap.insert(NameMap::value_type + (utility::stringUtils::toLower(name), ®isterer::creator)); } headerField* create(const string& name, const string& body = NULL_STRING); diff --git a/vmime/messaging/IMAPParser.hpp b/vmime/messaging/IMAPParser.hpp index 9755d4d2..d8ce230c 100644 --- a/vmime/messaging/IMAPParser.hpp +++ b/vmime/messaging/IMAPParser.hpp @@ -1231,7 +1231,7 @@ public: else { atom* at = parser.get (line, &pos); - const string name = stringUtils::toLower(at->value()); + const string name = utility::stringUtils::toLower(at->value()); delete (at); if (name == "answered") @@ -1403,7 +1403,7 @@ public: parser.check >(line, &pos); atom* at = parser.get (line, &pos); - const string name = stringUtils::toLower(at->value()); + const string name = utility::stringUtils::toLower(at->value()); delete (at); if (name == "marked") @@ -1802,7 +1802,7 @@ public: DEBUG_ENTER_COMPONENT("auth_type"); atom* at = parser.get (line, currentPos); - m_name = stringUtils::toLower(at->value()); + m_name = utility::stringUtils::toLower(at->value()); delete (at); if (m_name == "kerberos_v4") @@ -2124,7 +2124,7 @@ public: m_datetime.setDay(std::min(std::max(nd->value(), 1u), 31u)); m_datetime.setYear(ny->value()); - const string month(stringUtils::toLower(amo->value())); + const string month(utility::stringUtils::toLower(amo->value())); int mon = vmime::datetime::JANUARY; if (month.length() >= 3) diff --git a/vmime/messaging/serviceFactory.hpp b/vmime/messaging/serviceFactory.hpp index c1271bb9..aa8a58c4 100644 --- a/vmime/messaging/serviceFactory.hpp +++ b/vmime/messaging/serviceFactory.hpp @@ -122,7 +122,7 @@ public: template void registerServiceByProtocol(const string& protocol) { - const string name = stringUtils::toLower(protocol); + const string name = utility::stringUtils::toLower(protocol); m_services.push_back(new registeredServiceImpl (name)); } diff --git a/vmime/parameterFactory.hpp b/vmime/parameterFactory.hpp index 040426ad..4b192af5 100644 --- a/vmime/parameterFactory.hpp +++ b/vmime/parameterFactory.hpp @@ -64,7 +64,8 @@ public: template void registerName(const string& name) { - m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), ®isterer::creator)); + m_nameMap.insert(NameMap::value_type + (utility::stringUtils::toLower(name), ®isterer::creator)); } parameter* create(const string& name, const string& value = NULL_STRING); diff --git a/vmime/propertySet.hpp b/vmime/propertySet.hpp index 37f8635d..b9868f69 100644 --- a/vmime/propertySet.hpp +++ b/vmime/propertySet.hpp @@ -262,11 +262,11 @@ private: { public: - propFinder(const string& name) : m_name(stringUtils::toLower(name)) { } + propFinder(const string& name) : m_name(utility::stringUtils::toLower(name)) { } const bool operator()(property* const p) const { - return (stringUtils::toLower(p->getName()) == m_name); + return (utility::stringUtils::toLower(p->getName()) == m_name); } private: diff --git a/vmime/utility/datetimeUtils.hpp b/vmime/utility/datetimeUtils.hpp new file mode 100644 index 00000000..1a64bda5 --- /dev/null +++ b/vmime/utility/datetimeUtils.hpp @@ -0,0 +1,75 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#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 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 const 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 const int getDaysInMonth(const int year, const int month); + + /** Convert the specified local time and date to UT (GMT). + * + * @param date local date/time + * @return GMT date/time + */ + static const datetime localTimeToUniversalTime(const datetime& date); + + /** Convert the specified UT to local time and date. + * + * @param date GMT date/time + * @param zone local zone to convert to (see datetime::TimeZones enum) + * @return local time and date + */ + static const datetime universalTimeToLocalTime(const datetime& date, const int zone); +}; + + +} // utility +} // vmime + + +#endif // VMIME_DATETIMEUTILS_HPP_INCLUDED diff --git a/vmime/utility/stringUtils.hpp b/vmime/utility/stringUtils.hpp index d75765e8..07e6c33b 100644 --- a/vmime/utility/stringUtils.hpp +++ b/vmime/utility/stringUtils.hpp @@ -17,8 +17,8 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#ifndef VMIME_STRINGUTILS_HPP_INCLUDED -#define VMIME_STRINGUTILS_HPP_INCLUDED +#ifndef VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED +#define VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED #include "vmime/types.hpp" @@ -27,8 +27,8 @@ #include -namespace vmime -{ +namespace vmime { +namespace utility { /** Miscellaneous functions related to strings. @@ -125,7 +125,8 @@ public: }; +} // utility } // vmime -#endif // VMIME_STRINGUTILS_HPP_INCLUDED +#endif // VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED diff --git a/vmime/vmime.hpp b/vmime/vmime.hpp index 849b497e..90ae46be 100644 --- a/vmime/vmime.hpp +++ b/vmime/vmime.hpp @@ -71,6 +71,9 @@ // Property set #include "vmime/propertySet.hpp" +// Utilities +#include "vmime/utility/datetimeUtils.hpp" + // Messaging features #if VMIME_HAVE_MESSAGING_FEATURES #include "vmime/messaging/socket.hpp"