#include "CalendarObject.h" #include "../../common/file.h" using namespace std; CalendarObjectLoadResult CalendarObject::LoadFile(std::string LoadFilename){ // Check if the file exists and return // CALENDAROBJECTLOAD_CANNOTOPEN if not. if (!FileExists(LoadFilename)){ return CALENDAROBJECTLOAD_MISSING; } ifstream FileStream; string ReceivedStringData = ""; FileStream.open(LoadFilename, ifstream::in); if (FileStream.rdstate() & ifstream::failbit){ return CALENDAROBJECTLOAD_CANNOTOPEN; } if (FileStream.rdstate() & ifstream::badbit){ return CALENDAROBJECTLOAD_CANNOTOPEN; } // Read the data into a string. char *BufferRead = new char[256]; while (!FileStream.eof()){ FileStream.getline(BufferRead, 256); ReceivedStringData.append(BufferRead); ReceivedStringData.append("\n"); } delete[] BufferRead; CalendarObjectLoadResult StringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL; StringProcResult = LoadString(&ReceivedStringData); return StringProcResult; } CalendarObjectLoadResult CalendarObject::LoadString(std::string *LoadStringData){ bool NewLine = false; bool SkipMode = false; bool ColonFound = false; bool QuoteMode = false; char BufferChar = 0; int StringDataSize = LoadStringData->size(); int SeekCount = 0; string PropertyName; string PropertyValue; while (SeekCount < StringDataSize){ // Check if character is blank or a tab and is the first character // on a new line. if (((*LoadStringData)[SeekCount] == ' ' || (*LoadStringData)[SeekCount] == '\t') && NewLine == true){ // Character is on a new line and it is a space or // tab. Ignore this character as it is not part // of the value. NewLine = false; } else if ((*LoadStringData)[SeekCount] == '\"'){ if (QuoteMode == false){ QuoteMode = true; } else { QuoteMode = false; } BufferChar = (*LoadStringData)[SeekCount]; if (ColonFound == false){ PropertyName += BufferChar; } else { PropertyValue += BufferChar; } } else if (NewLine == true){ // Character is on a new line but not a space or // tab so check if the colon has been found // and add the property name and value to // the lists. if (ColonFound == true){ ObjectName.push_back(PropertyName); ObjectData.push_back(PropertyValue); } ColonFound = false; NewLine = false; PropertyName.clear(); PropertyValue.clear(); BufferChar = (*LoadStringData)[SeekCount]; PropertyName += BufferChar; } else if ((*LoadStringData)[SeekCount] == '\n'){ // Character is the new line character so mark // the NewLine boolean as true. NewLine = true; } else if ((*LoadStringData)[SeekCount] == ':' && QuoteMode == false){ // Character is the colon. Set the colon // found boolen to true. BufferChar = (*LoadStringData)[SeekCount]; if (ColonFound == true){ PropertyValue += BufferChar; } else { ColonFound = true; } } else { // Character is not part of a new line and is not // the new line character itself. BufferChar = (*LoadStringData)[SeekCount]; if (ColonFound == false){ PropertyName += BufferChar; } else { PropertyValue += BufferChar; } } SeekCount++; } // Finish off processing any data that wasn't processed // when the end of the string was reached. if (ColonFound == true && PropertyName.size() > 0 && PropertyValue.size() > 0){ ObjectName.push_back(PropertyName); ObjectData.push_back(PropertyValue); } // Check that the object contains valid data. CalendarObjectLoadResult StringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL; CalendarObjectValidResult BaseDataResult = ValidBaseObject(); CalendarObjectValidResult EventDataResult = ValidObject(); if (BaseDataResult != CALENDAROBJECTVALID_OK || EventDataResult != CALENDAROBJECTVALID_OK){ StringProcResult = CALENDAROBJECTLOAD_INVALIDFORMAT; } else { StringProcResult = CALENDAROBJECTLOAD_OK; } ProcessBaseData(); ProcessData(); return StringProcResult; } CalendarObjectValidResult CalendarObject::ValidBaseObject(){ bool ValidBegin = false; bool ValidVersion = false; bool ValidEnd = false; int SeekCount = 0; // Check that the first line contains BEGIN:VCALENDAR // and it only appears once. for (vector::iterator iter = ObjectName.begin(); iter != ObjectName.end(); iter++){ if (ObjectName[SeekCount] == "BEGIN" && ObjectData[SeekCount] == "VCALENDAR"){ if (ValidBegin == false){ ValidBegin = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } if (ObjectName[SeekCount] == "END" && ObjectData[SeekCount] == "VCALENDAR" && ValidBegin == false){ return CALENDAROBJECTVALID_INVALIDFORMAT; } SeekCount++; } SeekCount = 0; // Check that the last line contains END:VCALENDAR // and it only appears once. for (vector::iterator iter = ObjectName.begin(); iter != ObjectName.end(); iter++){ if (ObjectName[SeekCount] == "END" && ObjectData[SeekCount] == "VCALENDAR"){ if (ValidEnd == false){ ValidEnd = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } SeekCount++; } SeekCount = 0; // Check that the VERSION value contains 2.0 and that // it only appears once. for (vector::iterator iter = ObjectName.begin(); iter != ObjectName.end(); iter++){ if (ObjectName[SeekCount] == "VERSION" && ObjectData[SeekCount] == "2.0"){ if (ValidVersion == false){ ValidVersion = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } SeekCount++; } if (ValidBegin == true && ValidEnd == true && ValidVersion == true){ return CALENDAROBJECTVALID_OK; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } void CalendarObject::ProcessBaseData(){ // Process the base object data. multimap DataReceived; // Get the method (METHOD). DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "METHOD"); if (DataReceived.begin() != DataReceived.end()){ try { MethodTokens = DataReceived.begin()->first.substr(7); } catch(const out_of_range &oor){ // Do nothing as there is no data. } MethodData = DataReceived.begin()->second; } // Get the calendar scale (CALSCALE). DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "CALSCALE"); if (DataReceived.begin() != DataReceived.end()){ try { CalendarScaleTokens = DataReceived.begin()->first.substr(9); } catch(const out_of_range &oor){ // Do nothing as there is no data. } CalendarScaleData = DataReceived.begin()->second; } }