Enhancement - T2 implementation

- Improved Att/Mod implementation.
- Implemented more T2 methods.
This commit is contained in:
Paul Beckingham 2009-06-03 22:58:24 -04:00
parent f295fdf78f
commit 25450b4a7c
4 changed files with 254 additions and 15 deletions

View file

@ -196,6 +196,12 @@ bool Att::evalMod (Att& other)
return false; return false;
} }
////////////////////////////////////////////////////////////////////////////////
bool Att::match (const Att& other)
{
return false;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// name : " value " // name : " value "
std::string Att::composeF4 () const std::string Att::composeF4 () const

View file

@ -44,6 +44,7 @@ public:
bool parse (Nibbler&); bool parse (Nibbler&);
bool validMod (const std::string&); bool validMod (const std::string&);
bool evalMod (Att&); bool evalMod (Att&);
bool match (const Att&);
std::string composeF4 () const; std::string composeF4 () const;
void addMod (const std::string&); void addMod (const std::string&);

View file

@ -60,7 +60,8 @@ T2& T2::operator= (const T2& other)
throw std::string ("unimplemented T2::operator="); throw std::string ("unimplemented T2::operator=");
if (this != &other) if (this != &other)
{ {
mId = other.mId; sequence = other.sequence;
subst = other.subst;
} }
return *this; return *this;
@ -73,8 +74,177 @@ T2::~T2 ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Support FF2, FF3. // Support FF2, FF3.
void T2::legacyParse (const std::string& input) void T2::legacyParse (const std::string& line)
{ {
switch (determineVersion (line))
{
// File format version 1, from 2006.11.27 - 2007.12.31
case 1:
throw std::string ("Task no longer supports file format 1, originally used "
"between 27 November 2006 and 31 December 2007.");
break;
// File format version 2, from 2008.1.1 - 2009.3.23
case 2:
/*
{
if (line.length () > 46) // ^.{36} . \[\] \[\] \n
{
mUUID = line.substr (0, 36);
mStatus = line[37] == '+' ? completed
: line[37] == 'X' ? deleted
: line[37] == 'r' ? recurring
: pending;
size_t openTagBracket = line.find ("[");
size_t closeTagBracket = line.find ("]", openTagBracket);
if (openTagBracket != std::string::npos &&
closeTagBracket != std::string::npos)
{
size_t openAttrBracket = line.find ("[", closeTagBracket);
size_t closeAttrBracket = line.find ("]", openAttrBracket);
if (openAttrBracket != std::string::npos &&
closeAttrBracket != std::string::npos)
{
std::string tags = line.substr (
openTagBracket + 1, closeTagBracket - openTagBracket - 1);
std::vector <std::string> rawTags;
split (mTags, tags, ' ');
std::string attributes = line.substr (
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
std::vector <std::string> pairs;
split (pairs, attributes, ' ');
for (size_t i = 0; i < pairs.size (); ++i)
{
std::vector <std::string> pair;
split (pair, pairs[i], ':');
if (pair.size () == 2)
mAttributes[pair[0]] = pair[1];
}
mDescription = line.substr (closeAttrBracket + 2, std::string::npos);
}
else
throw std::string ("Missing attribute brackets");
}
else
throw std::string ("Missing tag brackets");
}
else
throw std::string ("Line too short");
mAnnotations.clear ();
}
*/
break;
// File format version 3, from 2009.3.23
case 3:
/*
{
if (line.length () > 49) // ^.{36} . \[\] \[\] \[\] \n
{
mUUID = line.substr (0, 36);
mStatus = line[37] == '+' ? completed
: line[37] == 'X' ? deleted
: line[37] == 'r' ? recurring
: pending;
size_t openTagBracket = line.find ("[");
size_t closeTagBracket = line.find ("]", openTagBracket);
if (openTagBracket != std::string::npos &&
closeTagBracket != std::string::npos)
{
size_t openAttrBracket = line.find ("[", closeTagBracket);
size_t closeAttrBracket = line.find ("]", openAttrBracket);
if (openAttrBracket != std::string::npos &&
closeAttrBracket != std::string::npos)
{
size_t openAnnoBracket = line.find ("[", closeAttrBracket);
size_t closeAnnoBracket = line.find ("]", openAnnoBracket);
if (openAnnoBracket != std::string::npos &&
closeAnnoBracket != std::string::npos)
{
std::string tags = line.substr (
openTagBracket + 1, closeTagBracket - openTagBracket - 1);
std::vector <std::string> rawTags;
split (mTags, tags, ' ');
std::string attributes = line.substr (
openAttrBracket + 1, closeAttrBracket - openAttrBracket - 1);
std::vector <std::string> pairs;
split (pairs, attributes, ' ');
for (size_t i = 0; i < pairs.size (); ++i)
{
std::vector <std::string> pair;
split (pair, pairs[i], ':');
if (pair.size () == 2)
mAttributes[pair[0]] = pair[1];
}
// Extract and split the annotations, which are of the form:
// 1234:"..." 5678:"..."
std::string annotations = line.substr (
openAnnoBracket + 1, closeAnnoBracket - openAnnoBracket - 1);
pairs.clear ();
std::string::size_type start = 0;
std::string::size_type end = 0;
do
{
end = annotations.find ('"', start);
if (end != std::string::npos)
{
end = annotations.find ('"', end + 1);
if (start != std::string::npos &&
end != std::string::npos)
{
pairs.push_back (annotations.substr (start, end - start + 1));
start = end + 2;
}
}
}
while (start != std::string::npos &&
end != std::string::npos);
for (size_t i = 0; i < pairs.size (); ++i)
{
std::string pair = pairs[i];
std::string::size_type colon = pair.find (":");
if (colon != std::string::npos)
{
std::string name = pair.substr (0, colon);
std::string value = pair.substr (colon + 2, pair.length () - colon - 3);
mAnnotations[::atoi (name.c_str ())] = value;
}
}
mDescription = line.substr (closeAnnoBracket + 2, std::string::npos);
}
else
throw std::string ("Missing annotation brackets.");
}
else
throw std::string ("Missing attribute brackets.");
}
else
throw std::string ("Missing tag brackets.");
}
else
throw std::string ("Line too short.");
}
*/
break;
default:
throw std::string ("Unrecognized task file format.");
break;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -130,3 +300,74 @@ bool T2::validate () const
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int T2::determineVersion (const std::string& line)
{
// Version 2 looks like:
//
// uuid status [tags] [attributes] description\n
//
// Where uuid looks like:
//
// 27755d92-c5e9-4c21-bd8e-c3dd9e6d3cf7
//
// Scan for the hyphens in the uuid, the following space, and a valid status
// character.
if (line[8] == '-' &&
line[13] == '-' &&
line[18] == '-' &&
line[23] == '-' &&
line[36] == ' ' &&
(line[37] == '-' || line[37] == '+' || line[37] == 'X' || line[37] == 'r'))
{
// Version 3 looks like:
//
// uuid status [tags] [attributes] [annotations] description\n
//
// Scan for the number of [] pairs.
std::string::size_type tagAtts = line.find ("] [", 0);
std::string::size_type attsAnno = line.find ("] [", tagAtts + 1);
std::string::size_type annoDesc = line.find ("] ", attsAnno + 1);
if (tagAtts != std::string::npos &&
attsAnno != std::string::npos &&
annoDesc != std::string::npos)
return 3;
else
return 2;
}
// Version 1 looks like:
//
// [tags] [attributes] description\n
// X [tags] [attributes] description\n
//
// Scan for the first character being either the bracket or X.
else if ((line[0] == '[' && line[line.length () - 1] != ']') ||
line.find ("X [") == 0)
return 1;
// Version 4 looks like:
//
// [name:"value" ...]
//
// Scan for [, ] and :".
if (line[0] == '[' &&
line[line.length () - 1] == ']' &&
line.find (":\"") != std::string::npos)
return 4;
// Version 5?
//
// Fortunately, with the hindsight that will come with version 5, the
// identifying characteristics of 1, 2, 3 and 4 may be modified such that if 5
// has a UUID followed by a status, then there is still a way to differentiate
// between 2, 3, 4 and 5.
//
// The danger is that a version 3 binary reads and misinterprets a version 4
// file. This is why it is a good idea to rely on an explicit version
// declaration rather than chance positioning.
// Zero means 'no idea'.
return 0;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -51,19 +51,16 @@ public:
Subst subst; Subst subst;
// Series of helper functions. // Series of helper functions.
int getId () const { return mId; } int id () const { return sequence.size () ? sequence[0] : 0; }
void setId (int id) { mId = id; sequence.push_back (id); } void id (int anotherId) { sequence.push_back (anotherId); }
/* /*
std::vector <int> getAllIds () const { return mSequence; }
void addId (int id) { if (mId == 0) mId = id; mSequence.push_back (id); }
status getStatus () const { return mStatus; } status getStatus () const { return mStatus; }
void setStatus (status s) { mStatus = s; } void setStatus (status s) { mStatus = s; }
bool hasTag (const std::string&) const; bool hasTag (const std::string&) const;
void getRemoveTags (std::vector<std::string>&); // SPECIAL void getRemoveTags (std::vector<std::string>&); // SPECIAL
void addRemoveTag (const std::string&); // SPECIAL void addRemoveTag (const std::string&); // SPECIAL
int getTagCount () const; int getTagCount () const;
void getTags (std::vector<std::string>&) const; void getTags (std::vector<std::string>&) const;
void addTag (const std::string&); void addTag (const std::string&);
@ -79,15 +76,9 @@ public:
bool validate () const; bool validate () const;
private: private:
/*
int determineVersion (const std::string&); int determineVersion (const std::string&);
*/
private: private:
/*
status mStatus;
*/
int mId;
/* /*
std::vector<std::string> mTags; std::vector<std::string> mTags;
std::vector<std::string> mRemoveTags; std::vector<std::string> mRemoveTags;