aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--SConstruct1
-rw-r--r--src/charset.cpp2
-rw-r--r--src/contentDisposition.cpp9
-rw-r--r--src/encoderFactory.cpp2
-rw-r--r--src/encoding.cpp9
-rw-r--r--src/fileAttachment.cpp2
-rw-r--r--src/header.cpp16
-rw-r--r--src/headerFieldFactory.cpp2
-rw-r--r--src/mediaType.cpp17
-rw-r--r--src/messaging/maildirStore.cpp2
-rw-r--r--src/messaging/serviceFactory.cpp2
-rw-r--r--src/messaging/url.cpp4
-rw-r--r--src/parameterFactory.cpp2
-rw-r--r--src/parameterizedHeaderField.cpp12
-rw-r--r--src/propertySet.cpp2
-rw-r--r--src/relay.cpp12
-rw-r--r--src/text.cpp2
-rw-r--r--src/utility/datetimeUtils.cpp221
-rw-r--r--src/utility/stringUtils.cpp5
-rw-r--r--tests/utility/stringUtilsTest.cpp69
-rw-r--r--vmime/encoderFactory.hpp2
-rw-r--r--vmime/headerFieldFactory.hpp3
-rw-r--r--vmime/messaging/IMAPParser.hpp8
-rw-r--r--vmime/messaging/serviceFactory.hpp2
-rw-r--r--vmime/parameterFactory.hpp3
-rw-r--r--vmime/propertySet.hpp4
-rw-r--r--vmime/utility/datetimeUtils.hpp75
-rw-r--r--vmime/utility/stringUtils.hpp11
-rw-r--r--vmime/vmime.hpp3
30 files changed, 412 insertions, 96 deletions
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 <[email protected]>
* 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 <registeredEncoder*>::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 <headerField*>::const_iterator pos = m_fields.begin();
const std::vector <headerField*>::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 <headerField*>::const_iterator pos = m_fields.begin();
const std::vector <headerField*>::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 <headerField*> header::findAllFields(const string& fieldName)
{
- const string name = stringUtils::toLower(fieldName);
+ const string name = utility::stringUtils::toLower(fieldName);
std::vector <headerField*> result;
@@ -346,7 +346,7 @@ std::vector <headerField*> 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 <headerField*> 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 <headerField*>::const_iterator pos = m_fields.begin();
const std::vector <headerField*>::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 <registeredService*>::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 <parameter*>::const_iterator pos = m_params.begin();
const std::vector <parameter*>::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 <parameter*>::const_iterator pos = m_params.begin();
const std::vector <parameter*>::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 <parameter*>::const_iterator pos = m_params.begin();
const std::vector <parameter*>::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 <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 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("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( "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("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", 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", 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 <vmime::string::size_type>(3),
- vmime::stringUtils::countASCIIchars(str1.begin(), str1.end()));
+ stringUtils::countASCIIchars(str1.begin(), str1.end()));
vmime::string str2("f=?oo");
assert_eq("2", static_cast <vmime::string::size_type>(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 <vmime::string::size_type>(4),
- vmime::stringUtils::countASCIIchars(str3.begin(), str3.end()));
+ stringUtils::countASCIIchars(str3.begin(), str3.end()));
vmime::string str4("foo\x80");
assert_eq("4", static_cast <vmime::string::size_type>(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 <class E>
void registerName(const string& name)
{
- m_encoders.push_back(new registeredEncoderImpl <E>(stringUtils::toLower(name)));
+ m_encoders.push_back(new registeredEncoderImpl <E>(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 <class T>
void registerName(const string& name)
{
- m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), &registerer<T>::creator));
+ m_nameMap.insert(NameMap::value_type
+ (utility::stringUtils::toLower(name), &registerer<T>::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 <atom>(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 <one_char <'\\'> >(line, &pos);
atom* at = parser.get <atom>(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 <atom>(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 <class S>
void registerServiceByProtocol(const string& protocol)
{
- const string name = stringUtils::toLower(protocol);
+ const string name = utility::stringUtils::toLower(protocol);
m_services.push_back(new registeredServiceImpl <S>(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 <class T>
void registerName(const string& name)
{
- m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), &registerer<T>::creator));
+ m_nameMap.insert(NameMap::value_type
+ (utility::stringUtils::toLower(name), &registerer<T>::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 <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 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 <sstream>
-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"