Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Updated/Added copyright header and licensing to all source files
[xestiacalendar/.git] / source / objects / calendarobject / CalendarObject.cpp
index 00f13c8..5a15e1d 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>
+
 #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<int> DeleteLines;
+       vector<string> AlarmObjectName;
+       vector<string> AlarmObjectData;
+       
+       // Check that the first line contains BEGIN:VCALENDAR
+       // and it only appears once.
+       
+       for (vector<string>::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<string>::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<string>::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<int>::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<string,string> 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
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy