1 // vcard34conv-v4conv.cpp - vCard34Conv Object vCard4 conversion subroutines.
3 // (c) 2012-2015 Xestia Software Development.
5 // This file is part of Xestia Address Book.
7 // Xestia Address Book 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 Address Book 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 Address Book. If not, see <http://www.gnu.org/licenses/>
19 #include "vcard34conv.h"
21 #include "../version.h"
22 #include "../common/textprocessing.h"
25 #include <wx/tokenzr.h>
26 #include <wx/datetime.h>
29 bool vCard34Conv::ConvertToV4(wxString *wxSData, vCard *vCardOut){
31 // Convert a vCard 3.0 format into the vCard 4.0 format.
33 std::map<int, wxString> ContactFileLines;
34 std::map<int, bool> ContactFileProcessed;
35 std::map<int, bool> ContactFileProcessedWorking;
36 std::map<int, wxString>::iterator striter;
37 std::map<int,bool>::iterator iterbool;
38 std::map<int,bool>::iterator iterboolsub;
39 wxString ContactLineRec;
41 // Process the received data.
43 wxStringTokenizer wSTContactFileLines(*wxSData, wxT("\r\n"));
45 int ContactLineSeek = 0;
47 while (wSTContactFileLines.HasMoreTokens() == TRUE){
49 ContactLineRec = wSTContactFileLines.GetNextToken();
50 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLineRec));
51 ContactFileProcessed.insert(std::make_pair(ContactLineSeek, FALSE));
56 bool QuoteMode = FALSE;
57 bool PropertyFind = TRUE;
58 bool ExtraLineSeek = TRUE;
59 bool ExtraLineSeekSub = TRUE;
61 bool NicknameFirst = FALSE;
62 bool TitleFirst = FALSE;
63 bool OrganisationFirst = FALSE;
64 bool NoteFirst = FALSE;
65 bool PhotoFirst = FALSE;
66 bool FoundData = FALSE;
68 wxString wxSPropertyVCARD4;
69 wxString wxSPropertySeg1;
70 wxString wxSPropertySeg2;
71 wxString wxSPropertyNextLine;
73 wxString ContactLineSub;
74 wxString PropertyName;
75 wxString PropertyValue;
76 wxString PropertyDataStr;
77 size_t ContactLineLen = 0;
78 size_t ContactLineSubLen = 0;
79 int QuoteBreakPoint = 0;
80 size_t intPrevValueSub = 0;
82 std::map<wxString, wxString> PropertyData;
83 std::map<wxString, bool> PropertyLock;
84 std::map<wxString, wxString> TempPropertyData;
85 std::map<wxString, bool> TempPropertyLock;
86 std::map<int, int> TempSplitPoints;
87 std::map<int, int> TempSplitLength;
88 std::map<int, int>::iterator SLiter;
90 wxString PropertFindSub;
91 wxString wxSPropertySub;
92 wxString wxSPropertySeg1Sub;
93 wxString wxSPropertySeg2Sub;
94 wxString wxSPropertyValues;
95 wxString wxSPropertyData;
96 wxString wxSPropertyNameConv;
97 wxString wxSPropertyXVCard4Value;
98 wxString ItemProcString;
100 bool XVCard4Value = FALSE;
101 bool VCard3Value = FALSE;
105 // Setup the version string.
107 strVer.Append(wxT("-//Xestia//Address Book Version "));
108 strVer.Append(wxT(XSDAB_VERSION));
109 strVer.Append(wxT("//KW"));
111 vCardOut->AddRaw(wxT("BEGIN"), wxT("VCARD"));
112 vCardOut->AddRaw(wxT("VERSION"), wxT("4.0"));
113 vCardOut->AddRaw(wxT("PRODID"), strVer);
122 // Process the properties which have X-FIRST.
124 // Clone the ContactFileProcessed into ContactFileProcessedWorking.
126 ContactFileProcessedWorking.insert(ContactFileProcessed.begin(), ContactFileProcessed.end());
128 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
129 iter != ContactFileLines.end(); ++iter){
131 ExtraLineSeek = TRUE;
133 iterbool = ContactFileProcessed.find(iter->first);
135 ContactLine = iter->second;
137 // Ignore certain variables as they are not needed.
139 if (ContactLine == wxT("BEGIN:VCARD") ||
140 ContactLine == wxT("END:VCARD") ||
141 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
142 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
143 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
144 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
145 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
146 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
147 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
148 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
149 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
150 ContactLine.Mid(0, 4) == wxT("REV:")){
152 iterbool->second = TRUE;
157 if (iterbool->second == TRUE){
163 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
169 if (ContactLine.Mid(0, 4) == wxT("item")){
171 // Line is a itemn... so ignore.
177 std::map<int,int> DataLineProcess;
178 std::map<int, bool>::iterator DLSLiter;
179 std::map<int,int> DataLineProcessOriginal;
180 int DataLineSeek = 0;
181 int DataLineSeekOrig = 0;
183 std::map<int,wxString>::iterator itersub = iter;
184 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterbool->first));
187 while (ExtraLineSeek == TRUE){
189 // Check if there is extra data on the next line
190 // (indicated by space or tab at the start) and add data.
194 if (itersub == ContactFileLines.end()){
200 iterboolsub = ContactFileProcessed.find(itersub->first);
202 if (iterboolsub == ContactFileProcessed.end()){
208 if (iterboolsub->second == TRUE){
214 wxSPropertyNextLine = itersub->second;
216 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
218 wxSPropertyNextLine.Remove(0, 1);
219 ContactLine.Append(wxSPropertyNextLine);
220 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterboolsub->first));
225 ExtraLineSeek = FALSE;
231 ContactLineLen = ContactLine.Len();
233 for (int i = 0; i <= ContactLineLen; i++){
235 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
237 PropertyFind = FALSE;
239 } else if (PropertyFind == TRUE){
241 wxSProperty.Append(ContactLine.Mid(i, 1));
245 if (ContactLine.Mid(i, 1) == wxT("\"")){
247 if (QuoteMode == TRUE){
259 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
268 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
269 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
271 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
272 wxSProperty = wxSPropertySegSplit.GetNextToken();
274 // Check what type of property it is.
278 if ((wxSProperty == wxT("PHOTO") && PhotoFirst == FALSE) ||
279 (wxSProperty == wxT("NICKNAME") && NicknameFirst == FALSE) ||
280 (wxSProperty == wxT("TITLE") && TitleFirst == FALSE) ||
281 (wxSProperty == wxT("FN") && FNFirst == FALSE) ||
282 (wxSProperty == wxT("ORG") && OrganisationFirst == FALSE) ||
283 (wxSProperty == wxT("NOTE") && NoteFirst == FALSE)){
285 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
286 intPrevValueSub = (wxSPropertyVCARD4.Len() + 2);
288 for (std::map<int,wxString>::iterator itersub = ContactFileLines.begin();
289 itersub != ContactFileLines.end(); ++itersub){
291 ContactLineSub = itersub->second;
293 ExtraLineSeekSub = TRUE;
295 iterboolsub = ContactFileProcessed.find(itersub->first);
297 // Ignore certain variables as they are not needed.
299 if (ContactLineSub == wxT("BEGIN:VCARD") ||
300 ContactLineSub == wxT("END:VCARD") ||
301 ContactLineSub.Mid(0, 8) == wxT("VERSION:") ||
302 ContactLineSub.Mid(0, 7) == wxT("PRODID:") ||
303 ContactLineSub.Mid(0, 5) == wxT("X-AIM") ||
304 ContactLineSub.Mid(0, 5) == wxT("X-MSN") ||
305 ContactLineSub.Mid(0, 5) == wxT("X-ICQ") ||
306 ContactLineSub.Mid(0, 10) == wxT("X-GADUGADU") ||
307 ContactLineSub.Mid(0, 7) == wxT("X-YAHOO") ||
308 ContactLineSub.Mid(0, 7) == wxT("X-SKYPE") ||
309 ContactLineSub.Mid(0, 8) == wxT("X-JABBER") ||
310 ContactLineSub.Mid(0, 4) == wxT("REV:")){
312 iterboolsub->second = TRUE;
317 if (iterboolsub->second == TRUE){
323 if (ContactLineSub.Mid(0, 1) == wxT(" ") || ContactLineSub.Mid(0, 1) == wxT("\t")){
329 if (ContactLineSub.Mid(0, 4) == wxT("item")){
331 // Line is a itemn... so ignore.
337 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
340 while (ExtraLineSeekSub == TRUE){
342 if (itersub == ContactFileLines.end()){
343 ExtraLineSeekSub = FALSE;
350 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
352 wxSPropertyNextLine = itersub->second;
354 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
356 wxSPropertyNextLine.Remove(0, 1);
357 ContactLineSub.Append(wxSPropertyNextLine);
358 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
364 ExtraLineSeekSub = FALSE;
370 ContactLineSubLen = ContactLineSub.Len();
372 wxSPropertySub.clear();
374 for (int i = 0; i <= ContactLineSubLen; i++){
376 if ((ContactLineSub.Mid(i, 1) == wxT(";") || ContactLineSub.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
378 PropertyFind = FALSE;
380 } else if (PropertyFind == TRUE){
382 wxSPropertySub.Append(ContactLineSub.Mid(i, 1));
386 if (ContactLineSub.Mid(i, 1) == wxT("\"")){
388 if (QuoteMode == TRUE){
400 if (ContactLineSub.Mid(i, 1) == wxT(":") && ContactLineSub.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
409 if (wxSPropertySub != wxSPropertyVCARD4){
411 wxSPropertySub.clear();
413 DataLineProcess.clear();
418 wxSPropertySeg1Sub = ContactLineSub.Mid(0, QuoteBreakPoint);
419 wxSPropertySeg2Sub = ContactLineSub.Mid((QuoteBreakPoint + 1));
421 // Split the property name data.
423 // Strip the X-VCARD4- from the variable.
425 wxString wxSPropertyChopped = wxSPropertySeg1Sub.Mid(9);
427 intPrevValueSub = (wxSProperty.Len() + 2);
429 SplitValuesData(&wxSPropertyChopped, &TempSplitPoints, &TempSplitLength, (int)intPrevValueSub, &TempPropertyData);
431 // Process the splitted data into temporary property data.
433 // Look for certain property names and the X-FIRST
436 bool ProcessData = FALSE;
438 // Check for X-FIRST.
440 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
441 xfiter != TempPropertyData.end(); ++xfiter){
443 PropertyName = xfiter->first;
444 PropertyValue = xfiter->second;
446 if (PropertyName == wxT("X-FIRST") && PropertyValue == wxT("TRUE")){
450 if (wxSProperty == wxT("PHOTO")){ PhotoFirst = TRUE; }
451 else if (wxSProperty == wxT("NICKNAME")){ NicknameFirst = TRUE; }
452 else if (wxSProperty == wxT("TITLE")){ TitleFirst = TRUE; }
453 else if (wxSProperty == wxT("FN")){ FNFirst = TRUE; }
454 else if (wxSProperty == wxT("ORG")){ OrganisationFirst = TRUE; }
455 else if (wxSProperty == wxT("NOTE")){ NoteFirst = TRUE; }
462 if (ProcessData == FALSE){
464 DataLineProcess.clear();
466 TempPropertyData.clear();
470 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
471 xfiter != TempPropertyData.end(); ++xfiter){
473 PropertyName = xfiter->first;
474 PropertyValue = xfiter->second;
476 if (PropertyName == wxT("X-FIRST")){
482 PropertyData.insert(std::make_pair(PropertyName, PropertyValue));
483 PropertyLock.insert(std::make_pair(PropertyName, FALSE));
487 // Mark all lines as processed.
489 for (std::map<int,int>::iterator dpiter = DataLineProcess.begin();
490 dpiter != DataLineProcess.end(); ++dpiter){
492 DLSLiter = ContactFileProcessed.find(dpiter->second);
493 DLSLiter->second = TRUE;
497 for (std::map<int,int>::iterator dpoiter = DataLineProcessOriginal.begin();
498 dpoiter != DataLineProcessOriginal.end(); ++dpoiter){
500 DLSLiter = ContactFileProcessed.find(dpoiter->second);
501 DLSLiter->second = TRUE;
505 DataLineProcess.clear();
506 DataLineProcessOriginal.clear();
508 DataLineSeekOrig = 0;
509 TempSplitPoints.clear();
510 TempSplitLength.clear();
511 TempPropertyData.clear();
523 wxSPropertySub.Clear();
524 wxSPropertySeg1.Clear();
525 wxSPropertySeg2.Clear();
526 wxSPropertySeg1Sub.Clear();
527 wxSPropertySeg2Sub.Clear();
528 wxSPropertyValues.Clear();
529 wxSPropertyData.Clear();
530 wxSPropertyXVCard4Value.Clear();
531 wxSPropertyNameConv.Clear();
532 PropertyData.clear();
533 PropertyLock.clear();
535 ContactLineSub.clear();
536 DataLineProcess.clear();
537 DataLineProcessOriginal.clear();
538 TempSplitPoints.clear();
539 TempSplitLength.clear();
540 wxSPropertyVCARD4.clear();
542 DataLineSeekOrig = 0;
543 XVCard4Value = FALSE;
548 if (FoundData == FALSE){
551 wxSPropertySub.Clear();
552 wxSPropertySeg1.Clear();
553 wxSPropertySeg2.Clear();
554 wxSPropertySeg1Sub.Clear();
555 wxSPropertySeg2Sub.Clear();
556 wxSPropertyValues.Clear();
557 wxSPropertyData.Clear();
558 wxSPropertyXVCard4Value.Clear();
559 wxSPropertyNameConv.Clear();
560 PropertyData.clear();
561 PropertyLock.clear();
563 ContactLineSub.clear();
564 DataLineProcess.clear();
565 DataLineProcessOriginal.clear();
566 TempSplitPoints.clear();
567 TempSplitLength.clear();
568 wxSPropertyVCARD4.clear();
570 DataLineSeekOrig = 0;
571 XVCard4Value = FALSE;
576 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
577 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
578 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
580 wxString FinalPropertyData;
582 FinalPropertyData.Append(wxSPropertyNameConv);
584 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
585 striter != PropertyData.end(); ++striter){
587 FinalPropertyData.Append(wxT(";"));
588 FinalPropertyData.Append(striter->first);
589 FinalPropertyData.Append(wxT("="));
590 FinalPropertyData.Append(striter->second);
594 wxString FinalPropValue;
596 if (wxSPropertyXVCard4Value.IsEmpty()){
598 FinalPropValue = wxSPropertyData;
602 if (wxSPropertyXVCard4Value != wxSPropertyData){
604 FinalPropValue = wxSPropertyXVCard4Value;
610 if (FinalPropertyData.IsEmpty() && FinalPropValue.IsEmpty()){
616 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
619 wxSPropertySub.Clear();
620 wxSPropertySeg1.Clear();
621 wxSPropertySeg2.Clear();
622 wxSPropertySeg1Sub.Clear();
623 wxSPropertySeg2Sub.Clear();
624 wxSPropertyValues.Clear();
625 wxSPropertyData.Clear();
626 wxSPropertyXVCard4Value.Clear();
627 wxSPropertyNameConv.Clear();
628 PropertyData.clear();
629 PropertyLock.clear();
631 ContactLineSub.clear();
632 DataLineProcess.clear();
633 DataLineProcessOriginal.clear();
634 wxSPropertyVCARD4.clear();
636 DataLineSeekOrig = 0;
637 XVCard4Value = FALSE;
642 // Process the non-itemn values.
644 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
645 iter != ContactFileLines.end(); ++iter){
647 ExtraLineSeek = TRUE;
649 iterbool = ContactFileProcessed.find(iter->first);
651 ContactLine = iter->second;
653 // Ignore certain variables as they are not needed.
655 if (ContactLine == wxT("BEGIN:VCARD") ||
656 ContactLine == wxT("END:VCARD") ||
657 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
658 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
659 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
660 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
661 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
662 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
663 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
664 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
665 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
666 ContactLine.Mid(0, 4) == wxT("REV:")){
668 iterbool->second = TRUE;
673 if (iterbool->second == TRUE){
679 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
685 if (ContactLine.Mid(0, 4) == wxT("item")){
687 // Line is a itemn... so ignore.
693 std::map<int,wxString>::iterator itersub = iter;
695 while (ExtraLineSeek == TRUE){
697 // Check if there is extra data on the next line
698 // (indicated by space or tab at the start) and add data.
700 if (itersub == ContactFileLines.end()){
701 ExtraLineSeekSub = FALSE;
709 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
711 if (iterboolsub == ContactFileProcessedWorking.end()){
717 if (iterboolsub->second == TRUE){
723 if (itersub == ContactFileLines.end()){
729 wxSPropertyNextLine = itersub->second;
731 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
733 wxSPropertyNextLine.Remove(0, 1);
734 ContactLine.Append(wxSPropertyNextLine);
735 iterboolsub->second = TRUE;
739 ExtraLineSeek = FALSE;
745 ContactLineLen = ContactLine.Len();
747 for (int i = 0; i <= ContactLineLen; i++){
749 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
751 PropertyFind = FALSE;
753 } else if (PropertyFind == TRUE){
755 wxSProperty.Append(ContactLine.Mid(i, 1));
759 if (ContactLine.Mid(i, 1) == wxT("\"")){
761 if (QuoteMode == TRUE){
773 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
782 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
783 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
785 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
786 wxSProperty = wxSPropertySegSplit.GetNextToken();
788 std::map<int,int> DataLineProcess;
789 std::map<int, bool>::iterator DLSLiter;
791 // Look for the X-VCARD4-(variablename) equivilant.
793 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
795 // Sort out remainder of the types.
797 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
798 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
799 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
801 wxString FinalPropertyData;
803 FinalPropertyData.Append(wxSPropertyNameConv);
805 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
806 striter != PropertyData.end(); ++striter){
808 FinalPropertyData.Append(wxT(";"));
809 FinalPropertyData.Append(striter->first);
810 FinalPropertyData.Append(wxT("="));
811 FinalPropertyData.Append(striter->second);
815 wxString FinalPropValue;
817 if (wxSPropertyXVCard4Value.IsEmpty()){
819 FinalPropValue = wxSPropertyData;
823 if (wxSPropertyXVCard4Value != wxSPropertyData){
825 FinalPropValue = wxSPropertyXVCard4Value;
831 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
834 wxSPropertySub.Clear();
835 wxSPropertySeg1.Clear();
836 wxSPropertySeg2.Clear();
837 wxSPropertyValues.Clear();
838 wxSPropertyData.Clear();
839 wxSPropertyXVCard4Value.Clear();
840 wxSPropertyNameConv.Clear();
841 PropertyData.clear();
842 PropertyLock.clear();
844 XVCard4Value = FALSE;
849 size_t ItemStringSeekLen = 0;
851 std::map<int, wxString> NumberedName;
852 std::map<int, wxString> NumberedData;
853 std::map<int, wxString> NumberedPropValues;
854 std::map<int, wxString> NumberedPropOldValue;
856 std::map<int, wxString> UnNumberedName;
857 std::map<int, wxString> UnNumberedData;
858 std::map<int, wxString> UnNumberedPropValues;
859 std::map<int, wxString> UnNumberedPropOldValue;
861 // Part 1: Get the itemn number.
863 std::map<int,bool>::iterator iterboolsecsub;
864 std::map<int,wxString>::iterator itersub;
865 std::map<int, wxString> TempData;
866 PropertyData.clear();
867 PropertyLock.clear();
869 wxString ItemStringSeek;
870 wxString ItemPropName;
873 ContactLineSub.clear();
874 ExtraLineSeekSub = 0;
875 wxString wxSPropertyNextLineSub;
876 ContactLineSubLen = 0;
878 PropertFindSub.clear();
879 wxSPropertySub.clear();
880 wxSPropertySeg1Sub.clear();
881 wxSPropertySeg2Sub.clear();
882 wxSPropertyValues.clear();
883 wxSPropertyData.clear();
884 wxSPropertyNameConv.clear();
885 wxSPropertyXVCard4Value.clear();
886 ItemProcString.clear();
888 XVCard4Value = FALSE;
891 std::map<wxString, void*> ItemMapIndex;
893 // Look for item in the initial line, process into a proper line then
894 // look for other lines with the same item association.
896 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
897 iter != ContactFileLines.end(); ++iter){
899 ExtraLineSeek = TRUE;
901 iterbool = ContactFileProcessed.find(iter->first);
903 if (iterbool->second == TRUE){
909 ContactLine = iter->second;
911 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
917 if (ContactLine.Mid(0, 4) != wxT("item")){
925 std::map<int,wxString>::iterator itersub = iter;
927 while (ExtraLineSeek == TRUE){
929 // Check if there is extra data on the next line
930 // (indicated by space or tab at the start) and add data.
933 iterboolsub = ContactFileProcessed.find(itersub->first);
935 if (iterboolsub == ContactFileProcessed.end()){
941 if (iterboolsub->second == TRUE){
947 if (itersub == ContactFileLines.end()){
953 wxSPropertyNextLine = itersub->second;
955 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
957 wxSPropertyNextLine.Remove(0, 1);
958 ContactLine.Append(wxSPropertyNextLine);
959 iterboolsub->second = TRUE;
963 ExtraLineSeek = FALSE;
969 ContactLineLen = ContactLine.Len();
971 for (int i = 0; i <= ContactLineLen; i++){
973 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
975 PropertyFind = FALSE;
977 } else if (PropertyFind == TRUE){
979 wxSProperty.Append(ContactLine.Mid(i, 1));
983 if (ContactLine.Mid(i, 1) == wxT("\"")){
985 if (QuoteMode == TRUE){
997 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1006 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1007 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1009 // Go through the lines and collect the lines like itemn.
1011 std::map<int,wxString> *ItemListData;
1012 ItemListData = new std::map<int,wxString>;
1014 wxStringTokenizer ItemData(wxSPropertySeg1, wxT("."));
1016 ItemString = ItemData.GetNextToken();
1017 ItemStringSeek = wxT("item") + ItemString.Mid(4);
1019 wxStringTokenizer ItemPropSplit(ItemData.GetNextToken(), wxT(";"));
1021 ItemPropName = ItemPropSplit.GetNextToken();
1023 ItemStringSeekLen = ItemStringSeek.Len();
1027 for (std::map<int,wxString>::iterator itersec = ContactFileLines.begin();
1028 itersec != ContactFileLines.end(); ++itersec){
1030 ExtraLineSeek = TRUE;
1032 iterboolsub = ContactFileProcessed.find(itersec->first);
1034 if (iterboolsub->second == TRUE){
1040 ContactLineSub = itersec->second;
1042 wxStringTokenizer ItemProcData(ContactLineSub, wxT("."));
1043 ItemProcString = ItemData.GetNextToken();
1045 if (ItemStringSeek != ContactLineSub.Mid(0, ItemStringSeekLen)){
1053 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1055 iterboolsub->second = TRUE;
1059 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1060 ItemMapIndex.insert(std::make_pair(ItemStringSeek, ItemListData));
1064 // Process each itemn set.
1066 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1067 iter != ItemMapIndex.end(); ++iter){
1069 std::map<int, wxString> *ItemDataPtr;
1071 ItemDataPtr = (std::map<int,wxString>*)iter->second;
1073 for (std::map<int,wxString>::iterator itersub = ItemDataPtr->begin();
1074 itersub != ItemDataPtr->end(); ++itersub){
1076 ContactLine = itersub->second;
1078 ContactLineLen = ContactLine.Len();
1080 for (int i = 0; i <= ContactLineLen; i++){
1082 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1084 PropertyFind = FALSE;
1086 } else if (PropertyFind == TRUE){
1088 wxSProperty.Append(ContactLine.Mid(i, 1));
1092 if (ContactLine.Mid(i, 1) == wxT("\"")){
1094 if (QuoteMode == TRUE){
1106 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1108 QuoteBreakPoint = i;
1115 wxSPropertySeg1Sub = ContactLine.Mid(0, QuoteBreakPoint);
1116 wxSPropertySeg2Sub = ContactLine.Mid((QuoteBreakPoint + 1));
1118 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1Sub, wxT(";"));
1119 wxSProperty = wxSPropertySegSplit.GetNextToken();
1121 // Sort out remainder of the types.
1123 // Skip certain X-* IM variables as they are processed via
1126 if (wxSProperty == wxT("X-AIM") || wxSProperty == wxT("X-MSN") ||
1127 wxSProperty == wxT("X-ICQ") || wxSProperty == wxT("X-GADUGADU") ||
1128 wxSProperty == wxT("X-YAHOO") || wxSProperty == wxT("X-SKYPE") ||
1129 wxSProperty == wxT("X-JABBER")){
1131 wxSProperty.clear();
1132 wxSPropertySub.Clear();
1133 wxSPropertySeg1.Clear();
1134 wxSPropertySeg2.Clear();
1135 wxSPropertyValues.Clear();
1136 wxSPropertyData.Clear();
1137 wxSPropertyXVCard4Value.Clear();
1138 wxSPropertyNameConv.Clear();
1139 PropertyData.clear();
1140 PropertyLock.clear();
1141 ContactLine.clear();
1142 XVCard4Value = FALSE;
1143 VCard3Value = FALSE;
1148 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1Sub, &wxSPropertySeg2Sub,
1149 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
1150 &wxSPropertyNameConv, &PropertyData, &PropertyLock, TRUE, &VCard3Value, &XVCard4Value);
1154 if (wxSPropertyNameConv.IsEmpty()){
1156 wxSProperty.clear();
1157 wxSPropertySub.Clear();
1158 wxSPropertySeg1.Clear();
1159 wxSPropertySeg2.Clear();
1160 wxSPropertyValues.Clear();
1161 wxSPropertyData.Clear();
1162 wxSPropertyXVCard4Value.Clear();
1163 wxSPropertyNameConv.Clear();
1164 PropertyData.clear();
1165 PropertyLock.clear();
1166 ContactLine.clear();
1167 XVCard4Value = FALSE;
1168 VCard3Value = FALSE;
1173 wxString FinalPropertyData;
1175 FinalPropertyData.Append(wxSPropertyNameConv);
1177 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
1178 striter != PropertyData.end(); ++striter){
1180 FinalPropertyData.Append(wxT(";"));
1181 FinalPropertyData.Append(striter->first);
1182 FinalPropertyData.Append(wxT("="));
1183 FinalPropertyData.Append(striter->second);
1187 wxString FinalPropValue;
1189 if (wxSPropertyXVCard4Value.IsEmpty()){
1191 FinalPropValue = wxSPropertyData;
1195 if (wxSPropertyXVCard4Value != wxSPropertyData){
1197 FinalPropValue = wxSPropertyData;
1201 FinalPropValue = wxSPropertyXVCard4Value;
1207 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
1209 wxSProperty.clear();
1210 wxSPropertySub.Clear();
1211 wxSPropertySeg1Sub.Clear();
1212 wxSPropertySeg2Sub.Clear();
1213 wxSPropertyValues.Clear();
1214 wxSPropertyData.Clear();
1215 wxSPropertyXVCard4Value.Clear();
1216 wxSPropertyNameConv.Clear();
1217 FinalPropertyData.clear();
1218 FinalPropValue.clear();
1219 PropertyData.clear();
1220 PropertyLock.clear();
1221 ContactLine.clear();
1222 XVCard4Value = FALSE;
1223 VCard3Value = FALSE;
1231 std::map<int, wxString> *ItemEraseData;
1233 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1234 iter != ItemMapIndex.end(); ++iter){
1236 ItemEraseData = (std::map<int,wxString>*)iter->second;
1238 delete ItemEraseData;
1239 ItemEraseData = NULL;
1243 ItemMapIndex.clear();
1245 vCardOut->AddRaw(wxT("END"), wxT("VCARD"));