- Implemented Nibbler::getDigit to retrieve a single numeric digit.
- Implemented Nibbler::getISODate.
This commit is contained in:
Paul Beckingham 2011-06-11 08:12:05 -04:00
parent ffcc2a49d8
commit a5feb6ef83
3 changed files with 115 additions and 1 deletions

View file

@ -28,6 +28,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <time.h>
#include <inttypes.h> #include <inttypes.h>
#include <Nibbler.h> #include <Nibbler.h>
#include <rx.h> #include <rx.h>
@ -264,6 +265,19 @@ bool Nibbler::getQuoted (
return false; return false;
} }
////////////////////////////////////////////////////////////////////////////////
bool Nibbler::getDigit (int& result)
{
if (mCursor < mLength &&
isdigit (mInput[mCursor]))
{
result = mInput[mCursor++] - '0';
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Nibbler::getInt (int& result) bool Nibbler::getInt (int& result)
{ {
@ -501,6 +515,78 @@ bool Nibbler::getUUID (std::string& result)
return false; return false;
} }
////////////////////////////////////////////////////////////////////////////////
// 19980119T070000Z = YYYYMMDDThhmmssZ
bool Nibbler::getDateISO (time_t& t)
{
std::string::size_type i = mCursor;
if (i < mLength &&
mLength - i >= 16)
{
if (isdigit (mInput[i + 0]) &&
isdigit (mInput[i + 1]) &&
isdigit (mInput[i + 2]) &&
isdigit (mInput[i + 3]) &&
isdigit (mInput[i + 4]) &&
isdigit (mInput[i + 5]) &&
isdigit (mInput[i + 6]) &&
isdigit (mInput[i + 7]) &&
mInput[i + 8] == 'T' &&
isdigit (mInput[i + 9]) &&
isdigit (mInput[i + 10]) &&
isdigit (mInput[i + 11]) &&
isdigit (mInput[i + 12]) &&
isdigit (mInput[i + 13]) &&
isdigit (mInput[i + 14]) &&
mInput[i + 15] == 'Z')
{
mCursor += 16;
int year = (mInput[i + 0] - '0') * 1000
+ (mInput[i + 1] - '0') * 100
+ (mInput[i + 2] - '0') * 10
+ (mInput[i + 3] - '0');
int month = (mInput[i + 4] - '0') * 10
+ (mInput[i + 5] - '0');
int day = (mInput[i + 6] - '0') * 10
+ (mInput[i + 7] - '0');
int hour = (mInput[i + 9] - '0') * 10
+ (mInput[i + 10] - '0');
int minute = (mInput[i + 11] - '0') * 10
+ (mInput[i + 12] - '0');
int second = (mInput[i + 13] - '0') * 10
+ (mInput[i + 14] - '0');
// Convert to epoch.
struct tm tms = {0};
tms.tm_isdst = -1; // Requests that mktime determine summer time effect.
tms.tm_mday = day;
tms.tm_mon = month - 1;
tms.tm_year = year - 1900;
tms.tm_hour = hour;
tms.tm_min = minute;
tms.tm_sec = second;
t = timegm (&tms);
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool Nibbler::getDate (const std::string& format, time_t& t)
{
return false;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Nibbler::skipN (const int quantity /* = 1 */) bool Nibbler::skipN (const int quantity /* = 1 */)
{ {

View file

@ -53,6 +53,7 @@ public:
*/ */
bool getQuoted (char, std::string&, bool quote = false); bool getQuoted (char, std::string&, bool quote = false);
bool getDigit (int&);
bool getInt (int&); bool getInt (int&);
bool getHex (int&); bool getHex (int&);
bool getUnsignedInt (int&); bool getUnsignedInt (int&);
@ -60,6 +61,8 @@ public:
bool getLiteral (const std::string&); bool getLiteral (const std::string&);
bool getRx (const std::string&, std::string&); bool getRx (const std::string&, std::string&);
bool getUUID (std::string&); bool getUUID (std::string&);
bool getDateISO (time_t&);
bool getDate (const std::string&, time_t&);
bool skipN (const int quantity = 1); bool skipN (const int quantity = 1);
bool skip (char); bool skip (char);

View file

@ -33,7 +33,7 @@ Context context;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
UnitTest t (171); UnitTest t (185);
try try
{ {
@ -41,6 +41,7 @@ int main (int argc, char** argv)
std::string s; std::string s;
int i; int i;
double d; double d;
time_t ti;
// Make sure the nibbler behaves itself with trivial input. // Make sure the nibbler behaves itself with trivial input.
t.diag ("Test all nibbler calls given empty input"); t.diag ("Test all nibbler calls given empty input");
@ -53,11 +54,14 @@ int main (int argc, char** argv)
t.notok (n.skipAll ('x'), "trivial: skipAll"); t.notok (n.skipAll ('x'), "trivial: skipAll");
t.notok (n.skipAllOneOf ("abc"), "trivial: skipAllOneOf"); t.notok (n.skipAllOneOf ("abc"), "trivial: skipAllOneOf");
t.notok (n.getQuoted ('"', s), "trivial: getQuoted"); t.notok (n.getQuoted ('"', s), "trivial: getQuoted");
t.notok (n.getDigit (i), "trivial: getDigit");
t.notok (n.getInt (i), "trivial: getInt"); t.notok (n.getInt (i), "trivial: getInt");
t.notok (n.getHex (i), "trivial: getHex"); t.notok (n.getHex (i), "trivial: getHex");
t.notok (n.getUnsignedInt (i), "trivial: getUnsignedInt"); t.notok (n.getUnsignedInt (i), "trivial: getUnsignedInt");
t.notok (n.getUntilEOL (s), "trivial: getUntilEOL"); t.notok (n.getUntilEOL (s), "trivial: getUntilEOL");
t.notok (n.getUntilEOS (s), "trivial: getUntilEOS"); t.notok (n.getUntilEOS (s), "trivial: getUntilEOS");
t.notok (n.getDateISO (ti), "trivial: getDateISO");
t.notok (n.getDate ("YYYYMMDD", ti), "trivial: getDate");
t.ok (n.depleted (), "trivial: depleted"); t.ok (n.depleted (), "trivial: depleted");
// bool getUntil (char, std::string&); // bool getUntil (char, std::string&);
@ -209,6 +213,15 @@ int main (int argc, char** argv)
t.ok (n.getQuoted ('"', s, true), "\"one\\\"two\" : getQuoted ('\"', true, true) -> true"); // 93 t.ok (n.getQuoted ('"', s, true), "\"one\\\"two\" : getQuoted ('\"', true, true) -> true"); // 93
t.is (s, "\"one\"two\"", "getQuoted ('\"', true) -> \"one\"two\""); // 94 t.is (s, "\"one\"two\"", "getQuoted ('\"', true) -> \"one\"two\""); // 94
// bool getDigit (int&);
t.diag ("Nibbler::getDigit");
n = Nibbler ("12x");
t.ok (n.getDigit (i), " '12x' : getdigit () -> true");
t.is (i, 1, " '12x' : getdigit () -> 1");
t.ok (n.getDigit (i), " '2x' : getdigit () -> true");
t.is (i, 2, " '2x' : getdigit () -> 2");
t.notok (n.getDigit (i), " 'x' : getdigit () -> false");
// bool getInt (int&); // bool getInt (int&);
t.diag ("Nibbler::getInt"); t.diag ("Nibbler::getInt");
n = Nibbler ("123 -4"); n = Nibbler ("123 -4");
@ -286,6 +299,18 @@ int main (int argc, char** argv)
t.is (s, "a0b1c2d3-e4f5-A6B7-C8D9-E0F1a2b3c4d5", "uuid 2 -> correct"); t.is (s, "a0b1c2d3-e4f5-A6B7-C8D9-E0F1a2b3c4d5", "uuid 2 -> correct");
t.ok (n.depleted (), "depleted"); t.ok (n.depleted (), "depleted");
// bool getDateISO (time_t&);
t.diag ("Nibbler::getDateISO");
n = Nibbler ("19980119T070000Z");
t.ok (n.getDateISO (ti), "'19980119T070000Z': getDateISO () -> true");
t.is (ti, 885193200, "'19980119T070000Z': getDateISO () -> 885193200");
t.ok (n.depleted (), "depleted");
n = Nibbler ("20090213T233130Z");
t.ok (n.getDateISO (ti), "'20090213T233130Z': getDateISO () -> true");
t.is (ti, 1234567890, "'20090213T233130Z': getDateISO () -> 1234567890");
t.ok (n.depleted (), "depleted");
// bool getUntilEOL (std::string&); // bool getUntilEOL (std::string&);
t.diag ("Nibbler::getUntilEOL"); t.diag ("Nibbler::getUntilEOL");
n = Nibbler ("one\ntwo"); n = Nibbler ("one\ntwo");