// CalendarFreeBusy.cpp - CalendarFreeBusy 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 "CalendarFreeBusy.h" using namespace std; CalendarObjectValidResult CalendarFreeBusyObject::ValidObject(){ bool validBegin = false; bool validEnd = false; bool validDateTimeStamp = false; bool validUniqueID = false; bool validDateTimeStart = false; int seekCount = 0; string propertyName; // Look for BEGIN:VFREEBUSY. for (vector::iterator iter = objectName.begin(); iter != objectName.end(); iter++){ if (objectName[seekCount] == "BEGIN" && objectData[seekCount] == "VFREEBUSY"){ if (validBegin == false){ validBegin = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } if (objectName[seekCount] == "END" && objectData[seekCount] == "VFREEBUSY" && validBegin == false){ return CALENDAROBJECTVALID_INVALIDFORMAT; } seekCount++; } seekCount = 0; // Look for DTSTAMP. for (vector::iterator iter = objectName.begin(); iter != objectName.end(); iter++){ try{ propertyName = objectName[seekCount].substr(0,7); } catch(const out_of_range& oor){ continue; } if (propertyName == "DTSTAMP"){ if (validDateTimeStamp == false){ validDateTimeStamp = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } seekCount++; } seekCount = 0; // Look for UID. for (vector::iterator iter = objectName.begin(); iter != objectName.end(); iter++){ try{ PropertyName = objectName[seekCount].substr(0,3); } catch(const out_of_range& oor){ continue; } if (propertyName == "UID"){ if (validUniqueID == false){ validUniqueID = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } seekCount++; } seekCount = 0; // Look for END:VFREEBUSY. for (vector::iterator iter = objectName.begin(); iter != objectName.end(); iter++){ if (objectName[seekCount] == "END" && objectData[seekCount] == "VFREEBUSY"){ if (validEnd == false){ validEnd = true; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } seekCount++; } // Check if the VEVENT is valid. if (validBegin == true && validEnd == true && validDateTimeStamp == true && validUniqueID == true){ return CALENDAROBJECTVALID_OK; } else { return CALENDAROBJECTVALID_INVALIDFORMAT; } } void CalendarFreeBusyObject::ProcessData(){ // Process the data. multimap dataReceived; map propertyData; string *propertyNameData = nullptr; int objectSeekCount = 0; // Get the Date Time Stamp (DTSTAMP). dataReceived = ProcessTextVectors(&objectName, &objectData, false, "DTSTAMP"); // Process the data from DTSTAMP. if (dataReceived.begin() != dataReceived.end()){ try { dateTimeStampTokens = dataReceived.begin()->first.substr(8); } catch(const out_of_range &oor){ // Do nothing as there is no data. } dateTimeStampData = dataReceived.begin()->second; } // Get the Unique ID (UID). dataReceived = ProcessTextVectors(&objectName, &objectData, false, "UID"); // Process the data from UID. if (dataReceived.begin() != dataReceived.end()){ try { uniqueIDTokens = dataReceived.begin()->first.substr(4); } catch(const out_of_range &oor){ // Do nothing as there is no data. } uniqueID = dataReceived.begin()->second; } // Process the data from CONTACT. dataReceived = ProcessTextVectors(&objectName, &objectData, false, "CONTACT"); objectSeekCount = 0; for(multimap::iterator iter = dataReceived.begin(); iter != dataReceived.end(); ++iter){ contactListTokens.push_back(""); contactListAltRep.push_back(""); contactListLanguage.push_back(""); contactList.push_back(""); bool tokenData = false; string propertyTokens; propertyNameData = (string*)&iter->first; propertyData = SplitValues(*propertyNameData); for(map::iterator dataiter = propertyData.begin(); dataiter != propertyData.end(); dataiter++){ if (dataiter->first == "ALTREP"){ contactListAltRep[objectSeekCount] = dataiter->second; } else if (dataiter->first == "LANGUAGE"){ contactListLanguage[objectSeekCount] = dataiter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += dataiter->first; propertyTokens += "="; propertyTokens += dataiter->second; } } if (propertyTokens.size() > 0){ contactListTokens[objectSeekCount] = propertyTokens; } contactList[objectSeekCount] = iter->second; objectSeekCount++; } // Get the Date Time Start value. dataReceived = ProcessTextVectors(&objectName, &objectData, false, "DTSTART"); // Process the data from DTSTART. if (dataReceived.begin() != dataReceived.end()){ bool tokenData = false; string propertyTokens; propertyNameData = (string*)&dataReceived.begin()->first; propertyData = SplitValues(*propertyNameData); for(map::iterator iter = propertyData.begin(); iter != propertyData.end(); iter++){ if (iter->first == "VALUE"){ dateTimeStartDataValue = iter->second; } else if (iter->first == "TZID"){ dateTimeStartDataTimeZoneID = iter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += iter->first; propertyTokens += "="; propertyTokens += iter->second; } } if (propertyTokens.size() > 0){ dateTimeStartDataTokens = propertyTokens; } dateTimeStartData = dataReceived.begin()->second; } // Process the data from DTEND. bool dateTimeEndProcessed = false; dataReceived = ProcessTextVectors(&objectName, &objectData, false, "DTEND"); if (dataReceived.begin() != dataReceived.end()){ bool tokenData = false; string propertyTokens; propertyNameData = (string*)&dataReceived.begin()->first; propertyData = SplitValues(*propertyNameData); for(map::iterator iter = propertyData.begin(); iter != propertyData.end(); iter++){ if (iter->first == "VALUE"){ dateTimeEndDataValue = iter->second; } else if (iter->first == "TZID"){ dateTimeEndDataTimeZoneID = iter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += iter->first; propertyTokens += "="; propertyTokens += iter->second; } } if (propertyTokens.size() > 0){ dateTimeEndDataTokens = propertyTokens; } dateTimeEndData = dataReceived.begin()->second; dateTimeEndProcessed = true; } // Process the data from ORGANIZER. dataReceived = ProcessTextVectors(&objectName, &objectData, false, "ORGANIZER"); if (dataReceived.begin() != dataReceived.end()){ bool tokenData = false; string propertyTokens; propertyNameData = (string*)&dataReceived.begin()->first; propertyData = SplitValues(*propertyNameData); for(map::iterator iter = propertyData.begin(); iter != propertyData.end(); iter++){ if (iter->first == "CN"){ organiserDataCommonName = iter->second; } else if (iter->first == "DIR"){ organiserDataDirectoryEntry = iter->second; } else if (iter->first == "SENT-BY"){ organiserDataSentByParam = iter->second; } else if (iter->first == "LANGUAGE"){ organiserDataLanguage = iter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += iter->first; propertyTokens += "="; propertyTokens += iter->second; } } if (propertyTokens.size() > 0){ organiserDataTokens = propertyTokens; } organiserData = dataReceived.begin()->second; } // Process the data from URL. dataReceived = ProcessTextVectors(&objectName, &objectData, false, "URL"); if (dataReceived.begin() != dataReceived.end()){ try { urlDataTokens = dataReceived.begin()->first.substr(4); } catch(const out_of_range &oor){ // Do nothing as there is no data. } urlData = dataReceived.begin()->second; } // Process the data from ATTENDEE. dataReceived = ProcessTextVectors(&objectName, &objectData, true, "ATTENDEE"); objectSeekCount = 0; for(multimap::iterator iter = dataReceived.begin(); iter != dataReceived.end(); ++iter){ attendeeListMember.push_back(""); attendeeListDelegatedFrom.push_back(""); attendeeListDelegatedTo.push_back(""); attendeeListRole.push_back(""); attendeeListRSVP.push_back(""); attendeeListDirectoryEntry.push_back(""); attendeeListSentBy.push_back(""); attendeeListCommonName.push_back(""); attendeeListCalendarUserType.push_back(""); attendeeListParticipationStatus.push_back(""); attendeeListLanguage.push_back(""); attendeeListTokens.push_back(""); attendeeList.push_back(""); bool tokenData = false; string propertyTokens; propertyNameData = (string*)&iter->first; propertyData = SplitValues(*propertyNameData); for(map::iterator dataiter = propertyData.begin(); dataiter != propertyData.end(); dataiter++){ if (dataiter->first == "CUTYPE"){ attendeeListCalendarUserType[objectSeekCount] = dataiter->second; } else if (dataiter->first == "MEMBER"){ attendeeListMember[objectSeekCount] = dataiter->second; } else if (dataiter->first == "ROLE"){ attendeeListRole[objectSeekCount] = dataiter->second; } else if (dataiter->first == "PARTSTAT"){ attendeeListParticipationStatus[objectSeekCount] = dataiter->second; } else if (dataiter->first == "RSVP"){ attendeeListRSVP[objectSeekCount] = dataiter->second; } else if (dataiter->first == "DELEGATED-TO"){ attendeeListDelegatedTo[objectSeekCount] = dataiter->second; } else if (dataiter->first == "DELEGATED-FROM"){ attendeeListDelegatedFrom[objectSeekCount] = dataiter->second; } else if (dataiter->first == "SENT-BY"){ attendeeListSentBy[objectSeekCount] = dataiter->second; } else if (dataiter->first == "CN"){ attendeeListCommonName[objectSeekCount] = dataiter->second; } else if (dataiter->first == "DIR"){ attendeeListDirectoryEntry[objectSeekCount] = dataiter->second; } else if (dataiter->first == "LANGUAGE"){ attendeeListLanguage[objectSeekCount] = dataiter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += dataiter->first; propertyTokens += "="; propertyTokens += dataiter->second; } } if (propertyTokens.size() > 0){ attendeeListTokens[objectSeekCount] = propertyTokens; } attendeeList[objectSeekCount] = iter->second; objectSeekCount++; } // Process the data from COMMENT. dataReceived = ProcessTextVectors(&objectName, &objectData, true, "COMMENT"); objectSeekCount = 0; for(multimap::iterator iter = dataReceived.begin(); iter != dataReceived.end(); ++iter){ commentListTokens.push_back(""); commentListAltRep.push_back(""); commentListLanguage.push_back(""); commentList.push_back(""); bool tokenData = false; string propertyTokens; propertyNameData = (string*)&iter->first; propertyData = SplitValues(*propertyNameData); for(map::iterator dataiter = propertyData.begin(); dataiter != propertyData.end(); dataiter++){ if (dataiter->first == "ALTREP"){ commentListAltRep[objectSeekCount] = dataiter->second; } else if (dataiter->first == "LANGUAGE"){ commentListLanguage[objectSeekCount] = dataiter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += dataiter->first; propertyTokens += "="; propertyTokens += dataiter->second; } } if (propertyTokens.size() > 0){ commentListTokens[objectSeekCount] = propertyTokens; } commentList[objectSeekCount] = iter->second; objectSeekCount++; } // Process the data from FREEBUSY. dataReceived = ProcessTextVectors(&objectName, &objectData, true, "FREEBUSY"); objectSeekCount = 0; for(multimap::iterator iter = dataReceived.begin(); iter != dataReceived.end(); ++iter){ freeBusyListTokens.push_back(""); freeBusyListType.push_back(""); freeBusyList.push_back(""); bool tokenData = false; string propertyTokens; propertyNameData = (string*)&iter->first; propertyData = SplitValues(*propertyNameData); for(map::iterator dataiter = propertyData.begin(); dataiter != propertyData.end(); dataiter++){ if (dataiter->first == "FBTYPE"){ freeBusyListType[objectSeekCount] = dataiter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += dataiter->first; propertyTokens += "="; propertyTokens += dataiter->second; } } if (propertyTokens.size() > 0){ freeBusyListTokens[objectSeekCount] = propertyTokens; } freeBusyList[objectSeekCount] = iter->second; objectSeekCount++; } // Process the data from REQUEST-STATUS. dataReceived = ProcessTextVectors(&objectName, &objectData, true, "REQUEST-STATUS"); objectSeekCount = 0; for(multimap::iterator iter = dataReceived.begin(); iter != dataReceived.end(); ++iter){ requestStatusTokens.push_back(""); requestStatusLanguage.push_back(""); requestStatusData.push_back(""); bool tokenData = false; string propertyTokens; propertyNameData = (string*)&iter->first; propertyData = SplitValues(propertyNameData); for(map::iterator dataiter = propertyData.begin(); dataiter != propertyData.end(); dataiter++){ if (dataiter->first == "LANGUAGE"){ requestStatusLanguage[objectSeekCount] = dataiter->second; } else { if (tokenData == false){ tokenData = true; } else { propertyTokens += ";"; } propertyTokens += dataiter->first; propertyTokens += "="; propertyTokens += dataiter->second; } } if (propertyTokens.size() > 0){ requestStatusTokens[objectSeekCount] = propertyTokens; } requestStatusData[objectSeekCount] = iter->second; objectSeekCount++; } objectSeekCount = 0; // Process data from X-* for(vector::iterator iter = objectName.begin(); iter != objectName.end(); ++iter){ bool tokenData = false; string propertyTokens; if (iter->substr(0,2) == "X-" && iter->size() > 2){ xTokensData.push_back(objectData[objectSeekCount]); xTokensDataTokens.push_back(objectName[objectSeekCount]); } objectSeekCount++; } }