From 69b18308d907cec874a9e124ea6d43b36b9e83fa Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 7 Sep 2008 04:19:11 +0000 Subject: [PATCH] 2008-09-07 Tatsuhiro Tsujikawa Implmented the functions to parse date. * src/TimeA2.cc * src/TimeA2.h * test/TimeTest.cc --- ChangeLog | 7 ++++++ src/TimeA2.cc | 56 +++++++++++++++++++++++++++++++++++++++++ src/TimeA2.h | 20 +++++++++++++++ test/Makefile.am | 3 ++- test/Makefile.in | 9 ++++--- test/TimeTest.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 test/TimeTest.cc diff --git a/ChangeLog b/ChangeLog index 7b7f6ef6..b1277f57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-09-07 Tatsuhiro Tsujikawa + + Implmented the functions to parse date. + * src/TimeA2.cc + * src/TimeA2.h + * test/TimeTest.cc + 2008-09-05 Tatsuhiro Tsujikawa Added "Firefox3 Cookie" feature to FeatureConfig diff --git a/src/TimeA2.cc b/src/TimeA2.cc index 985e1706..c837d861 100644 --- a/src/TimeA2.cc +++ b/src/TimeA2.cc @@ -35,6 +35,8 @@ #include "TimeA2.h" #include "Util.h" +#include "array_fun.h" +#include namespace aria2 { @@ -136,4 +138,58 @@ void Time::setTimeInSec(time_t sec) { tv.tv_usec = 0; } +bool Time::good() const +{ + return tv.tv_sec >= 0; +} + +Time Time::parse(const std::string& datetime, const std::string& format) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + char* r = strptime(datetime.c_str(), format.c_str(), &tm); + if(r != datetime.c_str()+datetime.size()) { + return Time(-1); + } + time_t thetime = timegm(&tm); + if(thetime == -1) { + if(tm.tm_year >= 2038-1900) { + thetime = INT32_MAX; + } + } + return Time(thetime); +} + +Time Time::parseRFC1123(const std::string& datetime) +{ + return parse(datetime, "%a, %d %b %Y %H:%M:%S GMT"); +} + +Time Time::parseRFC850(const std::string& datetime) +{ + return parse(datetime, "%a, %d-%b-%y %H:%M:%S GMT"); +} + +Time Time::parseRFC850Ext(const std::string& datetime) +{ + return parse(datetime, "%a, %d-%b-%Y %H:%M:%S GMT"); +} + +Time Time::parseHTTPDate(const std::string& datetime) +{ + Time (*funcs[])(const std::string&) = { + &parseRFC1123, + &parseRFC850Ext, + &parseRFC850, + }; + for(Time (**funcsp)(const std::string&) = &funcs[0]; + funcsp != &funcs[arrayLength(funcs)]; ++funcsp) { + Time t = (*funcsp)(datetime); + if(t.good()) { + return t; + } + } + return Time(-1); +} + } // namespace aria2 diff --git a/src/TimeA2.h b/src/TimeA2.h index 440e4b3a..e85d6b44 100644 --- a/src/TimeA2.h +++ b/src/TimeA2.h @@ -38,6 +38,7 @@ #include "common.h" #include "a2time.h" #include +#include namespace aria2 { @@ -85,6 +86,25 @@ public: void setTimeInSec(time_t sec); bool isNewer(const Time& time) const; + + bool good() const; + + // Currently timezone is assumed as GMT. + static Time parse(const std::string& datetime, const std::string& format); + + // Currently timezone is assumed to GMT. + static Time parseRFC1123(const std::string& datetime); + + // Currently timezone is assumed to GMT. + static Time parseRFC850(const std::string& datetime); + + // Currently timezone is assumed to GMT. + // Basically the format is RFC850, but year part is 4digit, eg 2008 + static Time parseRFC850Ext(const std::string& datetime); + + // Try parseRFC1123, parseRFC850Ex, parseRFC850 in that order and returns + // the first "good" Time object returned by these functions. + static Time parseHTTPDate(const std::string& datetime); }; } // namespace aria2 diff --git a/test/Makefile.am b/test/Makefile.am index e779f551..84b66d4c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -60,7 +60,8 @@ aria2c_SOURCES = AllTest.cc\ NsCookieParserTest.cc\ DirectDiskAdaptorTest.cc\ CookieTest.cc\ - CookieStorageTest.cc + CookieStorageTest.cc\ + TimeTest.cc if HAVE_LIBZ aria2c_SOURCES += GZipDecoderTest.cc diff --git a/test/Makefile.in b/test/Makefile.in index 391636ac..15f2d9bf 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -194,7 +194,7 @@ am__aria2c_SOURCES_DIST = AllTest.cc TestUtil.cc TestUtil.h \ ServerStatURISelectorTest.cc InOrderURISelectorTest.cc \ ServerStatTest.cc NsCookieParserTest.cc \ DirectDiskAdaptorTest.cc CookieTest.cc CookieStorageTest.cc \ - GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \ + TimeTest.cc GZipDecoderTest.cc Sqlite3MozCookieParserTest.cc \ MessageDigestHelperTest.cc \ IteratableChunkChecksumValidatorTest.cc \ IteratableChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \ @@ -366,8 +366,8 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) TestUtil.$(OBJEXT) \ InOrderURISelectorTest.$(OBJEXT) ServerStatTest.$(OBJEXT) \ NsCookieParserTest.$(OBJEXT) DirectDiskAdaptorTest.$(OBJEXT) \ CookieTest.$(OBJEXT) CookieStorageTest.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) + TimeTest.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) aria2c_OBJECTS = $(am_aria2c_OBJECTS) am__DEPENDENCIES_1 = aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1) @@ -589,7 +589,7 @@ aria2c_SOURCES = AllTest.cc TestUtil.cc TestUtil.h SocketCoreTest.cc \ ServerStatURISelectorTest.cc InOrderURISelectorTest.cc \ ServerStatTest.cc NsCookieParserTest.cc \ DirectDiskAdaptorTest.cc CookieTest.cc CookieStorageTest.cc \ - $(am__append_1) $(am__append_2) $(am__append_3) \ + TimeTest.cc $(am__append_1) $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 @@ -816,6 +816,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TaggedItemTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestUtil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UTPexExtensionMessageTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UriListParserTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@ diff --git a/test/TimeTest.cc b/test/TimeTest.cc new file mode 100644 index 00000000..4bfa1146 --- /dev/null +++ b/test/TimeTest.cc @@ -0,0 +1,65 @@ +#include "TimeA2.h" +#include "Exception.h" +#include "Util.h" +#include +#include + +namespace aria2 { + +class TimeTest:public CppUnit::TestFixture { + + CPPUNIT_TEST_SUITE(TimeTest); + CPPUNIT_TEST(testParseRFC1123); + CPPUNIT_TEST(testParseRFC850); + CPPUNIT_TEST(testParseRFC850Ext); + CPPUNIT_TEST(testParseHTTPDate); + CPPUNIT_TEST_SUITE_END(); +public: + void setUp() {} + + void tearDown() {} + + void testParseRFC1123(); + void testParseRFC850(); + void testParseRFC850Ext(); + void testParseHTTPDate(); +}; + + +CPPUNIT_TEST_SUITE_REGISTRATION(TimeTest); + +void TimeTest::testParseRFC1123() +{ + Time t1 = Time::parseRFC1123("Sat, 06 Sep 2008 15:26:33 GMT"); + CPPUNIT_ASSERT_EQUAL((time_t)1220714793, t1.getTime()); +} + +void TimeTest::testParseRFC850() +{ + Time t1 = Time::parseRFC850("Saturday, 06-Sep-08 15:26:33 GMT"); + CPPUNIT_ASSERT_EQUAL((time_t)1220714793, t1.getTime()); +} + +void TimeTest::testParseRFC850Ext() +{ + Time t1 = Time::parseRFC850Ext("Saturday, 06-Sep-2008 15:26:33 GMT"); + CPPUNIT_ASSERT_EQUAL((time_t)1220714793, t1.getTime()); +} + +void TimeTest::testParseHTTPDate() +{ + CPPUNIT_ASSERT_EQUAL((time_t)1220714793, + Time::parseHTTPDate + ("Sat, 06 Sep 2008 15:26:33 GMT").getTime()); + CPPUNIT_ASSERT_EQUAL((time_t)1220714793, + Time::parseHTTPDate + ("Sat, 06-Sep-2008 15:26:33 GMT").getTime()); + CPPUNIT_ASSERT_EQUAL((time_t)1220714793, + Time::parseHTTPDate + ("Sat, 06-Sep-08 15:26:33 GMT").getTime()); + CPPUNIT_ASSERT_EQUAL((time_t)-1, + Time::parseHTTPDate + ("Sat, 2008-09-06 15:26:33 GMT").getTime()); +} + +} // namespace aria2