X-Git-Url: http://Server1/repobrowser/?p=xestiacalendar%2F.git;a=blobdiff_plain;f=source%2Fobjects%2Fcalendarobject%2FCalendarObject.cpp;h=76cb4e6b00a0481ebe3331f2f22f405e5356b8a0;hp=6210b49e9a7fb97f95e6d55fb8c7ecf5a834a392;hb=49789773e2797383c866dca470fb99e80cb49e41;hpb=047cf7350cd7ae8e6f53263f68226af4a2c3681d diff --git a/source/objects/calendarobject/CalendarObject.cpp b/source/objects/calendarobject/CalendarObject.cpp index 6210b49..76cb4e6 100644 --- a/source/objects/calendarobject/CalendarObject.cpp +++ b/source/objects/calendarobject/CalendarObject.cpp @@ -1,250 +1,385 @@ +// 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){ +CalendarObjectLoadResult CalendarObject::LoadFile(std::string loadFilename){ // Check if the file exists and return // CALENDAROBJECTLOAD_CANNOTOPEN if not. - if (!FileExists(LoadFilename)){ + ifstream fileStream; + string receivedStringData = ""; + +#ifndef WIN32 + + if (!FileExists(loadFilename)) { return CALENDAROBJECTLOAD_MISSING; } - - ifstream FileStream; - string ReceivedStringData = ""; - - FileStream.open(LoadFilename, ifstream::in); - - if (FileStream.rdstate() & ifstream::failbit){ + + fileStream.open(loadFilename, ifstream::in); + +#else + + wstring loadFilename_utf16; + + int len = MultiByteToWideChar(CP_UTF8, 0, &loadFilename[0], (int)loadFilename.size(), NULL, 0); + + if (len > 0) + { + loadFilename_utf16.resize(len); + MultiByteToWideChar(CP_UTF8, 0, &loadFilename[0], (int)loadFilename.size(), &loadFilename_utf16[0], len); + } + + if (!FileExists(loadFilename_utf16)) { + return CALENDAROBJECTLOAD_MISSING; + } + + fileStream.open(loadFilename_utf16, ifstream::in); + +#endif + + if (fileStream.rdstate() & ifstream::failbit){ return CALENDAROBJECTLOAD_CANNOTOPEN; } - if (FileStream.rdstate() & ifstream::badbit){ + if (fileStream.rdstate() & ifstream::badbit){ return CALENDAROBJECTLOAD_CANNOTOPEN; } // Read the data into a string. - char *BufferRead = new char[256]; + char *bufferRead = new char[256]; - while (!FileStream.eof()){ + while (!fileStream.eof()){ - FileStream.getline(BufferRead, 256); - ReceivedStringData.append(BufferRead); - ReceivedStringData.append("\n"); + fileStream.getline(bufferRead, 256); + receivedStringData.append(bufferRead); + receivedStringData.append("\n"); } - delete[] BufferRead; + delete[] bufferRead; - CalendarObjectLoadResult StringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL; + CalendarObjectLoadResult stringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL; - StringProcResult = LoadString(&ReceivedStringData); + stringProcResult = LoadString(&receivedStringData); - return StringProcResult; + return stringProcResult; } -CalendarObjectLoadResult CalendarObject::LoadString(std::string *LoadStringData){ +CalendarObjectLoadResult CalendarObject::LoadString(std::string *loadStringData){ - bool NewLine = false; - bool SkipMode = false; - bool ColonFound = false; - char BufferChar = 0; - int StringDataSize = LoadStringData->size(); - int SeekCount = 0; - string PropertyName; - string PropertyValue; + 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){ + 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){ + 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; + newLine = false; - } else if (NewLine == true){ + } 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.insert(ObjectName.end(), PropertyName); - ObjectData.insert(ObjectData.end(), PropertyValue); + if (colonFound == true){ + objectName.push_back(propertyName); + objectData.push_back(propertyValue); } - ColonFound = false; - NewLine = false; - PropertyName.clear(); - PropertyValue.clear(); + colonFound = false; + newLine = false; + propertyName.clear(); + propertyValue.clear(); - BufferChar = (*LoadStringData)[SeekCount]; - PropertyName += BufferChar; + bufferChar = (*loadStringData)[seekCount]; + propertyName += bufferChar; - } else if ((*LoadStringData)[SeekCount] == '\n'){ + } else if ((*loadStringData)[seekCount] == '\n'){ // Character is the new line character so mark // the NewLine boolean as true. - NewLine = true; + newLine = true; - } else if ((*LoadStringData)[SeekCount] == ':'){ + } else if ((*loadStringData)[seekCount] == ':' && + quoteMode == false){ // Character is the colon. Set the colon // found boolen to true. - ColonFound = 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]; + bufferChar = (*loadStringData)[seekCount]; - if (ColonFound == false){ - PropertyName += BufferChar; + if (colonFound == false){ + propertyName += bufferChar; } else { - PropertyValue += BufferChar; + propertyValue += bufferChar; } } - SeekCount++; + 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){ + if (colonFound == true && + propertyName.size() > 0 && + propertyValue.size() > 0){ - ObjectName.insert(ObjectName.end(), PropertyName); - ObjectData.insert(ObjectData.end(), PropertyValue); + 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(); + CalendarObjectLoadResult stringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL; + CalendarObjectValidResult baseDataResult = ValidBaseObject(); + CalendarObjectValidResult eventDataResult = ValidObject(); - if (BaseDataResult != CALENDAROBJECTVALID_OK || - EventDataResult != CALENDAROBJECTVALID_OK){ + if (baseDataResult != CALENDAROBJECTVALID_OK || + eventDataResult != CALENDAROBJECTVALID_OK){ - StringProcResult = CALENDAROBJECTLOAD_INVALIDFORMAT; + stringProcResult = CALENDAROBJECTLOAD_INVALIDFORMAT; } else { - StringProcResult = CALENDAROBJECTLOAD_OK; + stringProcResult = CALENDAROBJECTLOAD_OK; } - return StringProcResult; + ProcessBaseData(); + ProcessData(); + + return stringProcResult; } CalendarObjectValidResult CalendarObject::ValidBaseObject(){ - bool ValidBegin = false; - bool ValidVersion = false; - bool ValidEnd = false; - int SeekCount = 0; + 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++){ + for (vector::iterator iter = objectName.begin(); + iter != objectName.end(); iter++){ - if (ObjectName[SeekCount] == "BEGIN" && - ObjectData[SeekCount] == "VCALENDAR"){ + if (objectName[seekCount] == "BEGIN" && + objectData[seekCount] == "VCALENDAR"){ - if (ValidBegin == false){ - ValidBegin = true; + if (validBegin == false){ + validBegin = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } - if (ObjectName[SeekCount] == "END" && - ObjectData[SeekCount] == "VCALENDAR" && - ValidBegin == false){ + 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; + } - SeekCount++; + 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; + 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++){ + for (vector::iterator iter = objectName.begin(); + iter != objectName.end(); iter++){ - if (ObjectName[SeekCount] == "END" && - ObjectData[SeekCount] == "VCALENDAR"){ + if (objectName[seekCount] == "END" && + objectData[seekCount] == "VCALENDAR"){ - if (ValidEnd == false){ - ValidEnd = true; + if (validEnd == false){ + validEnd = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } - SeekCount++; + seekCount++; } - SeekCount = 0; + 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++){ + for (vector::iterator iter = objectName.begin(); + iter != objectName.end(); iter++){ - if (ObjectName[SeekCount] == "VERSION" && - ObjectData[SeekCount] == "2.0"){ + if (objectName[seekCount] == "VERSION" && + objectData[seekCount] == "2.0"){ - if (ValidVersion == false){ - ValidVersion = true; + if (validVersion == false){ + validVersion = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } - SeekCount++; + seekCount++; } - if (ValidBegin == true && - ValidEnd == true && - ValidVersion == true){ - + // 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)); + + } + + if (validBegin == true && + validEnd == true && + validVersion == true && + validAlarmBegin == false){ + return CALENDAROBJECTVALID_OK; } else { @@ -253,4 +388,48 @@ CalendarObjectValidResult CalendarObject::ValidBaseObject(){ } +} + +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