1 // CalendarFreeBusy.cpp - CalendarFreeBusy class functions
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Calendar is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Calendar is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "CalendarFreeBusy.h"
23 CalendarObjectValidResult CalendarFreeBusyObject::ValidObject(){
25 bool validBegin = false;
26 bool validEnd = false;
27 bool validDateTimeStamp = false;
28 bool validUniqueID = false;
29 bool validDateTimeStart = false;
33 // Look for BEGIN:VFREEBUSY.
35 for (vector<string>::iterator iter = objectName.begin();
36 iter != objectName.end(); iter++){
38 if (objectName[seekCount] == "BEGIN" &&
39 objectData[seekCount] == "VFREEBUSY"){
41 if (validBegin == false){
44 return CALENDAROBJECTVALID_INVALIDFORMAT;
49 if (objectName[seekCount] == "END" &&
50 objectData[seekCount] == "VFREEBUSY" &&
53 return CALENDAROBJECTVALID_INVALIDFORMAT;
65 for (vector<string>::iterator iter = objectName.begin();
66 iter != objectName.end(); iter++){
69 propertyName = objectName[seekCount].substr(0,7);
72 catch(const out_of_range& oor){
76 if (propertyName == "DTSTAMP"){
78 if (validDateTimeStamp == false){
79 validDateTimeStamp = true;
81 return CALENDAROBJECTVALID_INVALIDFORMAT;
94 for (vector<string>::iterator iter = objectName.begin();
95 iter != objectName.end(); iter++){
98 PropertyName = objectName[seekCount].substr(0,3);
101 catch(const out_of_range& oor){
105 if (propertyName == "UID"){
107 if (validUniqueID == false){
108 validUniqueID = true;
110 return CALENDAROBJECTVALID_INVALIDFORMAT;
121 // Look for END:VFREEBUSY.
123 for (vector<string>::iterator iter = objectName.begin();
124 iter != objectName.end(); iter++){
126 if (objectName[seekCount] == "END" &&
127 objectData[seekCount] == "VFREEBUSY"){
129 if (validEnd == false){
132 return CALENDAROBJECTVALID_INVALIDFORMAT;
141 // Check if the VEVENT is valid.
143 if (validBegin == true &&
145 validDateTimeStamp == true &&
146 validUniqueID == true){
148 return CALENDAROBJECTVALID_OK;
152 return CALENDAROBJECTVALID_INVALIDFORMAT;
158 void CalendarFreeBusyObject::ProcessData(){
162 multimap<string,string> dataReceived;
163 map<string,string> propertyData;
164 string *propertyNameData = nullptr;
165 int objectSeekCount = 0;
167 // Get the Date Time Stamp (DTSTAMP).
169 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "DTSTAMP");
171 // Process the data from DTSTAMP.
173 if (dataReceived.begin() != dataReceived.end()){
176 dateTimeStampTokens = dataReceived.begin()->first.substr(8);
179 catch(const out_of_range &oor){
180 // Do nothing as there is no data.
183 dateTimeStampData = dataReceived.begin()->second;
187 // Get the Unique ID (UID).
189 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "UID");
191 // Process the data from UID.
193 if (dataReceived.begin() != dataReceived.end()){
196 uniqueIDTokens = dataReceived.begin()->first.substr(4);
199 catch(const out_of_range &oor){
200 // Do nothing as there is no data.
203 uniqueID = dataReceived.begin()->second;
207 // Process the data from CONTACT.
209 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "CONTACT");
213 for(multimap<string,string>::iterator iter = dataReceived.begin();
214 iter != dataReceived.end();
217 contactListTokens.push_back("");
218 contactListAltRep.push_back("");
219 contactListLanguage.push_back("");
220 contactList.push_back("");
222 bool tokenData = false;
223 string propertyTokens;
225 propertyNameData = (string*)&iter->first;
227 propertyData = SplitValues(*propertyNameData);
229 for(map<string,string>::iterator dataiter = propertyData.begin();
230 dataiter != propertyData.end(); dataiter++){
232 if (dataiter->first == "ALTREP"){
234 contactListAltRep[objectSeekCount] = dataiter->second;
236 } else if (dataiter->first == "LANGUAGE"){
238 contactListLanguage[objectSeekCount] = dataiter->second;
242 if (tokenData == false){
245 propertyTokens += ";";
248 propertyTokens += dataiter->first;
249 propertyTokens += "=";
250 propertyTokens += dataiter->second;
256 if (propertyTokens.size() > 0){
257 contactListTokens[objectSeekCount] = propertyTokens;
260 contactList[objectSeekCount] = iter->second;
266 // Get the Date Time Start value.
268 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "DTSTART");
270 // Process the data from DTSTART.
272 if (dataReceived.begin() != dataReceived.end()){
274 bool tokenData = false;
275 string propertyTokens;
277 propertyNameData = (string*)&dataReceived.begin()->first;
279 propertyData = SplitValues(*propertyNameData);
281 for(map<string,string>::iterator iter = propertyData.begin();
282 iter != propertyData.end(); iter++){
284 if (iter->first == "VALUE"){
286 dateTimeStartDataValue = iter->second;
288 } else if (iter->first == "TZID"){
290 dateTimeStartDataTimeZoneID = iter->second;
294 if (tokenData == false){
297 propertyTokens += ";";
300 propertyTokens += iter->first;
301 propertyTokens += "=";
302 propertyTokens += iter->second;
308 if (propertyTokens.size() > 0){
309 dateTimeStartDataTokens = propertyTokens;
312 dateTimeStartData = dataReceived.begin()->second;
316 // Process the data from DTEND.
318 bool dateTimeEndProcessed = false;
320 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "DTEND");
322 if (dataReceived.begin() != dataReceived.end()){
324 bool tokenData = false;
325 string propertyTokens;
327 propertyNameData = (string*)&dataReceived.begin()->first;
329 propertyData = SplitValues(*propertyNameData);
331 for(map<string,string>::iterator iter = propertyData.begin();
332 iter != propertyData.end(); iter++){
334 if (iter->first == "VALUE"){
336 dateTimeEndDataValue = iter->second;
338 } else if (iter->first == "TZID"){
340 dateTimeEndDataTimeZoneID = iter->second;
344 if (tokenData == false){
347 propertyTokens += ";";
350 propertyTokens += iter->first;
351 propertyTokens += "=";
352 propertyTokens += iter->second;
358 if (propertyTokens.size() > 0){
359 dateTimeEndDataTokens = propertyTokens;
362 dateTimeEndData = dataReceived.begin()->second;
364 dateTimeEndProcessed = true;
368 // Process the data from ORGANIZER.
370 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "ORGANIZER");
372 if (dataReceived.begin() != dataReceived.end()){
374 bool tokenData = false;
375 string propertyTokens;
377 propertyNameData = (string*)&dataReceived.begin()->first;
379 propertyData = SplitValues(*propertyNameData);
381 for(map<string,string>::iterator iter = propertyData.begin();
382 iter != propertyData.end(); iter++){
384 if (iter->first == "CN"){
386 organiserDataCommonName = iter->second;
388 } else if (iter->first == "DIR"){
390 organiserDataDirectoryEntry = iter->second;
392 } else if (iter->first == "SENT-BY"){
394 organiserDataSentByParam = iter->second;
396 } else if (iter->first == "LANGUAGE"){
398 organiserDataLanguage = iter->second;
402 if (tokenData == false){
405 propertyTokens += ";";
408 propertyTokens += iter->first;
409 propertyTokens += "=";
410 propertyTokens += iter->second;
416 if (propertyTokens.size() > 0){
418 organiserDataTokens = propertyTokens;
422 organiserData = dataReceived.begin()->second;
426 // Process the data from URL.
428 dataReceived = ProcessTextVectors(&objectName, &objectData, false, "URL");
430 if (dataReceived.begin() != dataReceived.end()){
433 urlDataTokens = dataReceived.begin()->first.substr(4);
436 catch(const out_of_range &oor){
437 // Do nothing as there is no data.
440 urlData = dataReceived.begin()->second;
444 // Process the data from ATTENDEE.
446 dataReceived = ProcessTextVectors(&objectName, &objectData, true, "ATTENDEE");
450 for(multimap<string,string>::iterator iter = dataReceived.begin();
451 iter != dataReceived.end();
454 attendeeListMember.push_back("");
455 attendeeListDelegatedFrom.push_back("");
456 attendeeListDelegatedTo.push_back("");
457 attendeeListRole.push_back("");
458 attendeeListRSVP.push_back("");
459 attendeeListDirectoryEntry.push_back("");
460 attendeeListSentBy.push_back("");
461 attendeeListCommonName.push_back("");
462 attendeeListCalendarUserType.push_back("");
463 attendeeListParticipationStatus.push_back("");
464 attendeeListLanguage.push_back("");
465 attendeeListTokens.push_back("");
466 attendeeList.push_back("");
468 bool tokenData = false;
469 string propertyTokens;
471 propertyNameData = (string*)&iter->first;
473 propertyData = SplitValues(*propertyNameData);
475 for(map<string,string>::iterator dataiter = propertyData.begin();
476 dataiter != propertyData.end(); dataiter++){
478 if (dataiter->first == "CUTYPE"){
480 attendeeListCalendarUserType[objectSeekCount] = dataiter->second;
482 } else if (dataiter->first == "MEMBER"){
484 attendeeListMember[objectSeekCount] = dataiter->second;
486 } else if (dataiter->first == "ROLE"){
488 attendeeListRole[objectSeekCount] = dataiter->second;
490 } else if (dataiter->first == "PARTSTAT"){
492 attendeeListParticipationStatus[objectSeekCount] = dataiter->second;
494 } else if (dataiter->first == "RSVP"){
496 attendeeListRSVP[objectSeekCount] = dataiter->second;
498 } else if (dataiter->first == "DELEGATED-TO"){
500 attendeeListDelegatedTo[objectSeekCount] = dataiter->second;
502 } else if (dataiter->first == "DELEGATED-FROM"){
504 attendeeListDelegatedFrom[objectSeekCount] = dataiter->second;
506 } else if (dataiter->first == "SENT-BY"){
508 attendeeListSentBy[objectSeekCount] = dataiter->second;
510 } else if (dataiter->first == "CN"){
512 attendeeListCommonName[objectSeekCount] = dataiter->second;
514 } else if (dataiter->first == "DIR"){
516 attendeeListDirectoryEntry[objectSeekCount] = dataiter->second;
518 } else if (dataiter->first == "LANGUAGE"){
520 attendeeListLanguage[objectSeekCount] = dataiter->second;
524 if (tokenData == false){
527 propertyTokens += ";";
530 propertyTokens += dataiter->first;
531 propertyTokens += "=";
532 propertyTokens += dataiter->second;
538 if (propertyTokens.size() > 0){
539 attendeeListTokens[objectSeekCount] = propertyTokens;
542 attendeeList[objectSeekCount] = iter->second;
548 // Process the data from COMMENT.
550 dataReceived = ProcessTextVectors(&objectName, &objectData, true, "COMMENT");
554 for(multimap<string,string>::iterator iter = dataReceived.begin();
555 iter != dataReceived.end();
558 commentListTokens.push_back("");
559 commentListAltRep.push_back("");
560 commentListLanguage.push_back("");
561 commentList.push_back("");
563 bool tokenData = false;
564 string propertyTokens;
566 propertyNameData = (string*)&iter->first;
568 propertyData = SplitValues(*propertyNameData);
570 for(map<string,string>::iterator dataiter = propertyData.begin();
571 dataiter != propertyData.end(); dataiter++){
573 if (dataiter->first == "ALTREP"){
575 commentListAltRep[objectSeekCount] = dataiter->second;
577 } else if (dataiter->first == "LANGUAGE"){
579 commentListLanguage[objectSeekCount] = dataiter->second;
583 if (tokenData == false){
586 propertyTokens += ";";
589 propertyTokens += dataiter->first;
590 propertyTokens += "=";
591 propertyTokens += dataiter->second;
597 if (propertyTokens.size() > 0){
598 commentListTokens[objectSeekCount] = propertyTokens;
601 commentList[objectSeekCount] = iter->second;
607 // Process the data from FREEBUSY.
609 dataReceived = ProcessTextVectors(&objectName, &objectData, true, "FREEBUSY");
613 for(multimap<string,string>::iterator iter = dataReceived.begin();
614 iter != dataReceived.end();
617 freeBusyListTokens.push_back("");
618 freeBusyListType.push_back("");
619 freeBusyList.push_back("");
621 bool tokenData = false;
622 string propertyTokens;
624 propertyNameData = (string*)&iter->first;
626 propertyData = SplitValues(*propertyNameData);
628 for(map<string,string>::iterator dataiter = propertyData.begin();
629 dataiter != propertyData.end(); dataiter++){
631 if (dataiter->first == "FBTYPE"){
633 freeBusyListType[objectSeekCount] = dataiter->second;
637 if (tokenData == false){
640 propertyTokens += ";";
643 propertyTokens += dataiter->first;
644 propertyTokens += "=";
645 propertyTokens += dataiter->second;
651 if (propertyTokens.size() > 0){
652 freeBusyListTokens[objectSeekCount] = propertyTokens;
655 freeBusyList[objectSeekCount] = iter->second;
661 // Process the data from REQUEST-STATUS.
663 dataReceived = ProcessTextVectors(&objectName, &objectData, true, "REQUEST-STATUS");
667 for(multimap<string,string>::iterator iter = dataReceived.begin();
668 iter != dataReceived.end();
671 requestStatusTokens.push_back("");
672 requestStatusLanguage.push_back("");
673 requestStatusData.push_back("");
675 bool tokenData = false;
676 string propertyTokens;
678 propertyNameData = (string*)&iter->first;
680 propertyData = SplitValues(propertyNameData);
682 for(map<string,string>::iterator dataiter = propertyData.begin();
683 dataiter != propertyData.end(); dataiter++){
685 if (dataiter->first == "LANGUAGE"){
687 requestStatusLanguage[objectSeekCount] = dataiter->second;
691 if (tokenData == false){
694 propertyTokens += ";";
697 propertyTokens += dataiter->first;
698 propertyTokens += "=";
699 propertyTokens += dataiter->second;
705 if (propertyTokens.size() > 0){
706 requestStatusTokens[objectSeekCount] = propertyTokens;
709 requestStatusData[objectSeekCount] = iter->second;
717 // Process data from X-*
719 for(vector<string>::iterator iter = objectName.begin();
720 iter != objectName.end(); ++iter){
722 bool tokenData = false;
723 string propertyTokens;
725 if (iter->substr(0,2) == "X-" &&
728 xTokensData.push_back(objectData[objectSeekCount]);
729 xTokensDataTokens.push_back(objectName[objectSeekCount]);