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;
60 bool BirthdayProcessed = FALSE;
61 bool AnniversaryProcessed = FALSE;
62 bool FNProcessed = FALSE;
63 bool GenderProcessed = FALSE;
64 bool NameProcessed = FALSE;
66 bool NicknameFirst = FALSE;
67 bool TitleFirst = FALSE;
68 bool OrganisationFirst = FALSE;
69 bool NoteFirst = FALSE;
70 bool PhotoFirst = FALSE;
71 bool LogoFirst = FALSE;
72 bool NameFirst = FALSE;
73 bool FoundData = FALSE;
74 int intExtraNickname = 0;
76 wxString wxSPropertyVCARD4;
77 wxString wxSPropertySeg1;
78 wxString wxSPropertySeg2;
79 wxString wxSPropertyNextLine;
81 wxString ContactLineSub;
82 wxString PropertyName;
83 wxString PropertyValue;
84 wxString PropertyDataStr;
85 size_t ContactLineLen = 0;
86 size_t ContactLineSubLen = 0;
87 int QuoteBreakPoint = 0;
88 size_t intPrevValueSub = 0;
90 std::map<wxString, wxString> PropertyData;
91 std::map<wxString, bool> PropertyLock;
92 std::map<wxString, wxString> TempPropertyData;
93 std::map<wxString, bool> TempPropertyLock;
94 std::map<int, int> TempSplitPoints;
95 std::map<int, int> TempSplitLength;
96 std::map<int, int>::iterator SLiter;
98 wxString PropertFindSub;
99 wxString wxSPropertySub;
100 wxString wxSPropertySeg1Sub;
101 wxString wxSPropertySeg2Sub;
102 wxString wxSPropertyValues;
103 wxString wxSPropertyData;
104 wxString wxSPropertyNameConv;
105 wxString wxSPropertyXVCard4Value;
106 wxString ItemProcString;
108 bool XVCard4Value = FALSE;
109 bool VCard3Value = FALSE;
110 bool SeekItemData = FALSE;
114 // Setup the version string.
116 strVer.Append(wxT("-//Xestia//Address Book Version "));
117 strVer.Append(wxT(XSDAB_VERSION));
118 strVer.Append(wxT("//KW"));
120 vCardOut->AddRaw(wxT("BEGIN"), wxT("VCARD"));
121 vCardOut->AddRaw(wxT("VERSION"), wxT("4.0"));
122 vCardOut->AddRaw(wxT("PRODID"), strVer);
131 // Process the properties which have X-FIRST.
133 // Clone the ContactFileProcessed into ContactFileProcessedWorking.
135 ContactFileProcessedWorking.insert(ContactFileProcessed.begin(), ContactFileProcessed.end());
137 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
138 iter != ContactFileLines.end(); ++iter){
140 ExtraLineSeek = TRUE;
142 iterbool = ContactFileProcessed.find(iter->first);
144 ContactLine = iter->second;
146 // Ignore certain variables as they are not needed.
148 if (ContactLine == wxT("BEGIN:VCARD") ||
149 ContactLine == wxT("END:VCARD") ||
150 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
151 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
152 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
153 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
154 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
155 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
156 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
157 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
158 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
159 ContactLine.Mid(0, 4) == wxT("REV:")){
161 iterbool->second = TRUE;
166 if (iterbool->second == TRUE){
172 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
178 if (ContactLine.Mid(0, 4) == wxT("item")){
180 // Line is a itemn... so ignore.
186 std::map<int,int> DataLineProcess;
187 std::map<int, bool>::iterator DLSLiter;
188 std::map<int,int> DataLineProcessOriginal;
189 int DataLineSeek = 0;
190 int DataLineSeekOrig = 0;
192 std::map<int,wxString>::iterator itersub = iter;
193 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterbool->first));
196 while (ExtraLineSeek == TRUE){
198 // Check if there is extra data on the next line
199 // (indicated by space or tab at the start) and add data.
203 if (itersub == ContactFileLines.end()){
209 iterboolsub = ContactFileProcessed.find(itersub->first);
211 if (iterboolsub == ContactFileProcessed.end()){
217 if (iterboolsub->second == TRUE){
223 wxSPropertyNextLine = itersub->second;
225 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
227 wxSPropertyNextLine.Remove(0, 1);
228 //wxSPropertyNextLine.Trim(FALSE);
229 //ContactLine.Trim();
230 ContactLine.Append(wxSPropertyNextLine);
231 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterboolsub->first));
233 //iterboolsub->second = TRUE;
237 ExtraLineSeek = FALSE;
243 ContactLineLen = ContactLine.Len();
245 for (int i = 0; i <= ContactLineLen; i++){
247 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
249 PropertyFind = FALSE;
251 } else if (PropertyFind == TRUE){
253 wxSProperty.Append(ContactLine.Mid(i, 1));
257 if (ContactLine.Mid(i, 1) == wxT("\"")){
259 if (QuoteMode == TRUE){
271 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
280 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
281 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
283 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
284 wxSProperty = wxSPropertySegSplit.GetNextToken();
286 // Check what type of property it is.
290 if ((wxSProperty == wxT("PHOTO") && PhotoFirst == FALSE) ||
291 (wxSProperty == wxT("NICKNAME") && NicknameFirst == FALSE) ||
292 (wxSProperty == wxT("TITLE") && TitleFirst == FALSE) ||
293 (wxSProperty == wxT("FN") && FNFirst == FALSE) ||
294 (wxSProperty == wxT("ORG") && OrganisationFirst == FALSE) ||
295 (wxSProperty == wxT("NOTE") && NoteFirst == FALSE)){
297 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
298 intPrevValueSub = (wxSPropertyVCARD4.Len() + 2);
300 for (std::map<int,wxString>::iterator itersub = ContactFileLines.begin();
301 itersub != ContactFileLines.end(); ++itersub){
303 //DataLineProcess = DataLineProcessOriginal;
304 //DataLineSeek = DataLineSeekOrig;
306 ContactLineSub = itersub->second;
308 ExtraLineSeekSub = TRUE;
310 iterboolsub = ContactFileProcessed.find(itersub->first);
311 //std::map<int,bool>::iterator iterorig = ContactFileProcessed.find(itersub->first);
312 //std::map<int,bool>::iterator itersuborig;
314 // Ignore certain variables as they are not needed.
316 if (ContactLineSub == wxT("BEGIN:VCARD") ||
317 ContactLineSub == wxT("END:VCARD") ||
318 ContactLineSub.Mid(0, 8) == wxT("VERSION:") ||
319 ContactLineSub.Mid(0, 7) == wxT("PRODID:") ||
320 ContactLineSub.Mid(0, 5) == wxT("X-AIM") ||
321 ContactLineSub.Mid(0, 5) == wxT("X-MSN") ||
322 ContactLineSub.Mid(0, 5) == wxT("X-ICQ") ||
323 ContactLineSub.Mid(0, 10) == wxT("X-GADUGADU") ||
324 ContactLineSub.Mid(0, 7) == wxT("X-YAHOO") ||
325 ContactLineSub.Mid(0, 7) == wxT("X-SKYPE") ||
326 ContactLineSub.Mid(0, 8) == wxT("X-JABBER") ||
327 ContactLineSub.Mid(0, 4) == wxT("REV:")){
329 iterboolsub->second = TRUE;
334 if (iterboolsub->second == TRUE){
340 if (ContactLineSub.Mid(0, 1) == wxT(" ") || ContactLineSub.Mid(0, 1) == wxT("\t")){
346 if (ContactLineSub.Mid(0, 4) == wxT("item")){
348 // Line is a itemn... so ignore.
354 //std::map<int,wxString>::iterator itersub = iter;
356 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
361 while (ExtraLineSeekSub == TRUE){
363 if (itersub == ContactFileLines.end()){
364 ExtraLineSeekSub = FALSE;
371 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
373 wxSPropertyNextLine = itersub->second;
375 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
377 wxSPropertyNextLine.Remove(0, 1);
378 //wxSPropertyNextLine.Trim(FALSE);
379 //ContactLine.Trim();
380 ContactLineSub.Append(wxSPropertyNextLine);
381 //iterboolsub->second = TRUE;
382 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
388 ExtraLineSeekSub = FALSE;
394 /*while (ExtraLineSeekSub == TRUE && iterboolsub != ContactFileProcessedWorking.end()){
396 // Check if there is extra data on the next line
397 // (indicated by space or tab at the start) and add data.
401 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
403 if (iterboolsub->second == TRUE){
409 if (itersub == ContactFileLines.end()){
415 wxSPropertyNextLine = itersub->second;
417 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
419 wxSPropertyNextLine.Remove(0, 1);
420 //wxSPropertyNextLine.Trim(FALSE);
421 //ContactLine.Trim();
422 ContactLineSub.Append(wxSPropertyNextLine);
423 //iterboolsub->second = TRUE;
424 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
430 ExtraLineSeekSub = FALSE;
434 if (iterboolsub == ContactFileProcessedWorking.end()){
437 ExtraLineSeekSub = FALSE;
443 ContactLineSubLen = ContactLineSub.Len();
445 wxSPropertySub.clear();
447 for (int i = 0; i <= ContactLineSubLen; i++){
449 if ((ContactLineSub.Mid(i, 1) == wxT(";") || ContactLineSub.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
451 PropertyFind = FALSE;
453 } else if (PropertyFind == TRUE){
455 wxSPropertySub.Append(ContactLineSub.Mid(i, 1));
459 if (ContactLineSub.Mid(i, 1) == wxT("\"")){
461 if (QuoteMode == TRUE){
473 if (ContactLineSub.Mid(i, 1) == wxT(":") && ContactLineSub.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
482 if (wxSPropertySub != wxSPropertyVCARD4){
484 wxSPropertySub.clear();
486 DataLineProcess.clear();
491 wxSPropertySeg1Sub = ContactLineSub.Mid(0, QuoteBreakPoint);
492 wxSPropertySeg2Sub = ContactLineSub.Mid((QuoteBreakPoint + 1));
494 // Split the property name data.
496 // Strip the X-VCARD4- from the variable.
498 wxString wxSPropertyChopped = wxSPropertySeg1Sub.Mid(9);
500 intPrevValueSub = (wxSProperty.Len() + 2);
502 SplitValuesData(&wxSPropertyChopped, &TempSplitPoints, &TempSplitLength, (int)intPrevValueSub, &TempPropertyData);
504 // Process the splitted data into temporary property data.
506 // Look for certain property names and the X-FIRST
509 bool ProcessData = FALSE;
511 // Check for X-FIRST.
513 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
514 xfiter != TempPropertyData.end(); ++xfiter){
516 PropertyName = xfiter->first;
517 PropertyValue = xfiter->second;
519 if (PropertyName == wxT("X-FIRST") && PropertyValue == wxT("TRUE")){
523 if (wxSProperty == wxT("PHOTO")){ PhotoFirst = TRUE; }
524 else if (wxSProperty == wxT("NICKNAME")){ NicknameFirst = TRUE; }
525 else if (wxSProperty == wxT("TITLE")){ TitleFirst = TRUE; }
526 else if (wxSProperty == wxT("FN")){ FNFirst = TRUE; }
527 else if (wxSProperty == wxT("ORG")){ OrganisationFirst = TRUE; }
528 else if (wxSProperty == wxT("NOTE")){ NoteFirst = TRUE; }
535 if (ProcessData == FALSE){
537 DataLineProcess.clear();
539 TempPropertyData.clear();
543 wxT("PHOTODANCEMATCH!");
545 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
546 xfiter != TempPropertyData.end(); ++xfiter){
548 PropertyName = xfiter->first;
549 PropertyValue = xfiter->second;
551 if (PropertyName == wxT("X-FIRST")){
557 PropertyData.insert(std::make_pair(PropertyName, PropertyValue));
558 PropertyLock.insert(std::make_pair(PropertyName, FALSE));
562 // Mark all lines as processed.
564 for (std::map<int,int>::iterator dpiter = DataLineProcess.begin();
565 dpiter != DataLineProcess.end(); ++dpiter){
567 DLSLiter = ContactFileProcessed.find(dpiter->second);
568 DLSLiter->second = TRUE;
572 for (std::map<int,int>::iterator dpoiter = DataLineProcessOriginal.begin();
573 dpoiter != DataLineProcessOriginal.end(); ++dpoiter){
575 DLSLiter = ContactFileProcessed.find(dpoiter->second);
576 DLSLiter->second = TRUE;
580 DataLineProcess.clear();
581 DataLineProcessOriginal.clear();
583 DataLineSeekOrig = 0;
584 TempSplitPoints.clear();
585 TempSplitLength.clear();
586 TempPropertyData.clear();
598 wxSPropertySub.Clear();
599 wxSPropertySeg1.Clear();
600 wxSPropertySeg2.Clear();
601 wxSPropertySeg1Sub.Clear();
602 wxSPropertySeg2Sub.Clear();
603 wxSPropertyValues.Clear();
604 wxSPropertyData.Clear();
605 wxSPropertyXVCard4Value.Clear();
606 wxSPropertyNameConv.Clear();
607 PropertyData.clear();
608 PropertyLock.clear();
610 ContactLineSub.clear();
611 DataLineProcess.clear();
612 DataLineProcessOriginal.clear();
613 TempSplitPoints.clear();
614 TempSplitLength.clear();
615 wxSPropertyVCARD4.clear();
617 DataLineSeekOrig = 0;
618 XVCard4Value = FALSE;
623 if (FoundData == FALSE){
626 wxSPropertySub.Clear();
627 wxSPropertySeg1.Clear();
628 wxSPropertySeg2.Clear();
629 wxSPropertySeg1Sub.Clear();
630 wxSPropertySeg2Sub.Clear();
631 wxSPropertyValues.Clear();
632 wxSPropertyData.Clear();
633 wxSPropertyXVCard4Value.Clear();
634 wxSPropertyNameConv.Clear();
635 PropertyData.clear();
636 PropertyLock.clear();
638 ContactLineSub.clear();
639 DataLineProcess.clear();
640 DataLineProcessOriginal.clear();
641 TempSplitPoints.clear();
642 TempSplitLength.clear();
643 wxSPropertyVCARD4.clear();
645 DataLineSeekOrig = 0;
646 XVCard4Value = FALSE;
651 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
652 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
653 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
655 wxString FinalPropertyData;
657 FinalPropertyData.Append(wxSPropertyNameConv);
659 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
660 striter != PropertyData.end(); ++striter){
662 FinalPropertyData.Append(wxT(";"));
663 FinalPropertyData.Append(striter->first);
664 FinalPropertyData.Append(wxT("="));
665 FinalPropertyData.Append(striter->second);
669 wxString FinalPropValue;
671 if (wxSPropertyXVCard4Value.IsEmpty()){
673 FinalPropValue = wxSPropertyData;
677 if (wxSPropertyXVCard4Value != wxSPropertyData){
679 FinalPropValue = wxSPropertyXVCard4Value;
685 if (FinalPropertyData.IsEmpty() && FinalPropValue.IsEmpty()){
691 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
694 wxSPropertySub.Clear();
695 wxSPropertySeg1.Clear();
696 wxSPropertySeg2.Clear();
697 wxSPropertySeg1Sub.Clear();
698 wxSPropertySeg2Sub.Clear();
699 wxSPropertyValues.Clear();
700 wxSPropertyData.Clear();
701 wxSPropertyXVCard4Value.Clear();
702 wxSPropertyNameConv.Clear();
703 //FinalPropertyData.clear();
704 //FinalPropValue.clear();
705 PropertyData.clear();
706 PropertyLock.clear();
708 ContactLineSub.clear();
709 DataLineProcess.clear();
710 DataLineProcessOriginal.clear();
711 wxSPropertyVCARD4.clear();
713 DataLineSeekOrig = 0;
714 XVCard4Value = FALSE;
719 // Process the non-itemn values.
721 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
722 iter != ContactFileLines.end(); ++iter){
724 ExtraLineSeek = TRUE;
726 iterbool = ContactFileProcessed.find(iter->first);
728 ContactLine = iter->second;
730 // Ignore certain variables as they are not needed.
732 if (ContactLine == wxT("BEGIN:VCARD") ||
733 ContactLine == wxT("END:VCARD") ||
734 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
735 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
736 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
737 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
738 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
739 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
740 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
741 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
742 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
743 ContactLine.Mid(0, 4) == wxT("REV:")){
745 iterbool->second = TRUE;
750 if (iterbool->second == TRUE){
756 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
762 if (ContactLine.Mid(0, 4) == wxT("item")){
764 // Line is a itemn... so ignore.
770 std::map<int,wxString>::iterator itersub = iter;
772 while (ExtraLineSeek == TRUE){
774 // Check if there is extra data on the next line
775 // (indicated by space or tab at the start) and add data.
777 if (itersub == ContactFileLines.end()){
778 ExtraLineSeekSub = FALSE;
786 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
788 if (iterboolsub == ContactFileProcessedWorking.end()){
794 if (iterboolsub->second == TRUE){
800 if (itersub == ContactFileLines.end()){
806 wxSPropertyNextLine = itersub->second;
808 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
810 wxSPropertyNextLine.Remove(0, 1);
811 //wxSPropertyNextLine.Trim(FALSE);
812 //ContactLine.Trim();
813 ContactLine.Append(wxSPropertyNextLine);
814 iterboolsub->second = TRUE;
818 ExtraLineSeek = FALSE;
824 ContactLineLen = ContactLine.Len();
826 for (int i = 0; i <= ContactLineLen; i++){
828 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
830 PropertyFind = FALSE;
832 } else if (PropertyFind == TRUE){
834 wxSProperty.Append(ContactLine.Mid(i, 1));
838 if (ContactLine.Mid(i, 1) == wxT("\"")){
840 if (QuoteMode == TRUE){
852 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
861 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
862 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
864 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
865 wxSProperty = wxSPropertySegSplit.GetNextToken();
867 std::map<int,int> DataLineProcess;
868 std::map<int, bool>::iterator DLSLiter;
870 // Look for the X-VCARD4-(variablename) equivilant.
872 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
874 // Sort out remainder of the types.
876 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
877 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
878 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
880 wxString FinalPropertyData;
882 FinalPropertyData.Append(wxSPropertyNameConv);
884 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
885 striter != PropertyData.end(); ++striter){
887 FinalPropertyData.Append(wxT(";"));
888 FinalPropertyData.Append(striter->first);
889 FinalPropertyData.Append(wxT("="));
890 FinalPropertyData.Append(striter->second);
894 wxString FinalPropValue;
896 if (wxSPropertyXVCard4Value.IsEmpty()){
898 FinalPropValue = wxSPropertyData;
902 if (wxSPropertyXVCard4Value != wxSPropertyData){
904 FinalPropValue = wxSPropertyXVCard4Value;
910 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
913 wxSPropertySub.Clear();
914 wxSPropertySeg1.Clear();
915 wxSPropertySeg2.Clear();
916 wxSPropertyValues.Clear();
917 wxSPropertyData.Clear();
918 wxSPropertyXVCard4Value.Clear();
919 wxSPropertyNameConv.Clear();
920 //FinalPropertyData.clear();
921 //FinalPropValue.clear();
922 PropertyData.clear();
923 PropertyLock.clear();
925 XVCard4Value = FALSE;
932 int NicknameCount = 0;
941 int RelatedCount = 0;
946 int CategoryCount = 0;
951 int CalReqAdrCount = 0;
952 int FreeBusyCount = 0;
957 int MaxItemNumber = 0;
959 int ItemUnordered = 0;
961 size_t ItemStringSeekLen = 0;
963 int ItemSeekSecSub = 0;
964 //int intValueSeek = 1;
966 std::map<int, wxString> NumberedName;
967 std::map<int, wxString> NumberedData;
968 std::map<int, wxString> NumberedPropValues;
969 std::map<int, wxString> NumberedPropOldValue;
971 std::map<int, wxString> UnNumberedName;
972 std::map<int, wxString> UnNumberedData;
973 std::map<int, wxString> UnNumberedPropValues;
974 std::map<int, wxString> UnNumberedPropOldValue;
976 // Part 1: Get the itemn number.
978 std::map<int,bool>::iterator iterboolsecsub;
979 std::map<int,wxString>::iterator itersub;
980 std::map<int, wxString> TempData;
981 PropertyData.clear();
982 PropertyLock.clear();
984 wxString ItemStringSeek;
985 wxString ItemPropName;
988 ContactLineSub.clear();
989 ExtraLineSeekSub = 0;
990 wxString wxSPropertyNextLineSub;
991 ContactLineSubLen = 0;
993 PropertFindSub.clear();
994 wxSPropertySub.clear();
995 wxSPropertySeg1Sub.clear();
996 wxSPropertySeg2Sub.clear();
997 wxSPropertyValues.clear();
998 wxSPropertyData.clear();
999 wxSPropertyNameConv.clear();
1000 wxSPropertyXVCard4Value.clear();
1001 ItemProcString.clear();
1003 XVCard4Value = FALSE;
1004 VCard3Value = FALSE;
1005 SeekItemData = FALSE;
1007 std::map<wxString, void*> ItemMapIndex;
1008 //std::map<wxString, wxString> ItemNameIndex;
1010 // Look for item in the initial line, process into a proper line then
1011 // look for other lines with the same item association.
1013 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
1014 iter != ContactFileLines.end(); ++iter){
1016 ExtraLineSeek = TRUE;
1018 iterbool = ContactFileProcessed.find(iter->first);
1020 if (iterbool->second == TRUE){
1026 ContactLine = iter->second;
1028 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
1034 if (ContactLine.Mid(0, 4) != wxT("item")){
1042 //ContactLineSeekSub = ContactLineSeek;
1043 std::map<int,wxString>::iterator itersub = iter;
1045 while (ExtraLineSeek == TRUE){
1047 // Check if there is extra data on the next line
1048 // (indicated by space or tab at the start) and add data.
1051 iterboolsub = ContactFileProcessed.find(itersub->first);
1053 if (iterboolsub == ContactFileProcessed.end()){
1059 if (iterboolsub->second == TRUE){
1065 if (itersub == ContactFileLines.end()){
1071 wxSPropertyNextLine = itersub->second;
1073 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1075 wxSPropertyNextLine.Remove(0, 1);
1076 //wxSPropertyNextLine.Trim(FALSE);
1077 //ContactLine.Trim();
1078 ContactLine.Append(wxSPropertyNextLine);
1079 iterboolsub->second = TRUE;
1083 ExtraLineSeek = FALSE;
1089 ContactLineLen = ContactLine.Len();
1091 for (int i = 0; i <= ContactLineLen; i++){
1093 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1095 PropertyFind = FALSE;
1097 } else if (PropertyFind == TRUE){
1099 wxSProperty.Append(ContactLine.Mid(i, 1));
1103 if (ContactLine.Mid(i, 1) == wxT("\"")){
1105 if (QuoteMode == TRUE){
1117 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1119 QuoteBreakPoint = i;
1126 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1127 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1129 // Go through the lines and collect the lines like itemn.
1131 std::map<int,wxString> *ItemListData;
1132 ItemListData = new std::map<int,wxString>;
1134 wxStringTokenizer ItemData(wxSPropertySeg1, wxT("."));
1136 ItemString = ItemData.GetNextToken();
1137 ItemStringSeek = wxT("item") + ItemString.Mid(4);
1139 wxStringTokenizer ItemPropSplit(ItemData.GetNextToken(), wxT(";"));
1141 ItemPropName = ItemPropSplit.GetNextToken();
1143 ItemStringSeekLen = ItemStringSeek.Len();
1147 for (std::map<int,wxString>::iterator itersec = ContactFileLines.begin();
1148 itersec != ContactFileLines.end(); ++itersec){
1150 ExtraLineSeek = TRUE;
1152 iterboolsub = ContactFileProcessed.find(itersec->first);
1154 if (iterboolsub->second == TRUE){
1160 ContactLineSub = itersec->second;
1162 wxStringTokenizer ItemProcData(ContactLineSub, wxT("."));
1163 ItemProcString = ItemData.GetNextToken();
1165 if (ItemStringSeek != ContactLineSub.Mid(0, ItemStringSeekLen)){
1173 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1175 iterboolsub->second = TRUE;
1179 //ItemNameIndex.insert(std::make_pair(ItemStringSeek, ItemPropName));
1180 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1181 ItemMapIndex.insert(std::make_pair(ItemStringSeek, ItemListData));
1185 // Process each itemn set.
1187 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1188 iter != ItemMapIndex.end(); ++iter){
1190 std::map<int, wxString> *ItemDataPtr;
1192 ItemDataPtr = (std::map<int,wxString>*)iter->second;
1194 for (std::map<int,wxString>::iterator itersub = ItemDataPtr->begin();
1195 itersub != ItemDataPtr->end(); ++itersub){
1197 ContactLine = itersub->second;
1199 ContactLineLen = ContactLine.Len();
1201 for (int i = 0; i <= ContactLineLen; i++){
1203 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1205 PropertyFind = FALSE;
1207 } else if (PropertyFind == TRUE){
1209 wxSProperty.Append(ContactLine.Mid(i, 1));
1213 if (ContactLine.Mid(i, 1) == wxT("\"")){
1215 if (QuoteMode == TRUE){
1227 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1229 QuoteBreakPoint = i;
1236 wxSPropertySeg1Sub = ContactLine.Mid(0, QuoteBreakPoint);
1237 wxSPropertySeg2Sub = ContactLine.Mid((QuoteBreakPoint + 1));
1239 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1Sub, wxT(";"));
1240 wxSProperty = wxSPropertySegSplit.GetNextToken();
1242 // Sort out remainder of the types.
1244 // Skip certain X-* IM variables as they are processed via
1247 if (wxSProperty == wxT("X-AIM") || wxSProperty == wxT("X-MSN") ||
1248 wxSProperty == wxT("X-ICQ") || wxSProperty == wxT("X-GADUGADU") ||
1249 wxSProperty == wxT("X-YAHOO") || wxSProperty == wxT("X-SKYPE") ||
1250 wxSProperty == wxT("X-JABBER")){
1252 wxSProperty.clear();
1253 wxSPropertySub.Clear();
1254 wxSPropertySeg1.Clear();
1255 wxSPropertySeg2.Clear();
1256 wxSPropertyValues.Clear();
1257 wxSPropertyData.Clear();
1258 wxSPropertyXVCard4Value.Clear();
1259 wxSPropertyNameConv.Clear();
1260 //FinalPropertyData.clear();
1261 //FinalPropValue.clear();
1262 PropertyData.clear();
1263 PropertyLock.clear();
1264 ContactLine.clear();
1265 XVCard4Value = FALSE;
1266 VCard3Value = FALSE;
1271 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1Sub, &wxSPropertySeg2Sub,
1272 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
1273 &wxSPropertyNameConv, &PropertyData, &PropertyLock, TRUE, &VCard3Value, &XVCard4Value);
1277 if (wxSPropertyNameConv.IsEmpty()){
1279 wxSProperty.clear();
1280 wxSPropertySub.Clear();
1281 wxSPropertySeg1.Clear();
1282 wxSPropertySeg2.Clear();
1283 wxSPropertyValues.Clear();
1284 wxSPropertyData.Clear();
1285 wxSPropertyXVCard4Value.Clear();
1286 wxSPropertyNameConv.Clear();
1287 //FinalPropertyData.clear();
1288 //FinalPropValue.clear();
1289 PropertyData.clear();
1290 PropertyLock.clear();
1291 ContactLine.clear();
1292 XVCard4Value = FALSE;
1293 VCard3Value = FALSE;
1298 wxString FinalPropertyData;
1300 FinalPropertyData.Append(wxSPropertyNameConv);
1302 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
1303 striter != PropertyData.end(); ++striter){
1305 FinalPropertyData.Append(wxT(";"));
1306 FinalPropertyData.Append(striter->first);
1307 FinalPropertyData.Append(wxT("="));
1308 FinalPropertyData.Append(striter->second);
1312 wxString FinalPropValue;
1314 if (wxSPropertyXVCard4Value.IsEmpty()){
1316 FinalPropValue = wxSPropertyData;
1320 if (wxSPropertyXVCard4Value != wxSPropertyData){
1322 FinalPropValue = wxSPropertyData;
1326 FinalPropValue = wxSPropertyXVCard4Value;
1332 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
1334 wxSProperty.clear();
1335 wxSPropertySub.Clear();
1336 wxSPropertySeg1Sub.Clear();
1337 wxSPropertySeg2Sub.Clear();
1338 wxSPropertyValues.Clear();
1339 wxSPropertyData.Clear();
1340 wxSPropertyXVCard4Value.Clear();
1341 wxSPropertyNameConv.Clear();
1342 FinalPropertyData.clear();
1343 FinalPropValue.clear();
1344 PropertyData.clear();
1345 PropertyLock.clear();
1346 ContactLine.clear();
1347 XVCard4Value = FALSE;
1348 VCard3Value = FALSE;
1351 //PropertyData.clear();
1352 //PropertyLock.clear();
1358 std::map<int, wxString> *ItemEraseData;
1360 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1361 iter != ItemMapIndex.end(); ++iter){
1363 ItemEraseData = (std::map<int,wxString>*)iter->second;
1365 delete ItemEraseData;
1366 ItemEraseData = NULL;
1370 ItemMapIndex.clear();
1372 vCardOut->AddRaw(wxT("END"), wxT("VCARD"));