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]);