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 ContactLine.Append(wxSPropertyNextLine);
229 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterboolsub->first));
234 ExtraLineSeek = FALSE;
240 ContactLineLen = ContactLine.Len();
242 for (int i = 0; i <= ContactLineLen; i++){
244 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
246 PropertyFind = FALSE;
248 } else if (PropertyFind == TRUE){
250 wxSProperty.Append(ContactLine.Mid(i, 1));
254 if (ContactLine.Mid(i, 1) == wxT("\"")){
256 if (QuoteMode == TRUE){
268 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
277 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
278 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
280 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
281 wxSProperty = wxSPropertySegSplit.GetNextToken();
283 // Check what type of property it is.
287 if ((wxSProperty == wxT("PHOTO") && PhotoFirst == FALSE) ||
288 (wxSProperty == wxT("NICKNAME") && NicknameFirst == FALSE) ||
289 (wxSProperty == wxT("TITLE") && TitleFirst == FALSE) ||
290 (wxSProperty == wxT("FN") && FNFirst == FALSE) ||
291 (wxSProperty == wxT("ORG") && OrganisationFirst == FALSE) ||
292 (wxSProperty == wxT("NOTE") && NoteFirst == FALSE)){
294 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
295 intPrevValueSub = (wxSPropertyVCARD4.Len() + 2);
297 for (std::map<int,wxString>::iterator itersub = ContactFileLines.begin();
298 itersub != ContactFileLines.end(); ++itersub){
300 ContactLineSub = itersub->second;
302 ExtraLineSeekSub = TRUE;
304 iterboolsub = ContactFileProcessed.find(itersub->first);
306 // Ignore certain variables as they are not needed.
308 if (ContactLineSub == wxT("BEGIN:VCARD") ||
309 ContactLineSub == wxT("END:VCARD") ||
310 ContactLineSub.Mid(0, 8) == wxT("VERSION:") ||
311 ContactLineSub.Mid(0, 7) == wxT("PRODID:") ||
312 ContactLineSub.Mid(0, 5) == wxT("X-AIM") ||
313 ContactLineSub.Mid(0, 5) == wxT("X-MSN") ||
314 ContactLineSub.Mid(0, 5) == wxT("X-ICQ") ||
315 ContactLineSub.Mid(0, 10) == wxT("X-GADUGADU") ||
316 ContactLineSub.Mid(0, 7) == wxT("X-YAHOO") ||
317 ContactLineSub.Mid(0, 7) == wxT("X-SKYPE") ||
318 ContactLineSub.Mid(0, 8) == wxT("X-JABBER") ||
319 ContactLineSub.Mid(0, 4) == wxT("REV:")){
321 iterboolsub->second = TRUE;
326 if (iterboolsub->second == TRUE){
332 if (ContactLineSub.Mid(0, 1) == wxT(" ") || ContactLineSub.Mid(0, 1) == wxT("\t")){
338 if (ContactLineSub.Mid(0, 4) == wxT("item")){
340 // Line is a itemn... so ignore.
346 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
349 while (ExtraLineSeekSub == TRUE){
351 if (itersub == ContactFileLines.end()){
352 ExtraLineSeekSub = FALSE;
359 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
361 wxSPropertyNextLine = itersub->second;
363 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
365 wxSPropertyNextLine.Remove(0, 1);
366 ContactLineSub.Append(wxSPropertyNextLine);
367 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
373 ExtraLineSeekSub = FALSE;
379 ContactLineSubLen = ContactLineSub.Len();
381 wxSPropertySub.clear();
383 for (int i = 0; i <= ContactLineSubLen; i++){
385 if ((ContactLineSub.Mid(i, 1) == wxT(";") || ContactLineSub.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
387 PropertyFind = FALSE;
389 } else if (PropertyFind == TRUE){
391 wxSPropertySub.Append(ContactLineSub.Mid(i, 1));
395 if (ContactLineSub.Mid(i, 1) == wxT("\"")){
397 if (QuoteMode == TRUE){
409 if (ContactLineSub.Mid(i, 1) == wxT(":") && ContactLineSub.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
418 if (wxSPropertySub != wxSPropertyVCARD4){
420 wxSPropertySub.clear();
422 DataLineProcess.clear();
427 wxSPropertySeg1Sub = ContactLineSub.Mid(0, QuoteBreakPoint);
428 wxSPropertySeg2Sub = ContactLineSub.Mid((QuoteBreakPoint + 1));
430 // Split the property name data.
432 // Strip the X-VCARD4- from the variable.
434 wxString wxSPropertyChopped = wxSPropertySeg1Sub.Mid(9);
436 intPrevValueSub = (wxSProperty.Len() + 2);
438 SplitValuesData(&wxSPropertyChopped, &TempSplitPoints, &TempSplitLength, (int)intPrevValueSub, &TempPropertyData);
440 // Process the splitted data into temporary property data.
442 // Look for certain property names and the X-FIRST
445 bool ProcessData = FALSE;
447 // Check for X-FIRST.
449 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
450 xfiter != TempPropertyData.end(); ++xfiter){
452 PropertyName = xfiter->first;
453 PropertyValue = xfiter->second;
455 if (PropertyName == wxT("X-FIRST") && PropertyValue == wxT("TRUE")){
459 if (wxSProperty == wxT("PHOTO")){ PhotoFirst = TRUE; }
460 else if (wxSProperty == wxT("NICKNAME")){ NicknameFirst = TRUE; }
461 else if (wxSProperty == wxT("TITLE")){ TitleFirst = TRUE; }
462 else if (wxSProperty == wxT("FN")){ FNFirst = TRUE; }
463 else if (wxSProperty == wxT("ORG")){ OrganisationFirst = TRUE; }
464 else if (wxSProperty == wxT("NOTE")){ NoteFirst = TRUE; }
471 if (ProcessData == FALSE){
473 DataLineProcess.clear();
475 TempPropertyData.clear();
479 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
480 xfiter != TempPropertyData.end(); ++xfiter){
482 PropertyName = xfiter->first;
483 PropertyValue = xfiter->second;
485 if (PropertyName == wxT("X-FIRST")){
491 PropertyData.insert(std::make_pair(PropertyName, PropertyValue));
492 PropertyLock.insert(std::make_pair(PropertyName, FALSE));
496 // Mark all lines as processed.
498 for (std::map<int,int>::iterator dpiter = DataLineProcess.begin();
499 dpiter != DataLineProcess.end(); ++dpiter){
501 DLSLiter = ContactFileProcessed.find(dpiter->second);
502 DLSLiter->second = TRUE;
506 for (std::map<int,int>::iterator dpoiter = DataLineProcessOriginal.begin();
507 dpoiter != DataLineProcessOriginal.end(); ++dpoiter){
509 DLSLiter = ContactFileProcessed.find(dpoiter->second);
510 DLSLiter->second = TRUE;
514 DataLineProcess.clear();
515 DataLineProcessOriginal.clear();
517 DataLineSeekOrig = 0;
518 TempSplitPoints.clear();
519 TempSplitLength.clear();
520 TempPropertyData.clear();
532 wxSPropertySub.Clear();
533 wxSPropertySeg1.Clear();
534 wxSPropertySeg2.Clear();
535 wxSPropertySeg1Sub.Clear();
536 wxSPropertySeg2Sub.Clear();
537 wxSPropertyValues.Clear();
538 wxSPropertyData.Clear();
539 wxSPropertyXVCard4Value.Clear();
540 wxSPropertyNameConv.Clear();
541 PropertyData.clear();
542 PropertyLock.clear();
544 ContactLineSub.clear();
545 DataLineProcess.clear();
546 DataLineProcessOriginal.clear();
547 TempSplitPoints.clear();
548 TempSplitLength.clear();
549 wxSPropertyVCARD4.clear();
551 DataLineSeekOrig = 0;
552 XVCard4Value = FALSE;
557 if (FoundData == FALSE){
560 wxSPropertySub.Clear();
561 wxSPropertySeg1.Clear();
562 wxSPropertySeg2.Clear();
563 wxSPropertySeg1Sub.Clear();
564 wxSPropertySeg2Sub.Clear();
565 wxSPropertyValues.Clear();
566 wxSPropertyData.Clear();
567 wxSPropertyXVCard4Value.Clear();
568 wxSPropertyNameConv.Clear();
569 PropertyData.clear();
570 PropertyLock.clear();
572 ContactLineSub.clear();
573 DataLineProcess.clear();
574 DataLineProcessOriginal.clear();
575 TempSplitPoints.clear();
576 TempSplitLength.clear();
577 wxSPropertyVCARD4.clear();
579 DataLineSeekOrig = 0;
580 XVCard4Value = FALSE;
585 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
586 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
587 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
589 wxString FinalPropertyData;
591 FinalPropertyData.Append(wxSPropertyNameConv);
593 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
594 striter != PropertyData.end(); ++striter){
596 FinalPropertyData.Append(wxT(";"));
597 FinalPropertyData.Append(striter->first);
598 FinalPropertyData.Append(wxT("="));
599 FinalPropertyData.Append(striter->second);
603 wxString FinalPropValue;
605 if (wxSPropertyXVCard4Value.IsEmpty()){
607 FinalPropValue = wxSPropertyData;
611 if (wxSPropertyXVCard4Value != wxSPropertyData){
613 FinalPropValue = wxSPropertyXVCard4Value;
619 if (FinalPropertyData.IsEmpty() && FinalPropValue.IsEmpty()){
625 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
628 wxSPropertySub.Clear();
629 wxSPropertySeg1.Clear();
630 wxSPropertySeg2.Clear();
631 wxSPropertySeg1Sub.Clear();
632 wxSPropertySeg2Sub.Clear();
633 wxSPropertyValues.Clear();
634 wxSPropertyData.Clear();
635 wxSPropertyXVCard4Value.Clear();
636 wxSPropertyNameConv.Clear();
637 PropertyData.clear();
638 PropertyLock.clear();
640 ContactLineSub.clear();
641 DataLineProcess.clear();
642 DataLineProcessOriginal.clear();
643 wxSPropertyVCARD4.clear();
645 DataLineSeekOrig = 0;
646 XVCard4Value = FALSE;
651 // Process the non-itemn values.
653 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
654 iter != ContactFileLines.end(); ++iter){
656 ExtraLineSeek = TRUE;
658 iterbool = ContactFileProcessed.find(iter->first);
660 ContactLine = iter->second;
662 // Ignore certain variables as they are not needed.
664 if (ContactLine == wxT("BEGIN:VCARD") ||
665 ContactLine == wxT("END:VCARD") ||
666 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
667 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
668 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
669 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
670 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
671 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
672 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
673 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
674 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
675 ContactLine.Mid(0, 4) == wxT("REV:")){
677 iterbool->second = TRUE;
682 if (iterbool->second == TRUE){
688 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
694 if (ContactLine.Mid(0, 4) == wxT("item")){
696 // Line is a itemn... so ignore.
702 std::map<int,wxString>::iterator itersub = iter;
704 while (ExtraLineSeek == TRUE){
706 // Check if there is extra data on the next line
707 // (indicated by space or tab at the start) and add data.
709 if (itersub == ContactFileLines.end()){
710 ExtraLineSeekSub = FALSE;
718 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
720 if (iterboolsub == ContactFileProcessedWorking.end()){
726 if (iterboolsub->second == TRUE){
732 if (itersub == ContactFileLines.end()){
738 wxSPropertyNextLine = itersub->second;
740 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
742 wxSPropertyNextLine.Remove(0, 1);
743 ContactLine.Append(wxSPropertyNextLine);
744 iterboolsub->second = TRUE;
748 ExtraLineSeek = FALSE;
754 ContactLineLen = ContactLine.Len();
756 for (int i = 0; i <= ContactLineLen; i++){
758 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
760 PropertyFind = FALSE;
762 } else if (PropertyFind == TRUE){
764 wxSProperty.Append(ContactLine.Mid(i, 1));
768 if (ContactLine.Mid(i, 1) == wxT("\"")){
770 if (QuoteMode == TRUE){
782 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
791 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
792 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
794 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
795 wxSProperty = wxSPropertySegSplit.GetNextToken();
797 std::map<int,int> DataLineProcess;
798 std::map<int, bool>::iterator DLSLiter;
800 // Look for the X-VCARD4-(variablename) equivilant.
802 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
804 // Sort out remainder of the types.
806 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
807 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
808 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
810 wxString FinalPropertyData;
812 FinalPropertyData.Append(wxSPropertyNameConv);
814 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
815 striter != PropertyData.end(); ++striter){
817 FinalPropertyData.Append(wxT(";"));
818 FinalPropertyData.Append(striter->first);
819 FinalPropertyData.Append(wxT("="));
820 FinalPropertyData.Append(striter->second);
824 wxString FinalPropValue;
826 if (wxSPropertyXVCard4Value.IsEmpty()){
828 FinalPropValue = wxSPropertyData;
832 if (wxSPropertyXVCard4Value != wxSPropertyData){
834 FinalPropValue = wxSPropertyXVCard4Value;
840 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
843 wxSPropertySub.Clear();
844 wxSPropertySeg1.Clear();
845 wxSPropertySeg2.Clear();
846 wxSPropertyValues.Clear();
847 wxSPropertyData.Clear();
848 wxSPropertyXVCard4Value.Clear();
849 wxSPropertyNameConv.Clear();
850 PropertyData.clear();
851 PropertyLock.clear();
853 XVCard4Value = FALSE;
860 int NicknameCount = 0;
869 int RelatedCount = 0;
874 int CategoryCount = 0;
879 int CalReqAdrCount = 0;
880 int FreeBusyCount = 0;
885 int MaxItemNumber = 0;
887 int ItemUnordered = 0;
889 size_t ItemStringSeekLen = 0;
891 int ItemSeekSecSub = 0;
893 std::map<int, wxString> NumberedName;
894 std::map<int, wxString> NumberedData;
895 std::map<int, wxString> NumberedPropValues;
896 std::map<int, wxString> NumberedPropOldValue;
898 std::map<int, wxString> UnNumberedName;
899 std::map<int, wxString> UnNumberedData;
900 std::map<int, wxString> UnNumberedPropValues;
901 std::map<int, wxString> UnNumberedPropOldValue;
903 // Part 1: Get the itemn number.
905 std::map<int,bool>::iterator iterboolsecsub;
906 std::map<int,wxString>::iterator itersub;
907 std::map<int, wxString> TempData;
908 PropertyData.clear();
909 PropertyLock.clear();
911 wxString ItemStringSeek;
912 wxString ItemPropName;
915 ContactLineSub.clear();
916 ExtraLineSeekSub = 0;
917 wxString wxSPropertyNextLineSub;
918 ContactLineSubLen = 0;
920 PropertFindSub.clear();
921 wxSPropertySub.clear();
922 wxSPropertySeg1Sub.clear();
923 wxSPropertySeg2Sub.clear();
924 wxSPropertyValues.clear();
925 wxSPropertyData.clear();
926 wxSPropertyNameConv.clear();
927 wxSPropertyXVCard4Value.clear();
928 ItemProcString.clear();
930 XVCard4Value = FALSE;
932 SeekItemData = FALSE;
934 std::map<wxString, void*> ItemMapIndex;
936 // Look for item in the initial line, process into a proper line then
937 // look for other lines with the same item association.
939 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
940 iter != ContactFileLines.end(); ++iter){
942 ExtraLineSeek = TRUE;
944 iterbool = ContactFileProcessed.find(iter->first);
946 if (iterbool->second == TRUE){
952 ContactLine = iter->second;
954 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
960 if (ContactLine.Mid(0, 4) != wxT("item")){
968 std::map<int,wxString>::iterator itersub = iter;
970 while (ExtraLineSeek == TRUE){
972 // Check if there is extra data on the next line
973 // (indicated by space or tab at the start) and add data.
976 iterboolsub = ContactFileProcessed.find(itersub->first);
978 if (iterboolsub == ContactFileProcessed.end()){
984 if (iterboolsub->second == TRUE){
990 if (itersub == ContactFileLines.end()){
996 wxSPropertyNextLine = itersub->second;
998 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1000 wxSPropertyNextLine.Remove(0, 1);
1001 ContactLine.Append(wxSPropertyNextLine);
1002 iterboolsub->second = TRUE;
1006 ExtraLineSeek = FALSE;
1012 ContactLineLen = ContactLine.Len();
1014 for (int i = 0; i <= ContactLineLen; i++){
1016 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1018 PropertyFind = FALSE;
1020 } else if (PropertyFind == TRUE){
1022 wxSProperty.Append(ContactLine.Mid(i, 1));
1026 if (ContactLine.Mid(i, 1) == wxT("\"")){
1028 if (QuoteMode == TRUE){
1040 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1042 QuoteBreakPoint = i;
1049 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1050 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1052 // Go through the lines and collect the lines like itemn.
1054 std::map<int,wxString> *ItemListData;
1055 ItemListData = new std::map<int,wxString>;
1057 wxStringTokenizer ItemData(wxSPropertySeg1, wxT("."));
1059 ItemString = ItemData.GetNextToken();
1060 ItemStringSeek = wxT("item") + ItemString.Mid(4);
1062 wxStringTokenizer ItemPropSplit(ItemData.GetNextToken(), wxT(";"));
1064 ItemPropName = ItemPropSplit.GetNextToken();
1066 ItemStringSeekLen = ItemStringSeek.Len();
1070 for (std::map<int,wxString>::iterator itersec = ContactFileLines.begin();
1071 itersec != ContactFileLines.end(); ++itersec){
1073 ExtraLineSeek = TRUE;
1075 iterboolsub = ContactFileProcessed.find(itersec->first);
1077 if (iterboolsub->second == TRUE){
1083 ContactLineSub = itersec->second;
1085 wxStringTokenizer ItemProcData(ContactLineSub, wxT("."));
1086 ItemProcString = ItemData.GetNextToken();
1088 if (ItemStringSeek != ContactLineSub.Mid(0, ItemStringSeekLen)){
1096 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1098 iterboolsub->second = TRUE;
1102 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1103 ItemMapIndex.insert(std::make_pair(ItemStringSeek, ItemListData));
1107 // Process each itemn set.
1109 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1110 iter != ItemMapIndex.end(); ++iter){
1112 std::map<int, wxString> *ItemDataPtr;
1114 ItemDataPtr = (std::map<int,wxString>*)iter->second;
1116 for (std::map<int,wxString>::iterator itersub = ItemDataPtr->begin();
1117 itersub != ItemDataPtr->end(); ++itersub){
1119 ContactLine = itersub->second;
1121 ContactLineLen = ContactLine.Len();
1123 for (int i = 0; i <= ContactLineLen; i++){
1125 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1127 PropertyFind = FALSE;
1129 } else if (PropertyFind == TRUE){
1131 wxSProperty.Append(ContactLine.Mid(i, 1));
1135 if (ContactLine.Mid(i, 1) == wxT("\"")){
1137 if (QuoteMode == TRUE){
1149 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1151 QuoteBreakPoint = i;
1158 wxSPropertySeg1Sub = ContactLine.Mid(0, QuoteBreakPoint);
1159 wxSPropertySeg2Sub = ContactLine.Mid((QuoteBreakPoint + 1));
1161 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1Sub, wxT(";"));
1162 wxSProperty = wxSPropertySegSplit.GetNextToken();
1164 // Sort out remainder of the types.
1166 // Skip certain X-* IM variables as they are processed via
1169 if (wxSProperty == wxT("X-AIM") || wxSProperty == wxT("X-MSN") ||
1170 wxSProperty == wxT("X-ICQ") || wxSProperty == wxT("X-GADUGADU") ||
1171 wxSProperty == wxT("X-YAHOO") || wxSProperty == wxT("X-SKYPE") ||
1172 wxSProperty == wxT("X-JABBER")){
1174 wxSProperty.clear();
1175 wxSPropertySub.Clear();
1176 wxSPropertySeg1.Clear();
1177 wxSPropertySeg2.Clear();
1178 wxSPropertyValues.Clear();
1179 wxSPropertyData.Clear();
1180 wxSPropertyXVCard4Value.Clear();
1181 wxSPropertyNameConv.Clear();
1182 PropertyData.clear();
1183 PropertyLock.clear();
1184 ContactLine.clear();
1185 XVCard4Value = FALSE;
1186 VCard3Value = FALSE;
1191 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1Sub, &wxSPropertySeg2Sub,
1192 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
1193 &wxSPropertyNameConv, &PropertyData, &PropertyLock, TRUE, &VCard3Value, &XVCard4Value);
1197 if (wxSPropertyNameConv.IsEmpty()){
1199 wxSProperty.clear();
1200 wxSPropertySub.Clear();
1201 wxSPropertySeg1.Clear();
1202 wxSPropertySeg2.Clear();
1203 wxSPropertyValues.Clear();
1204 wxSPropertyData.Clear();
1205 wxSPropertyXVCard4Value.Clear();
1206 wxSPropertyNameConv.Clear();
1207 PropertyData.clear();
1208 PropertyLock.clear();
1209 ContactLine.clear();
1210 XVCard4Value = FALSE;
1211 VCard3Value = FALSE;
1216 wxString FinalPropertyData;
1218 FinalPropertyData.Append(wxSPropertyNameConv);
1220 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
1221 striter != PropertyData.end(); ++striter){
1223 FinalPropertyData.Append(wxT(";"));
1224 FinalPropertyData.Append(striter->first);
1225 FinalPropertyData.Append(wxT("="));
1226 FinalPropertyData.Append(striter->second);
1230 wxString FinalPropValue;
1232 if (wxSPropertyXVCard4Value.IsEmpty()){
1234 FinalPropValue = wxSPropertyData;
1238 if (wxSPropertyXVCard4Value != wxSPropertyData){
1240 FinalPropValue = wxSPropertyData;
1244 FinalPropValue = wxSPropertyXVCard4Value;
1250 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
1252 wxSProperty.clear();
1253 wxSPropertySub.Clear();
1254 wxSPropertySeg1Sub.Clear();
1255 wxSPropertySeg2Sub.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;
1274 std::map<int, wxString> *ItemEraseData;
1276 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1277 iter != ItemMapIndex.end(); ++iter){
1279 ItemEraseData = (std::map<int,wxString>*)iter->second;
1281 delete ItemEraseData;
1282 ItemEraseData = NULL;
1286 ItemMapIndex.clear();
1288 vCardOut->AddRaw(wxT("END"), wxT("VCARD"));