X-Git-Url: http://Server1/repobrowser/?a=blobdiff_plain;f=source%2Fobjects%2Fcalendarobject%2FCalendarObject.cpp;h=6cfe78bca1f92833583efb58868a7b33b0e143b7;hb=1fe6e43892e5c572949a293a9e19704b5debadad;hp=00f13c86c4901f9a90dd9d7d14d0779524b9d5e5;hpb=e623dcc4464ff0ffc10a2484eec12fbb461a354e;p=xestiacalendar%2F.git diff --git a/source/objects/calendarobject/CalendarObject.cpp b/source/objects/calendarobject/CalendarObject.cpp index 00f13c8..6cfe78b 100644 --- a/source/objects/calendarobject/CalendarObject.cpp +++ b/source/objects/calendarobject/CalendarObject.cpp @@ -1,9 +1,413 @@ +// CalendarObject.cpp - CalendarObject class functions +// +// (c) 2016-2017 Xestia Software Development. +// +// This file is part of Xestia Calendar. +// +// Xestia Calendar 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, version 3 of the license. +// +// Xestia Calendar 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 Xestia Calendar. If not, see + #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 validAlarmBegin = false; + bool validVersion = false; + bool validEnd = false; + int seekCount = 0; + vector deleteLines; + vector alarmObjectName; + vector alarmObjectData; + + // 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; + + } else if (objectName[seekCount] == "END" && + objectData[seekCount] == "VALARM" && + validAlarmBegin == false){ + + return CALENDAROBJECTVALID_INVALIDFORMAT; + + } else if (objectName[seekCount] == "END" && + objectData[seekCount] == "VCALENDAR" && + validAlarmBegin == true){ + + return CALENDAROBJECTVALID_INVALIDFORMAT; + + } + + // Look for any VALARM sections. + + if (validAlarmBegin == true){ + + alarmObjectName.push_back(objectName[seekCount]); + alarmObjectData.push_back(objectData[seekCount]); + deleteLines.push_back(seekCount); + + } + + if (objectName[seekCount] == "END" && + objectData[seekCount] == "VALARM" && + validAlarmBegin == true){ + + eventAlarmName.push_back(alarmObjectName); + eventAlarmData.push_back(alarmObjectData); + + alarmObjectName.clear(); + alarmObjectData.clear(); + + validAlarmBegin = false; + + } + + if (objectName[seekCount] == "BEGIN" && + objectData[seekCount] == "VALARM" && + validBegin == true){ + + if (validAlarmBegin == false){ + validAlarmBegin = true; + } else { + return CALENDAROBJECTVALID_INVALIDFORMAT; + } + + alarmObjectName.push_back(objectName[seekCount]); + alarmObjectData.push_back(objectData[seekCount]); + deleteLines.push_back(seekCount); + + } + + 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++; + + } + + // Remove lines that aren't needed as they have + // been moved to the EventAlarm section. + + for (vector::reverse_iterator deliter = deleteLines.rbegin(); + deliter != deleteLines.rend(); deliter++){ + + objectName.erase(objectName.begin()+(*deliter)); + objectData.erase(objectData.begin()+(*deliter)); + + } -CalendarObjectLoadResult CalendarObject::LoadFile(){ - + if (validBegin == true && + validEnd == true && + validVersion == true && + validAlarmBegin == false){ + + return CALENDAROBJECTVALID_OK; + + } else { + + return CALENDAROBJECTVALID_INVALIDFORMAT; + + } + } -CalendarObjectLoadResult CalendarObject::LoadString(){ - +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; + + } + } \ No newline at end of file