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 std::map<int, wxString> ContactFileLines;
32 std::map<int, bool> ContactFileProcessed;
33 std::map<int, bool> ContactFileProcessedWorking;
34 std::map<int, wxString>::iterator striter;
35 std::map<int,bool>::iterator iterbool;
36 std::map<int,bool>::iterator iterboolsub;
37 wxString ContactLineRec;
39 // Process the received data.
41 wxStringTokenizer wSTContactFileLines(*wxSData, wxT("\r\n"));
43 int ContactLineSeek = 0;
45 while (wSTContactFileLines.HasMoreTokens() == TRUE){
47 ContactLineRec = wSTContactFileLines.GetNextToken();
48 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLineRec));
49 ContactFileProcessed.insert(std::make_pair(ContactLineSeek, FALSE));
54 bool QuoteMode = FALSE;
55 bool PropertyFind = TRUE;
56 bool ExtraLineSeek = TRUE;
57 bool ExtraLineSeekSub = TRUE;
58 bool BirthdayProcessed = FALSE;
59 bool AnniversaryProcessed = FALSE;
60 bool FNProcessed = FALSE;
61 bool GenderProcessed = FALSE;
62 bool NameProcessed = FALSE;
64 bool NicknameFirst = FALSE;
65 bool TitleFirst = FALSE;
66 bool OrganisationFirst = FALSE;
67 bool NoteFirst = FALSE;
68 bool PhotoFirst = FALSE;
69 bool LogoFirst = FALSE;
70 bool NameFirst = FALSE;
71 bool FoundData = FALSE;
72 int intExtraNickname = 0;
74 wxString wxSPropertyVCARD4;
75 wxString wxSPropertySeg1;
76 wxString wxSPropertySeg2;
77 wxString wxSPropertyNextLine;
79 wxString ContactLineSub;
80 wxString PropertyName;
81 wxString PropertyValue;
82 wxString PropertyDataStr;
83 size_t ContactLineLen = 0;
84 size_t ContactLineSubLen = 0;
85 int QuoteBreakPoint = 0;
86 size_t intPrevValueSub = 0;
88 std::map<wxString, wxString> PropertyData;
89 std::map<wxString, bool> PropertyLock;
90 std::map<wxString, wxString> TempPropertyData;
91 std::map<wxString, bool> TempPropertyLock;
92 std::map<int, int> TempSplitPoints;
93 std::map<int, int> TempSplitLength;
94 std::map<int, int>::iterator SLiter;
96 wxString PropertFindSub;
97 wxString wxSPropertySub;
98 wxString wxSPropertySeg1Sub;
99 wxString wxSPropertySeg2Sub;
100 wxString wxSPropertyValues;
101 wxString wxSPropertyData;
102 wxString wxSPropertyNameConv;
103 wxString wxSPropertyXVCard4Value;
104 wxString ItemProcString;
106 bool XVCard4Value = FALSE;
107 bool VCard3Value = FALSE;
108 bool SeekItemData = FALSE;
112 // Setup the version string.
114 strVer.Append(wxT("-//Xestia//Address Book Version "));
115 strVer.Append(wxT(XSDAB_VERSION));
116 strVer.Append(wxT("//KW"));
118 vCardOut->AddRaw(wxT("BEGIN"), wxT("VCARD"));
119 vCardOut->AddRaw(wxT("VERSION"), wxT("4.0"));
120 vCardOut->AddRaw(wxT("PRODID"), strVer);
129 // Process the properties which have X-FIRST.
131 // Clone the ContactFileProcessed into ContactFileProcessedWorking.
133 ContactFileProcessedWorking.insert(ContactFileProcessed.begin(), ContactFileProcessed.end());
135 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
136 iter != ContactFileLines.end(); ++iter){
138 ExtraLineSeek = TRUE;
140 iterbool = ContactFileProcessed.find(iter->first);
142 ContactLine = iter->second;
144 // Ignore certain variables as they are not needed.
146 if (ContactLine == wxT("BEGIN:VCARD") ||
147 ContactLine == wxT("END:VCARD") ||
148 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
149 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
150 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
151 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
152 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
153 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
154 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
155 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
156 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
157 ContactLine.Mid(0, 4) == wxT("REV:")){
159 iterbool->second = TRUE;
164 if (iterbool->second == TRUE){
170 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
176 if (ContactLine.Mid(0, 4) == wxT("item")){
178 // Line is a itemn... so ignore.
184 std::map<int,int> DataLineProcess;
185 std::map<int, bool>::iterator DLSLiter;
186 std::map<int,int> DataLineProcessOriginal;
187 int DataLineSeek = 0;
188 int DataLineSeekOrig = 0;
190 std::map<int,wxString>::iterator itersub = iter;
191 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterbool->first));
194 while (ExtraLineSeek == TRUE){
196 // Check if there is extra data on the next line
197 // (indicated by space or tab at the start) and add data.
201 if (itersub == ContactFileLines.end()){
207 iterboolsub = ContactFileProcessed.find(itersub->first);
209 if (iterboolsub == ContactFileProcessed.end()){
215 if (iterboolsub->second == TRUE){
221 wxSPropertyNextLine = itersub->second;
223 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
225 wxSPropertyNextLine.Remove(0, 1);
226 //wxSPropertyNextLine.Trim(FALSE);
227 //ContactLine.Trim();
228 ContactLine.Append(wxSPropertyNextLine);
229 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterboolsub->first));
231 //iterboolsub->second = TRUE;
235 ExtraLineSeek = FALSE;
241 ContactLineLen = ContactLine.Len();
243 for (int i = 0; i <= ContactLineLen; i++){
245 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
247 PropertyFind = FALSE;
249 } else if (PropertyFind == TRUE){
251 wxSProperty.Append(ContactLine.Mid(i, 1));
255 if (ContactLine.Mid(i, 1) == wxT("\"")){
257 if (QuoteMode == TRUE){
269 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
278 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
279 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
281 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
282 wxSProperty = wxSPropertySegSplit.GetNextToken();
284 // Check what type of property it is.
288 if ((wxSProperty == wxT("PHOTO") && PhotoFirst == FALSE) ||
289 (wxSProperty == wxT("NICKNAME") && NicknameFirst == FALSE) ||
290 (wxSProperty == wxT("TITLE") && TitleFirst == FALSE) ||
291 (wxSProperty == wxT("FN") && FNFirst == FALSE) ||
292 (wxSProperty == wxT("ORG") && OrganisationFirst == FALSE) ||
293 (wxSProperty == wxT("NOTE") && NoteFirst == FALSE)){
295 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
296 intPrevValueSub = (wxSPropertyVCARD4.Len() + 2);
298 for (std::map<int,wxString>::iterator itersub = ContactFileLines.begin();
299 itersub != ContactFileLines.end(); ++itersub){
301 //DataLineProcess = DataLineProcessOriginal;
302 //DataLineSeek = DataLineSeekOrig;
304 ContactLineSub = itersub->second;
306 ExtraLineSeekSub = TRUE;
308 iterboolsub = ContactFileProcessed.find(itersub->first);
309 //std::map<int,bool>::iterator iterorig = ContactFileProcessed.find(itersub->first);
310 //std::map<int,bool>::iterator itersuborig;
312 // Ignore certain variables as they are not needed.
314 if (ContactLineSub == wxT("BEGIN:VCARD") ||
315 ContactLineSub == wxT("END:VCARD") ||
316 ContactLineSub.Mid(0, 8) == wxT("VERSION:") ||
317 ContactLineSub.Mid(0, 7) == wxT("PRODID:") ||
318 ContactLineSub.Mid(0, 5) == wxT("X-AIM") ||
319 ContactLineSub.Mid(0, 5) == wxT("X-MSN") ||
320 ContactLineSub.Mid(0, 5) == wxT("X-ICQ") ||
321 ContactLineSub.Mid(0, 10) == wxT("X-GADUGADU") ||
322 ContactLineSub.Mid(0, 7) == wxT("X-YAHOO") ||
323 ContactLineSub.Mid(0, 7) == wxT("X-SKYPE") ||
324 ContactLineSub.Mid(0, 8) == wxT("X-JABBER") ||
325 ContactLineSub.Mid(0, 4) == wxT("REV:")){
327 iterboolsub->second = TRUE;
332 if (iterboolsub->second == TRUE){
338 if (ContactLineSub.Mid(0, 1) == wxT(" ") || ContactLineSub.Mid(0, 1) == wxT("\t")){
344 if (ContactLineSub.Mid(0, 4) == wxT("item")){
346 // Line is a itemn... so ignore.
352 //std::map<int,wxString>::iterator itersub = iter;
354 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
359 while (ExtraLineSeekSub == TRUE){
361 if (itersub == ContactFileLines.end()){
362 ExtraLineSeekSub = FALSE;
369 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
371 wxSPropertyNextLine = itersub->second;
373 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
375 wxSPropertyNextLine.Remove(0, 1);
376 //wxSPropertyNextLine.Trim(FALSE);
377 //ContactLine.Trim();
378 ContactLineSub.Append(wxSPropertyNextLine);
379 //iterboolsub->second = TRUE;
380 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
386 ExtraLineSeekSub = FALSE;
392 /*while (ExtraLineSeekSub == TRUE && iterboolsub != ContactFileProcessedWorking.end()){
394 // Check if there is extra data on the next line
395 // (indicated by space or tab at the start) and add data.
399 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
401 if (iterboolsub->second == TRUE){
407 if (itersub == ContactFileLines.end()){
413 wxSPropertyNextLine = itersub->second;
415 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
417 wxSPropertyNextLine.Remove(0, 1);
418 //wxSPropertyNextLine.Trim(FALSE);
419 //ContactLine.Trim();
420 ContactLineSub.Append(wxSPropertyNextLine);
421 //iterboolsub->second = TRUE;
422 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
428 ExtraLineSeekSub = FALSE;
432 if (iterboolsub == ContactFileProcessedWorking.end()){
435 ExtraLineSeekSub = FALSE;
441 ContactLineSubLen = ContactLineSub.Len();
443 wxSPropertySub.clear();
445 for (int i = 0; i <= ContactLineSubLen; i++){
447 if ((ContactLineSub.Mid(i, 1) == wxT(";") || ContactLineSub.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
449 PropertyFind = FALSE;
451 } else if (PropertyFind == TRUE){
453 wxSPropertySub.Append(ContactLineSub.Mid(i, 1));
457 if (ContactLineSub.Mid(i, 1) == wxT("\"")){
459 if (QuoteMode == TRUE){
471 if (ContactLineSub.Mid(i, 1) == wxT(":") && ContactLineSub.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
480 if (wxSPropertySub != wxSPropertyVCARD4){
482 wxSPropertySub.clear();
484 DataLineProcess.clear();
489 wxSPropertySeg1Sub = ContactLineSub.Mid(0, QuoteBreakPoint);
490 wxSPropertySeg2Sub = ContactLineSub.Mid((QuoteBreakPoint + 1));
492 // Split the property name data.
494 // Strip the X-VCARD4- from the variable.
496 wxString wxSPropertyChopped = wxSPropertySeg1Sub.Mid(9);
498 intPrevValueSub = (wxSProperty.Len() + 2);
500 SplitValuesData(&wxSPropertyChopped, &TempSplitPoints, &TempSplitLength, (int)intPrevValueSub, &TempPropertyData);
502 // Process the splitted data into temporary property data.
504 // Look for certain property names and the X-FIRST
507 bool ProcessData = FALSE;
509 // Check for X-FIRST.
511 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
512 xfiter != TempPropertyData.end(); ++xfiter){
514 PropertyName = xfiter->first;
515 PropertyValue = xfiter->second;
517 if (PropertyName == wxT("X-FIRST") && PropertyValue == wxT("TRUE")){
521 if (wxSProperty == wxT("PHOTO")){ PhotoFirst = TRUE; }
522 else if (wxSProperty == wxT("NICKNAME")){ NicknameFirst = TRUE; }
523 else if (wxSProperty == wxT("TITLE")){ TitleFirst = TRUE; }
524 else if (wxSProperty == wxT("FN")){ FNFirst = TRUE; }
525 else if (wxSProperty == wxT("ORG")){ OrganisationFirst = TRUE; }
526 else if (wxSProperty == wxT("NOTE")){ NoteFirst = TRUE; }
533 if (ProcessData == FALSE){
535 DataLineProcess.clear();
537 TempPropertyData.clear();
541 wxT("PHOTODANCEMATCH!");
543 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
544 xfiter != TempPropertyData.end(); ++xfiter){
546 PropertyName = xfiter->first;
547 PropertyValue = xfiter->second;
549 if (PropertyName == wxT("X-FIRST")){
555 PropertyData.insert(std::make_pair(PropertyName, PropertyValue));
556 PropertyLock.insert(std::make_pair(PropertyName, FALSE));
560 // Mark all lines as processed.
562 for (std::map<int,int>::iterator dpiter = DataLineProcess.begin();
563 dpiter != DataLineProcess.end(); ++dpiter){
565 DLSLiter = ContactFileProcessed.find(dpiter->second);
566 DLSLiter->second = TRUE;
570 for (std::map<int,int>::iterator dpoiter = DataLineProcessOriginal.begin();
571 dpoiter != DataLineProcessOriginal.end(); ++dpoiter){
573 DLSLiter = ContactFileProcessed.find(dpoiter->second);
574 DLSLiter->second = TRUE;
578 DataLineProcess.clear();
579 DataLineProcessOriginal.clear();
581 DataLineSeekOrig = 0;
582 TempSplitPoints.clear();
583 TempSplitLength.clear();
584 TempPropertyData.clear();
596 wxSPropertySub.Clear();
597 wxSPropertySeg1.Clear();
598 wxSPropertySeg2.Clear();
599 wxSPropertySeg1Sub.Clear();
600 wxSPropertySeg2Sub.Clear();
601 wxSPropertyValues.Clear();
602 wxSPropertyData.Clear();
603 wxSPropertyXVCard4Value.Clear();
604 wxSPropertyNameConv.Clear();
605 PropertyData.clear();
606 PropertyLock.clear();
608 ContactLineSub.clear();
609 DataLineProcess.clear();
610 DataLineProcessOriginal.clear();
611 TempSplitPoints.clear();
612 TempSplitLength.clear();
613 wxSPropertyVCARD4.clear();
615 DataLineSeekOrig = 0;
616 XVCard4Value = FALSE;
621 if (FoundData == FALSE){
624 wxSPropertySub.Clear();
625 wxSPropertySeg1.Clear();
626 wxSPropertySeg2.Clear();
627 wxSPropertySeg1Sub.Clear();
628 wxSPropertySeg2Sub.Clear();
629 wxSPropertyValues.Clear();
630 wxSPropertyData.Clear();
631 wxSPropertyXVCard4Value.Clear();
632 wxSPropertyNameConv.Clear();
633 PropertyData.clear();
634 PropertyLock.clear();
636 ContactLineSub.clear();
637 DataLineProcess.clear();
638 DataLineProcessOriginal.clear();
639 TempSplitPoints.clear();
640 TempSplitLength.clear();
641 wxSPropertyVCARD4.clear();
643 DataLineSeekOrig = 0;
644 XVCard4Value = FALSE;
649 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
650 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
651 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
653 wxString FinalPropertyData;
655 FinalPropertyData.Append(wxSPropertyNameConv);
657 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
658 striter != PropertyData.end(); ++striter){
660 FinalPropertyData.Append(wxT(";"));
661 FinalPropertyData.Append(striter->first);
662 FinalPropertyData.Append(wxT("="));
663 FinalPropertyData.Append(striter->second);
667 wxString FinalPropValue;
669 if (wxSPropertyXVCard4Value.IsEmpty()){
671 FinalPropValue = wxSPropertyData;
675 if (wxSPropertyXVCard4Value != wxSPropertyData){
677 FinalPropValue = wxSPropertyXVCard4Value;
683 if (FinalPropertyData.IsEmpty() && FinalPropValue.IsEmpty()){
689 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
692 wxSPropertySub.Clear();
693 wxSPropertySeg1.Clear();
694 wxSPropertySeg2.Clear();
695 wxSPropertySeg1Sub.Clear();
696 wxSPropertySeg2Sub.Clear();
697 wxSPropertyValues.Clear();
698 wxSPropertyData.Clear();
699 wxSPropertyXVCard4Value.Clear();
700 wxSPropertyNameConv.Clear();
701 //FinalPropertyData.clear();
702 //FinalPropValue.clear();
703 PropertyData.clear();
704 PropertyLock.clear();
706 ContactLineSub.clear();
707 DataLineProcess.clear();
708 DataLineProcessOriginal.clear();
709 wxSPropertyVCARD4.clear();
711 DataLineSeekOrig = 0;
712 XVCard4Value = FALSE;
717 // Process the non-itemn values.
719 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
720 iter != ContactFileLines.end(); ++iter){
722 ExtraLineSeek = TRUE;
724 iterbool = ContactFileProcessed.find(iter->first);
726 ContactLine = iter->second;
728 // Ignore certain variables as they are not needed.
730 if (ContactLine == wxT("BEGIN:VCARD") ||
731 ContactLine == wxT("END:VCARD") ||
732 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
733 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
734 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
735 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
736 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
737 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
738 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
739 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
740 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
741 ContactLine.Mid(0, 4) == wxT("REV:")){
743 iterbool->second = TRUE;
748 if (iterbool->second == TRUE){
754 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
760 if (ContactLine.Mid(0, 4) == wxT("item")){
762 // Line is a itemn... so ignore.
768 std::map<int,wxString>::iterator itersub = iter;
770 while (ExtraLineSeek == TRUE){
772 // Check if there is extra data on the next line
773 // (indicated by space or tab at the start) and add data.
775 if (itersub == ContactFileLines.end()){
776 ExtraLineSeekSub = FALSE;
784 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
786 if (iterboolsub == ContactFileProcessedWorking.end()){
792 if (iterboolsub->second == TRUE){
798 if (itersub == ContactFileLines.end()){
804 wxSPropertyNextLine = itersub->second;
806 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
808 wxSPropertyNextLine.Remove(0, 1);
809 //wxSPropertyNextLine.Trim(FALSE);
810 //ContactLine.Trim();
811 ContactLine.Append(wxSPropertyNextLine);
812 iterboolsub->second = TRUE;
816 ExtraLineSeek = FALSE;
822 ContactLineLen = ContactLine.Len();
824 for (int i = 0; i <= ContactLineLen; i++){
826 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
828 PropertyFind = FALSE;
830 } else if (PropertyFind == TRUE){
832 wxSProperty.Append(ContactLine.Mid(i, 1));
836 if (ContactLine.Mid(i, 1) == wxT("\"")){
838 if (QuoteMode == TRUE){
850 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
859 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
860 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
862 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
863 wxSProperty = wxSPropertySegSplit.GetNextToken();
865 std::map<int,int> DataLineProcess;
866 std::map<int, bool>::iterator DLSLiter;
868 // Look for the X-VCARD4-(variablename) equivilant.
870 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
872 // Sort out remainder of the types.
874 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
875 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
876 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
878 wxString FinalPropertyData;
880 FinalPropertyData.Append(wxSPropertyNameConv);
882 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
883 striter != PropertyData.end(); ++striter){
885 FinalPropertyData.Append(wxT(";"));
886 FinalPropertyData.Append(striter->first);
887 FinalPropertyData.Append(wxT("="));
888 FinalPropertyData.Append(striter->second);
892 wxString FinalPropValue;
894 if (wxSPropertyXVCard4Value.IsEmpty()){
896 FinalPropValue = wxSPropertyData;
900 if (wxSPropertyXVCard4Value != wxSPropertyData){
902 FinalPropValue = wxSPropertyXVCard4Value;
908 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
911 wxSPropertySub.Clear();
912 wxSPropertySeg1.Clear();
913 wxSPropertySeg2.Clear();
914 wxSPropertyValues.Clear();
915 wxSPropertyData.Clear();
916 wxSPropertyXVCard4Value.Clear();
917 wxSPropertyNameConv.Clear();
918 //FinalPropertyData.clear();
919 //FinalPropValue.clear();
920 PropertyData.clear();
921 PropertyLock.clear();
923 XVCard4Value = FALSE;
930 int NicknameCount = 0;
939 int RelatedCount = 0;
944 int CategoryCount = 0;
949 int CalReqAdrCount = 0;
950 int FreeBusyCount = 0;
955 int MaxItemNumber = 0;
957 int ItemUnordered = 0;
959 size_t ItemStringSeekLen = 0;
961 int ItemSeekSecSub = 0;
962 //int intValueSeek = 1;
964 std::map<int, wxString> NumberedName;
965 std::map<int, wxString> NumberedData;
966 std::map<int, wxString> NumberedPropValues;
967 std::map<int, wxString> NumberedPropOldValue;
969 std::map<int, wxString> UnNumberedName;
970 std::map<int, wxString> UnNumberedData;
971 std::map<int, wxString> UnNumberedPropValues;
972 std::map<int, wxString> UnNumberedPropOldValue;
974 // Part 1: Get the itemn number.
976 std::map<int,bool>::iterator iterboolsecsub;
977 std::map<int,wxString>::iterator itersub;
978 std::map<int, wxString> TempData;
979 PropertyData.clear();
980 PropertyLock.clear();
982 wxString ItemStringSeek;
983 wxString ItemPropName;
986 ContactLineSub.clear();
987 ExtraLineSeekSub = 0;
988 wxString wxSPropertyNextLineSub;
989 ContactLineSubLen = 0;
991 PropertFindSub.clear();
992 wxSPropertySub.clear();
993 wxSPropertySeg1Sub.clear();
994 wxSPropertySeg2Sub.clear();
995 wxSPropertyValues.clear();
996 wxSPropertyData.clear();
997 wxSPropertyNameConv.clear();
998 wxSPropertyXVCard4Value.clear();
999 ItemProcString.clear();
1001 XVCard4Value = FALSE;
1002 VCard3Value = FALSE;
1003 SeekItemData = FALSE;
1005 std::map<wxString, void*> ItemMapIndex;
1006 //std::map<wxString, wxString> ItemNameIndex;
1008 // Look for item in the initial line, process into a proper line then
1009 // look for other lines with the same item association.
1011 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
1012 iter != ContactFileLines.end(); ++iter){
1014 ExtraLineSeek = TRUE;
1016 iterbool = ContactFileProcessed.find(iter->first);
1018 if (iterbool->second == TRUE){
1024 ContactLine = iter->second;
1026 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
1032 if (ContactLine.Mid(0, 4) != wxT("item")){
1040 //ContactLineSeekSub = ContactLineSeek;
1041 std::map<int,wxString>::iterator itersub = iter;
1043 while (ExtraLineSeek == TRUE){
1045 // Check if there is extra data on the next line
1046 // (indicated by space or tab at the start) and add data.
1049 iterboolsub = ContactFileProcessed.find(itersub->first);
1051 if (iterboolsub == ContactFileProcessed.end()){
1057 if (iterboolsub->second == TRUE){
1063 if (itersub == ContactFileLines.end()){
1069 wxSPropertyNextLine = itersub->second;
1071 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1073 wxSPropertyNextLine.Remove(0, 1);
1074 //wxSPropertyNextLine.Trim(FALSE);
1075 //ContactLine.Trim();
1076 ContactLine.Append(wxSPropertyNextLine);
1077 iterboolsub->second = TRUE;
1081 ExtraLineSeek = FALSE;
1087 ContactLineLen = ContactLine.Len();
1089 for (int i = 0; i <= ContactLineLen; i++){
1091 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1093 PropertyFind = FALSE;
1095 } else if (PropertyFind == TRUE){
1097 wxSProperty.Append(ContactLine.Mid(i, 1));
1101 if (ContactLine.Mid(i, 1) == wxT("\"")){
1103 if (QuoteMode == TRUE){
1115 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1117 QuoteBreakPoint = i;
1124 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1125 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1127 // Go through the lines and collect the lines like itemn.
1129 std::map<int,wxString> *ItemListData;
1130 ItemListData = new std::map<int,wxString>;
1132 wxStringTokenizer ItemData(wxSPropertySeg1, wxT("."));
1134 ItemString = ItemData.GetNextToken();
1135 ItemStringSeek = wxT("item") + ItemString.Mid(4);
1137 wxStringTokenizer ItemPropSplit(ItemData.GetNextToken(), wxT(";"));
1139 ItemPropName = ItemPropSplit.GetNextToken();
1141 ItemStringSeekLen = ItemStringSeek.Len();
1145 for (std::map<int,wxString>::iterator itersec = ContactFileLines.begin();
1146 itersec != ContactFileLines.end(); ++itersec){
1148 ExtraLineSeek = TRUE;
1150 iterboolsub = ContactFileProcessed.find(itersec->first);
1152 if (iterboolsub->second == TRUE){
1158 ContactLineSub = itersec->second;
1160 wxStringTokenizer ItemProcData(ContactLineSub, wxT("."));
1161 ItemProcString = ItemData.GetNextToken();
1163 if (ItemStringSeek != ContactLineSub.Mid(0, ItemStringSeekLen)){
1171 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1173 iterboolsub->second = TRUE;
1177 //ItemNameIndex.insert(std::make_pair(ItemStringSeek, ItemPropName));
1178 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1179 ItemMapIndex.insert(std::make_pair(ItemStringSeek, ItemListData));
1183 // Process each itemn set.
1185 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1186 iter != ItemMapIndex.end(); ++iter){
1188 std::map<int, wxString> *ItemDataPtr;
1190 ItemDataPtr = (std::map<int,wxString>*)iter->second;
1192 for (std::map<int,wxString>::iterator itersub = ItemDataPtr->begin();
1193 itersub != ItemDataPtr->end(); ++itersub){
1195 ContactLine = itersub->second;
1197 ContactLineLen = ContactLine.Len();
1199 for (int i = 0; i <= ContactLineLen; i++){
1201 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1203 PropertyFind = FALSE;
1205 } else if (PropertyFind == TRUE){
1207 wxSProperty.Append(ContactLine.Mid(i, 1));
1211 if (ContactLine.Mid(i, 1) == wxT("\"")){
1213 if (QuoteMode == TRUE){
1225 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1227 QuoteBreakPoint = i;
1234 wxSPropertySeg1Sub = ContactLine.Mid(0, QuoteBreakPoint);
1235 wxSPropertySeg2Sub = ContactLine.Mid((QuoteBreakPoint + 1));
1237 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1Sub, wxT(";"));
1238 wxSProperty = wxSPropertySegSplit.GetNextToken();
1240 // Sort out remainder of the types.
1242 // Skip certain X-* IM variables as they are processed via
1245 if (wxSProperty == wxT("X-AIM") || wxSProperty == wxT("X-MSN") ||
1246 wxSProperty == wxT("X-ICQ") || wxSProperty == wxT("X-GADUGADU") ||
1247 wxSProperty == wxT("X-YAHOO") || wxSProperty == wxT("X-SKYPE") ||
1248 wxSProperty == wxT("X-JABBER")){
1250 wxSProperty.clear();
1251 wxSPropertySub.Clear();
1252 wxSPropertySeg1.Clear();
1253 wxSPropertySeg2.Clear();
1254 wxSPropertyValues.Clear();
1255 wxSPropertyData.Clear();
1256 wxSPropertyXVCard4Value.Clear();
1257 wxSPropertyNameConv.Clear();
1258 //FinalPropertyData.clear();
1259 //FinalPropValue.clear();
1260 PropertyData.clear();
1261 PropertyLock.clear();
1262 ContactLine.clear();
1263 XVCard4Value = FALSE;
1264 VCard3Value = FALSE;
1269 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1Sub, &wxSPropertySeg2Sub,
1270 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
1271 &wxSPropertyNameConv, &PropertyData, &PropertyLock, TRUE, &VCard3Value, &XVCard4Value);
1275 if (wxSPropertyNameConv.IsEmpty()){
1277 wxSProperty.clear();
1278 wxSPropertySub.Clear();
1279 wxSPropertySeg1.Clear();
1280 wxSPropertySeg2.Clear();
1281 wxSPropertyValues.Clear();
1282 wxSPropertyData.Clear();
1283 wxSPropertyXVCard4Value.Clear();
1284 wxSPropertyNameConv.Clear();
1285 //FinalPropertyData.clear();
1286 //FinalPropValue.clear();
1287 PropertyData.clear();
1288 PropertyLock.clear();
1289 ContactLine.clear();
1290 XVCard4Value = FALSE;
1291 VCard3Value = FALSE;
1296 wxString FinalPropertyData;
1298 FinalPropertyData.Append(wxSPropertyNameConv);
1300 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
1301 striter != PropertyData.end(); ++striter){
1303 FinalPropertyData.Append(wxT(";"));
1304 FinalPropertyData.Append(striter->first);
1305 FinalPropertyData.Append(wxT("="));
1306 FinalPropertyData.Append(striter->second);
1310 wxString FinalPropValue;
1312 if (wxSPropertyXVCard4Value.IsEmpty()){
1314 FinalPropValue = wxSPropertyData;
1318 if (wxSPropertyXVCard4Value != wxSPropertyData){
1320 FinalPropValue = wxSPropertyData;
1324 FinalPropValue = wxSPropertyXVCard4Value;
1330 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
1332 wxSProperty.clear();
1333 wxSPropertySub.Clear();
1334 wxSPropertySeg1Sub.Clear();
1335 wxSPropertySeg2Sub.Clear();
1336 wxSPropertyValues.Clear();
1337 wxSPropertyData.Clear();
1338 wxSPropertyXVCard4Value.Clear();
1339 wxSPropertyNameConv.Clear();
1340 FinalPropertyData.clear();
1341 FinalPropValue.clear();
1342 PropertyData.clear();
1343 PropertyLock.clear();
1344 ContactLine.clear();
1345 XVCard4Value = FALSE;
1346 VCard3Value = FALSE;
1349 //PropertyData.clear();
1350 //PropertyLock.clear();
1356 std::map<int, wxString> *ItemEraseData;
1358 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1359 iter != ItemMapIndex.end(); ++iter){
1361 ItemEraseData = (std::map<int,wxString>*)iter->second;
1363 delete ItemEraseData;
1364 ItemEraseData = NULL;
1368 ItemMapIndex.clear();
1370 vCardOut->AddRaw(wxT("END"), wxT("VCARD"));