X-Git-Url: http://Server1/repobrowser/?a=blobdiff_plain;f=source%2Fobjects%2Fcalendarobject%2FCalendarObject.cpp;h=5a15e1d593c58c1530c75a28e521b2f9a1d1bbde;hb=cba151c4b833a26c63984769f921bab5e755decd;hp=00f13c86c4901f9a90dd9d7d14d0779524b9d5e5;hpb=e623dcc4464ff0ffc10a2484eec12fbb461a354e;p=xestiacalendar%2F.git diff --git a/source/objects/calendarobject/CalendarObject.cpp b/source/objects/calendarobject/CalendarObject.cpp index 00f13c8..5a15e1d 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