1 #include "CalendarTimezone.h"
5 CalendarObjectValidResult CalendarTimezoneObject::ValidObject(){
7 bool ValidBegin = false;
9 bool ValidTimeZoneID = false;
13 // Look for BEGIN:VEVENT.
15 for (vector<string>::iterator iter = ObjectName.begin();
16 iter != ObjectName.end(); iter++){
18 if (ObjectName[SeekCount] == "BEGIN" &&
19 ObjectData[SeekCount] == "VTIMEZONE"){
21 if (ValidBegin == false){
24 return CALENDAROBJECTVALID_INVALIDFORMAT;
29 if (ObjectName[SeekCount] == "END" &&
30 ObjectData[SeekCount] == "VTIMEZONE" &&
33 return CALENDAROBJECTVALID_INVALIDFORMAT;
45 for (vector<string>::iterator iter = ObjectName.begin();
46 iter != ObjectName.end(); iter++){
49 PropertyName = ObjectName[SeekCount].substr(0,4);
52 catch(const out_of_range& oor){
56 if (PropertyName == "TZID"){
58 if (ValidTimeZoneID == false){
59 ValidTimeZoneID = true;
61 return CALENDAROBJECTVALID_INVALIDFORMAT;
72 // Look for END:VEVENT.
74 for (vector<string>::iterator iter = ObjectName.begin();
75 iter != ObjectName.end(); iter++){
77 if (ObjectName[SeekCount] == "END" &&
78 ObjectData[SeekCount] == "VTIMEZONE"){
80 if (ValidEnd == false){
83 return CALENDAROBJECTVALID_INVALIDFORMAT;
92 // Check if the VEVENT is valid.
94 if (ValidBegin == true &&
96 ValidTimeZoneID == true){
98 return CALENDAROBJECTVALID_OK;
102 return CALENDAROBJECTVALID_INVALIDFORMAT;
108 void CalendarTimezoneObject::ProcessData(){
112 multimap<string,string> DataReceived;
113 map<string,string> PropertyData;
114 string *PropertyNameData = nullptr;
115 int ObjectSeekCount = 0;
117 // Process the data from TZID.
119 DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "TZID");
121 if (DataReceived.begin() != DataReceived.end()){
124 TimeZoneDataTokens = DataReceived.begin()->first.substr(5);
127 catch(const out_of_range &oor){
128 // Do nothing as there is no data.
131 TimeZoneData = DataReceived.begin()->second;
135 // Process the data from LAST-MODIFIED.
137 DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "LAST-MODIFIED");
139 if (DataReceived.begin() != DataReceived.end()){
142 LastModifiedTokens = DataReceived.begin()->first.substr(14);
145 catch(const out_of_range &oor){
146 // Do nothing as there is no data.
149 LastModifiedData = DataReceived.begin()->second;
153 // Process the data from TZURL.
155 DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "TZURL");
157 if (DataReceived.begin() != DataReceived.end()){
160 TimeZoneURLTokens = DataReceived.begin()->first.substr(6);
163 catch(const out_of_range &oor){
164 // Do nothing as there is no data.
167 TimeZoneURLData = DataReceived.begin()->second;
171 // Process data from each STANDARD and DAYLIGHT.
173 ProcessStandardDaylight();
178 for (vector<vector<string>>::iterator tzsiter = TimezoneStandardName.begin();
179 tzsiter != TimezoneStandardName.end(); tzsiter++){
181 bool DateTimeStartFound = false;
182 bool TimeZoneOffsetToFound = false;
183 bool TimeZoneOffsetFromFound = false;
185 TimezoneDataStruct NewTZData;
187 // Process the data from DTSTART.
189 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
190 &TimezoneStandardData[SeekCount], false, "DTSTART");
192 if (DataReceived.begin() != DataReceived.end()){
195 NewTZData.DateTimeStartTokens = DataReceived.begin()->first.substr(8);
198 catch(const out_of_range &oor){
199 // Do nothing as there is no data.
202 NewTZData.DateTimeStartData = DataReceived.begin()->second;
203 DateTimeStartFound = true;
207 // Process the data from TZOFFSETFROM.
209 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
210 &TimezoneStandardData[SeekCount], false, "TZOFFSETFROM");
212 if (DataReceived.begin() != DataReceived.end()){
215 NewTZData.TimeZoneOffsetFromTokens = DataReceived.begin()->first.substr(13);
218 catch(const out_of_range &oor){
219 // Do nothing as there is no data.
222 NewTZData.TimeZoneOffsetFromData = DataReceived.begin()->second;
223 TimeZoneOffsetFromFound = true;
227 // Process the data from TZOFFSETTO.
229 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
230 &TimezoneStandardData[SeekCount], false, "TZOFFSETTO");
232 if (DataReceived.begin() != DataReceived.end()){
235 NewTZData.TimeZoneOffsetToTokens = DataReceived.begin()->first.substr(11);
238 catch(const out_of_range &oor){
239 // Do nothing as there is no data.
242 NewTZData.TimeZoneOffsetToData = DataReceived.begin()->second;
243 TimeZoneOffsetToFound = true;
247 // Process the data from RRULE.
249 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
250 &TimezoneStandardData[SeekCount], false, "RRULE");
252 if (DataReceived.begin() != DataReceived.end()){
255 NewTZData.RecurranceRuleDataTokens = DataReceived.begin()->first.substr(6);
258 catch(const out_of_range &oor){
259 // Do nothing as there is no data.
262 NewTZData.RecurranceRuleData = DataReceived.begin()->second;
266 // Process the data from COMMENT.
268 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
269 &TimezoneStandardData[SeekCount], true, "COMMENT");
273 for(multimap<string,string>::iterator propiter = DataReceived.begin();
274 propiter != DataReceived.end();
277 NewTZData.CommentListTokens.push_back("");
278 NewTZData.CommentListAltRep.push_back("");
279 NewTZData.CommentListLanguage.push_back("");
280 NewTZData.CommentList.push_back("");
282 bool TokenData = false;
283 string PropertyTokens;
285 PropertyNameData = (string*)&propiter->first;
287 PropertyData = SplitValues(*PropertyNameData);
289 for(map<string,string>::iterator propdataiter = PropertyData.begin();
290 propdataiter != PropertyData.end(); propdataiter++){
292 if (propdataiter->first == "ALTREP"){
294 NewTZData.CommentListAltRep[ObjectSeekCount] = propdataiter->second;
296 } else if (propdataiter->first == "LANGUAGE"){
298 NewTZData.CommentListLanguage[ObjectSeekCount] = propdataiter->second;
302 if (TokenData == false){
305 PropertyTokens += ";";
308 PropertyTokens += propdataiter->first;
309 PropertyTokens += "=";
310 PropertyTokens += propdataiter->second;
316 if (PropertyTokens.size() > 0){
317 NewTZData.CommentListTokens[ObjectSeekCount] = PropertyTokens;
320 NewTZData.CommentList[ObjectSeekCount] = propiter->second;
326 // Process the data from RDATE.
328 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
329 &TimezoneStandardData[SeekCount], true, "RDATE");
333 for(multimap<string,string>::iterator propiter = DataReceived.begin();
334 propiter != DataReceived.end();
337 NewTZData.RecurranceDateDataTokens.push_back("");
338 NewTZData.RecurranceDateDataValue.push_back("");
339 NewTZData.RecurranceDateDataTimeZoneParam.push_back("");
340 NewTZData.RecurranceDateData.push_back("");
342 bool TokenData = false;
343 string PropertyTokens;
345 PropertyNameData = (string*)&propiter->first;
347 PropertyData = SplitValues(*PropertyNameData);
349 for(map<string,string>::iterator dataiter = PropertyData.begin();
350 dataiter != PropertyData.end(); dataiter++){
352 if (dataiter->first == "VALUE"){
354 NewTZData.RecurranceDateDataValue[ObjectSeekCount] = dataiter->second;
356 } else if (dataiter->first == "TZID"){
358 NewTZData.RecurranceDateDataTimeZoneParam[ObjectSeekCount] = dataiter->second;
362 if (TokenData == false){
365 PropertyTokens += ";";
368 PropertyTokens += dataiter->first;
369 PropertyTokens += "=";
370 PropertyTokens += dataiter->second;
376 if (PropertyTokens.size() > 0){
377 NewTZData.RecurranceDateDataTokens[ObjectSeekCount] = PropertyTokens;
380 NewTZData.RecurranceDateData[ObjectSeekCount] = propiter->second;
386 // Process the data from TZNAME.
388 DataReceived = ProcessTextVectors(&TimezoneStandardName[SeekCount],
389 &TimezoneStandardData[SeekCount], true, "TZNAME");
393 for(multimap<string,string>::iterator propiter = DataReceived.begin();
394 propiter != DataReceived.end();
397 NewTZData.TimeZoneNameTokens.push_back("");
398 NewTZData.TimeZoneNameLanguage.push_back("");
399 NewTZData.TimeZoneNameData.push_back("");
401 bool TokenData = false;
402 string PropertyTokens;
404 PropertyNameData = (string*)&propiter->first;
406 PropertyData = SplitValues(*PropertyNameData);
408 for(map<string,string>::iterator dataiter = PropertyData.begin();
409 dataiter != PropertyData.end(); dataiter++){
411 if (dataiter->first == "LANGUAGE"){
413 NewTZData.TimeZoneNameLanguage[ObjectSeekCount] = dataiter->second;
417 if (TokenData == false){
420 PropertyTokens += ";";
423 PropertyTokens += dataiter->first;
424 PropertyTokens += "=";
425 PropertyTokens += dataiter->second;
431 if (PropertyTokens.size() > 0){
432 NewTZData.TimeZoneNameTokens[ObjectSeekCount] = PropertyTokens;
435 NewTZData.TimeZoneNameData[ObjectSeekCount] = propiter->second;
443 // Process data from X-*
445 for(vector<string>::iterator propiter = TimezoneStandardName[SeekCount].begin();
446 propiter != TimezoneStandardName[SeekCount].end(); ++propiter){
448 if (propiter->substr(0,2) == "X-" &&
449 propiter->size() > 2){
451 NewTZData.XTokensData.push_back(TimezoneStandardData[SeekCount][ObjectSeekCount]);
452 NewTZData.XTokensDataTokens.push_back(TimezoneStandardName[SeekCount][ObjectSeekCount]);
460 // Check if the required values were given and
461 // insert NewTZData into the vector list of
462 // standard timezones.
464 if (DateTimeStartFound == true &&
465 TimeZoneOffsetToFound == true &&
466 TimeZoneOffsetFromFound == true){
468 TimezoneStandardCollection.push_back(NewTZData);
479 for (vector<vector<string>>::iterator tzsiter = TimezoneDaylightName.begin();
480 tzsiter != TimezoneDaylightName.end(); tzsiter++){
482 bool DateTimeStartFound = false;
483 bool TimeZoneOffsetToFound = false;
484 bool TimeZoneOffsetFromFound = false;
486 TimezoneDataStruct NewTZData;
488 // Process the data from DTSTART.
490 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
491 &TimezoneDaylightData[SeekCount], false, "DTSTART");
493 if (DataReceived.begin() != DataReceived.end()){
496 NewTZData.DateTimeStartTokens = DataReceived.begin()->first.substr(8);
499 catch(const out_of_range &oor){
500 // Do nothing as there is no data.
503 NewTZData.DateTimeStartData = DataReceived.begin()->second;
504 DateTimeStartFound = true;
508 // Process the data from TZOFFSETFROM.
510 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
511 &TimezoneDaylightData[SeekCount], false, "TZOFFSETFROM");
513 if (DataReceived.begin() != DataReceived.end()){
516 NewTZData.TimeZoneOffsetFromTokens = DataReceived.begin()->first.substr(13);
519 catch(const out_of_range &oor){
520 // Do nothing as there is no data.
523 NewTZData.TimeZoneOffsetFromData = DataReceived.begin()->second;
524 TimeZoneOffsetFromFound = true;
528 // Process the data from TZOFFSETTO.
530 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
531 &TimezoneDaylightData[SeekCount], false, "TZOFFSETTO");
533 if (DataReceived.begin() != DataReceived.end()){
536 NewTZData.TimeZoneOffsetToTokens = DataReceived.begin()->first.substr(11);
539 catch(const out_of_range &oor){
540 // Do nothing as there is no data.
543 NewTZData.TimeZoneOffsetToData = DataReceived.begin()->second;
544 TimeZoneOffsetToFound = true;
548 // Process the data from RRULE.
550 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
551 &TimezoneDaylightData[SeekCount], false, "RRULE");
553 if (DataReceived.begin() != DataReceived.end()){
556 NewTZData.RecurranceRuleDataTokens = DataReceived.begin()->first.substr(6);
559 catch(const out_of_range &oor){
560 // Do nothing as there is no data.
563 NewTZData.RecurranceRuleData = DataReceived.begin()->second;
567 // Process the data from COMMENT.
569 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
570 &TimezoneDaylightData[SeekCount], true, "COMMENT");
574 for(multimap<string,string>::iterator propiter = DataReceived.begin();
575 propiter != DataReceived.end();
578 NewTZData.CommentListTokens.push_back("");
579 NewTZData.CommentListAltRep.push_back("");
580 NewTZData.CommentListLanguage.push_back("");
581 NewTZData.CommentList.push_back("");
583 bool TokenData = false;
584 string PropertyTokens;
586 PropertyNameData = (string*)&propiter->first;
588 PropertyData = SplitValues(*PropertyNameData);
590 for(map<string,string>::iterator propdataiter = PropertyData.begin();
591 propdataiter != PropertyData.end(); propdataiter++){
593 if (propdataiter->first == "ALTREP"){
595 NewTZData.CommentListAltRep[ObjectSeekCount] = propdataiter->second;
597 } else if (propdataiter->first == "LANGUAGE"){
599 NewTZData.CommentListLanguage[ObjectSeekCount] = propdataiter->second;
603 if (TokenData == false){
606 PropertyTokens += ";";
609 PropertyTokens += propdataiter->first;
610 PropertyTokens += "=";
611 PropertyTokens += propdataiter->second;
617 if (PropertyTokens.size() > 0){
618 NewTZData.CommentListTokens[ObjectSeekCount] = PropertyTokens;
621 NewTZData.CommentList[ObjectSeekCount] = propiter->second;
627 // Process the data from RDATE.
629 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
630 &TimezoneDaylightData[SeekCount], true, "RDATE");
634 for(multimap<string,string>::iterator propiter = DataReceived.begin();
635 propiter != DataReceived.end();
638 NewTZData.RecurranceDateDataTokens.push_back("");
639 NewTZData.RecurranceDateDataValue.push_back("");
640 NewTZData.RecurranceDateDataTimeZoneParam.push_back("");
641 NewTZData.RecurranceDateData.push_back("");
643 bool TokenData = false;
644 string PropertyTokens;
646 PropertyNameData = (string*)&propiter->first;
648 PropertyData = SplitValues(*PropertyNameData);
650 for(map<string,string>::iterator dataiter = PropertyData.begin();
651 dataiter != PropertyData.end(); dataiter++){
653 if (dataiter->first == "VALUE"){
655 NewTZData.RecurranceDateDataValue[ObjectSeekCount] = dataiter->second;
657 } else if (dataiter->first == "TZID"){
659 NewTZData.RecurranceDateDataTimeZoneParam[ObjectSeekCount] = dataiter->second;
663 if (TokenData == false){
666 PropertyTokens += ";";
669 PropertyTokens += dataiter->first;
670 PropertyTokens += "=";
671 PropertyTokens += dataiter->second;
677 if (PropertyTokens.size() > 0){
678 NewTZData.RecurranceDateDataTokens[ObjectSeekCount] = PropertyTokens;
681 NewTZData.RecurranceDateData[ObjectSeekCount] = propiter->second;
687 // Process the data from TZNAME.
689 DataReceived = ProcessTextVectors(&TimezoneDaylightName[SeekCount],
690 &TimezoneDaylightData[SeekCount], true, "TZNAME");
694 for(multimap<string,string>::iterator propiter = DataReceived.begin();
695 propiter != DataReceived.end();
698 NewTZData.TimeZoneNameTokens.push_back("");
699 NewTZData.TimeZoneNameLanguage.push_back("");
700 NewTZData.TimeZoneNameData.push_back("");
702 bool TokenData = false;
703 string PropertyTokens;
705 PropertyNameData = (string*)&propiter->first;
707 PropertyData = SplitValues(*PropertyNameData);
709 for(map<string,string>::iterator dataiter = PropertyData.begin();
710 dataiter != PropertyData.end(); dataiter++){
712 if (dataiter->first == "LANGUAGE"){
714 NewTZData.TimeZoneNameLanguage[ObjectSeekCount] = dataiter->second;
718 if (TokenData == false){
721 PropertyTokens += ";";
724 PropertyTokens += dataiter->first;
725 PropertyTokens += "=";
726 PropertyTokens += dataiter->second;
732 if (PropertyTokens.size() > 0){
733 NewTZData.TimeZoneNameTokens[ObjectSeekCount] = PropertyTokens;
736 NewTZData.TimeZoneNameData[ObjectSeekCount] = propiter->second;
744 // Process data from X-*
746 for(vector<string>::iterator propiter = TimezoneDaylightName[SeekCount].begin();
747 propiter != TimezoneDaylightName[SeekCount].end(); ++propiter){
749 if (propiter->substr(0,2) == "X-" &&
750 propiter->size() > 2){
752 NewTZData.XTokensData.push_back(TimezoneDaylightData[SeekCount][ObjectSeekCount]);
753 NewTZData.XTokensDataTokens.push_back(TimezoneDaylightName[SeekCount][ObjectSeekCount]);
761 // Check if the required values were given and
762 // insert NewTZData into the vector list of
763 // daylight timezones.
765 if (DateTimeStartFound == true &&
766 TimeZoneOffsetToFound == true &&
767 TimeZoneOffsetFromFound == true){
769 TimezoneDaylightCollection.push_back(NewTZData);
779 void CalendarTimezoneObject::ProcessStandardDaylight(){
783 bool TZMode = false; // False = STANDARD, True = DAYLIGHT.
784 bool ValidBegin = false;
785 vector<string> TimezoneObjectName;
786 vector<string> TimezoneObjectData;
788 for (vector<string>::iterator iter = ObjectName.begin();
789 iter != ObjectName.end(); iter++){
791 // Check if the current name is BEGIN and
792 // data is either STANDARD or DAYLIGHT.
794 if (ObjectName[SeekCount] == "BEGIN" &&
795 (ObjectData[SeekCount] == "STANDARD" ||
796 ObjectData[SeekCount] == "DAYLIGHT")){
798 if (ValidBegin == false){
804 if (ObjectData[SeekCount] == "STANDARD"){
806 } else if (ObjectData[SeekCount] == "DAYLIGHT") {
815 // Check if current name is END and
816 // data is either STANDARD or DAYLIGHT.
818 if (ObjectName[SeekCount] == "END" &&
819 (ObjectData[SeekCount] == "STANDARD" ||
820 ObjectData[SeekCount] == "DAYLIGHT") &&
823 if (TZMode == false && TimezoneObjectName.size() > 0){
824 TimezoneStandardName.push_back(TimezoneObjectName);
825 TimezoneStandardData.push_back(TimezoneObjectData);
827 TimezoneDaylightName.push_back(TimezoneObjectName);
828 TimezoneDaylightData.push_back(TimezoneObjectData);
831 TimezoneObjectName.clear();
832 TimezoneObjectData.clear();
838 if (ValidBegin == true){
840 TimezoneObjectName.push_back(ObjectName[SeekCount]);
841 TimezoneObjectData.push_back(ObjectData[SeekCount]);