1 #include "vcard34conv.h"
3 #include "../version.h"
4 #include "../common/textprocessing.h"
7 #include <wx/tokenzr.h>
8 #include <wx/datetime.h>
11 bool vCard34Conv::ConvertToV4(wxString *wxSData, vCard *vCardOut){
13 std::map<int, wxString> ContactFileLines;
14 std::map<int, bool> ContactFileProcessed;
15 std::map<int, bool> ContactFileProcessedWorking;
16 std::map<int, wxString>::iterator striter;
17 std::map<int,bool>::iterator iterbool;
18 std::map<int,bool>::iterator iterboolsub;
19 wxString ContactLineRec;
21 // Process the received data.
23 wxStringTokenizer wSTContactFileLines(*wxSData, wxT("\r\n"));
25 int ContactLineSeek = 0;
27 while (wSTContactFileLines.HasMoreTokens() == TRUE){
29 ContactLineRec = wSTContactFileLines.GetNextToken();
30 ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLineRec));
31 ContactFileProcessed.insert(std::make_pair(ContactLineSeek, FALSE));
36 bool QuoteMode = FALSE;
37 bool PropertyFind = TRUE;
38 bool ExtraLineSeek = TRUE;
39 bool ExtraLineSeekSub = TRUE;
40 bool BirthdayProcessed = FALSE;
41 bool AnniversaryProcessed = FALSE;
42 bool FNProcessed = FALSE;
43 bool GenderProcessed = FALSE;
44 bool NameProcessed = FALSE;
46 bool NicknameFirst = FALSE;
47 bool TitleFirst = FALSE;
48 bool OrganisationFirst = FALSE;
49 bool NoteFirst = FALSE;
50 bool PhotoFirst = FALSE;
51 bool LogoFirst = FALSE;
52 bool NameFirst = FALSE;
53 bool FoundData = FALSE;
54 int intExtraNickname = 0;
56 wxString wxSPropertyVCARD4;
57 wxString wxSPropertySeg1;
58 wxString wxSPropertySeg2;
59 wxString wxSPropertyNextLine;
61 wxString ContactLineSub;
62 wxString PropertyName;
63 wxString PropertyValue;
64 wxString PropertyDataStr;
65 size_t ContactLineLen = 0;
66 size_t ContactLineSubLen = 0;
67 int QuoteBreakPoint = 0;
68 size_t intPrevValueSub = 0;
70 std::map<wxString, wxString> PropertyData;
71 std::map<wxString, bool> PropertyLock;
72 std::map<wxString, wxString> TempPropertyData;
73 std::map<wxString, bool> TempPropertyLock;
74 std::map<int, int> TempSplitPoints;
75 std::map<int, int> TempSplitLength;
76 std::map<int, int>::iterator SLiter;
78 wxString PropertFindSub;
79 wxString wxSPropertySub;
80 wxString wxSPropertySeg1Sub;
81 wxString wxSPropertySeg2Sub;
82 wxString wxSPropertyValues;
83 wxString wxSPropertyData;
84 wxString wxSPropertyNameConv;
85 wxString wxSPropertyXVCard4Value;
86 wxString ItemProcString;
88 bool XVCard4Value = FALSE;
89 bool VCard3Value = FALSE;
90 bool SeekItemData = FALSE;
94 // Setup the version string.
96 strVer.Append(wxT("-//Xestia//Address Book Version "));
97 strVer.Append(wxT(XSDAB_VERSION));
98 strVer.Append(wxT("//KW"));
100 vCardOut->AddRaw(wxT("BEGIN"), wxT("VCARD"));
101 vCardOut->AddRaw(wxT("VERSION"), wxT("4.0"));
102 vCardOut->AddRaw(wxT("PRODID"), strVer);
111 // Process the properties which have X-FIRST.
113 // Clone the ContactFileProcessed into ContactFileProcessedWorking.
115 ContactFileProcessedWorking.insert(ContactFileProcessed.begin(), ContactFileProcessed.end());
117 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
118 iter != ContactFileLines.end(); ++iter){
120 ExtraLineSeek = TRUE;
122 iterbool = ContactFileProcessed.find(iter->first);
124 ContactLine = iter->second;
126 // Ignore certain variables as they are not needed.
128 if (ContactLine == wxT("BEGIN:VCARD") ||
129 ContactLine == wxT("END:VCARD") ||
130 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
131 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
132 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
133 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
134 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
135 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
136 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
137 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
138 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
139 ContactLine.Mid(0, 4) == wxT("REV:")){
141 iterbool->second = TRUE;
146 if (iterbool->second == TRUE){
152 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
158 if (ContactLine.Mid(0, 4) == wxT("item")){
160 // Line is a itemn... so ignore.
166 std::map<int,int> DataLineProcess;
167 std::map<int, bool>::iterator DLSLiter;
168 std::map<int,int> DataLineProcessOriginal;
169 int DataLineSeek = 0;
170 int DataLineSeekOrig = 0;
172 std::map<int,wxString>::iterator itersub = iter;
173 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterbool->first));
176 while (ExtraLineSeek == TRUE){
178 // Check if there is extra data on the next line
179 // (indicated by space or tab at the start) and add data.
183 if (itersub == ContactFileLines.end()){
189 iterboolsub = ContactFileProcessed.find(itersub->first);
191 if (iterboolsub == ContactFileProcessed.end()){
197 if (iterboolsub->second == TRUE){
203 wxSPropertyNextLine = itersub->second;
205 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
207 wxSPropertyNextLine.Remove(0, 1);
208 //wxSPropertyNextLine.Trim(FALSE);
209 //ContactLine.Trim();
210 ContactLine.Append(wxSPropertyNextLine);
211 DataLineProcessOriginal.insert(std::make_pair(DataLineSeekOrig, iterboolsub->first));
213 //iterboolsub->second = TRUE;
217 ExtraLineSeek = FALSE;
223 ContactLineLen = ContactLine.Len();
225 for (int i = 0; i <= ContactLineLen; i++){
227 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
229 PropertyFind = FALSE;
231 } else if (PropertyFind == TRUE){
233 wxSProperty.Append(ContactLine.Mid(i, 1));
237 if (ContactLine.Mid(i, 1) == wxT("\"")){
239 if (QuoteMode == TRUE){
251 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
260 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
261 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
263 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
264 wxSProperty = wxSPropertySegSplit.GetNextToken();
266 // Check what type of property it is.
270 if ((wxSProperty == wxT("PHOTO") && PhotoFirst == FALSE) ||
271 (wxSProperty == wxT("NICKNAME") && NicknameFirst == FALSE) ||
272 (wxSProperty == wxT("TITLE") && TitleFirst == FALSE) ||
273 (wxSProperty == wxT("FN") && FNFirst == FALSE) ||
274 (wxSProperty == wxT("ORG") && OrganisationFirst == FALSE) ||
275 (wxSProperty == wxT("NOTE") && NoteFirst == FALSE)){
277 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
278 intPrevValueSub = (wxSPropertyVCARD4.Len() + 2);
280 for (std::map<int,wxString>::iterator itersub = ContactFileLines.begin();
281 itersub != ContactFileLines.end(); ++itersub){
283 //DataLineProcess = DataLineProcessOriginal;
284 //DataLineSeek = DataLineSeekOrig;
286 ContactLineSub = itersub->second;
288 ExtraLineSeekSub = TRUE;
290 iterboolsub = ContactFileProcessed.find(itersub->first);
291 //std::map<int,bool>::iterator iterorig = ContactFileProcessed.find(itersub->first);
292 //std::map<int,bool>::iterator itersuborig;
294 // Ignore certain variables as they are not needed.
296 if (ContactLineSub == wxT("BEGIN:VCARD") ||
297 ContactLineSub == wxT("END:VCARD") ||
298 ContactLineSub.Mid(0, 8) == wxT("VERSION:") ||
299 ContactLineSub.Mid(0, 7) == wxT("PRODID:") ||
300 ContactLineSub.Mid(0, 5) == wxT("X-AIM") ||
301 ContactLineSub.Mid(0, 5) == wxT("X-MSN") ||
302 ContactLineSub.Mid(0, 5) == wxT("X-ICQ") ||
303 ContactLineSub.Mid(0, 10) == wxT("X-GADUGADU") ||
304 ContactLineSub.Mid(0, 7) == wxT("X-YAHOO") ||
305 ContactLineSub.Mid(0, 7) == wxT("X-SKYPE") ||
306 ContactLineSub.Mid(0, 8) == wxT("X-JABBER") ||
307 ContactLineSub.Mid(0, 4) == wxT("REV:")){
309 iterboolsub->second = TRUE;
314 if (iterboolsub->second == TRUE){
320 if (ContactLineSub.Mid(0, 1) == wxT(" ") || ContactLineSub.Mid(0, 1) == wxT("\t")){
326 if (ContactLineSub.Mid(0, 4) == wxT("item")){
328 // Line is a itemn... so ignore.
334 //std::map<int,wxString>::iterator itersub = iter;
336 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
341 while (ExtraLineSeekSub == TRUE){
343 if (itersub == ContactFileLines.end()){
344 ExtraLineSeekSub = FALSE;
351 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
353 wxSPropertyNextLine = itersub->second;
355 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
357 wxSPropertyNextLine.Remove(0, 1);
358 //wxSPropertyNextLine.Trim(FALSE);
359 //ContactLine.Trim();
360 ContactLineSub.Append(wxSPropertyNextLine);
361 //iterboolsub->second = TRUE;
362 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
368 ExtraLineSeekSub = FALSE;
374 /*while (ExtraLineSeekSub == TRUE && iterboolsub != ContactFileProcessedWorking.end()){
376 // Check if there is extra data on the next line
377 // (indicated by space or tab at the start) and add data.
381 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
383 if (iterboolsub->second == TRUE){
389 if (itersub == ContactFileLines.end()){
395 wxSPropertyNextLine = itersub->second;
397 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
399 wxSPropertyNextLine.Remove(0, 1);
400 //wxSPropertyNextLine.Trim(FALSE);
401 //ContactLine.Trim();
402 ContactLineSub.Append(wxSPropertyNextLine);
403 //iterboolsub->second = TRUE;
404 DataLineProcess.insert(std::make_pair(DataLineSeek, itersub->first));
410 ExtraLineSeekSub = FALSE;
414 if (iterboolsub == ContactFileProcessedWorking.end()){
417 ExtraLineSeekSub = FALSE;
423 ContactLineSubLen = ContactLineSub.Len();
425 wxSPropertySub.clear();
427 for (int i = 0; i <= ContactLineSubLen; i++){
429 if ((ContactLineSub.Mid(i, 1) == wxT(";") || ContactLineSub.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
431 PropertyFind = FALSE;
433 } else if (PropertyFind == TRUE){
435 wxSPropertySub.Append(ContactLineSub.Mid(i, 1));
439 if (ContactLineSub.Mid(i, 1) == wxT("\"")){
441 if (QuoteMode == TRUE){
453 if (ContactLineSub.Mid(i, 1) == wxT(":") && ContactLineSub.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
462 if (wxSPropertySub != wxSPropertyVCARD4){
464 wxSPropertySub.clear();
466 DataLineProcess.clear();
471 wxSPropertySeg1Sub = ContactLineSub.Mid(0, QuoteBreakPoint);
472 wxSPropertySeg2Sub = ContactLineSub.Mid((QuoteBreakPoint + 1));
474 // Split the property name data.
476 // Strip the X-VCARD4- from the variable.
478 wxString wxSPropertyChopped = wxSPropertySeg1Sub.Mid(9);
480 intPrevValueSub = (wxSProperty.Len() + 2);
482 SplitValuesData(&wxSPropertyChopped, &TempSplitPoints, &TempSplitLength, (int)intPrevValueSub, &TempPropertyData);
484 // Process the splitted data into temporary property data.
486 // Look for certain property names and the X-FIRST
489 bool ProcessData = FALSE;
491 // Check for X-FIRST.
493 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
494 xfiter != TempPropertyData.end(); ++xfiter){
496 PropertyName = xfiter->first;
497 PropertyValue = xfiter->second;
499 if (PropertyName == wxT("X-FIRST") && PropertyValue == wxT("TRUE")){
503 if (wxSProperty == wxT("PHOTO")){ PhotoFirst = TRUE; }
504 else if (wxSProperty == wxT("NICKNAME")){ NicknameFirst = TRUE; }
505 else if (wxSProperty == wxT("TITLE")){ TitleFirst = TRUE; }
506 else if (wxSProperty == wxT("FN")){ FNFirst = TRUE; }
507 else if (wxSProperty == wxT("ORG")){ OrganisationFirst = TRUE; }
508 else if (wxSProperty == wxT("NOTE")){ NoteFirst = TRUE; }
515 if (ProcessData == FALSE){
517 DataLineProcess.clear();
519 TempPropertyData.clear();
523 wxT("PHOTODANCEMATCH!");
525 for (std::map<wxString, wxString>::iterator xfiter = TempPropertyData.begin();
526 xfiter != TempPropertyData.end(); ++xfiter){
528 PropertyName = xfiter->first;
529 PropertyValue = xfiter->second;
531 if (PropertyName == wxT("X-FIRST")){
537 PropertyData.insert(std::make_pair(PropertyName, PropertyValue));
538 PropertyLock.insert(std::make_pair(PropertyName, FALSE));
542 // Mark all lines as processed.
544 for (std::map<int,int>::iterator dpiter = DataLineProcess.begin();
545 dpiter != DataLineProcess.end(); ++dpiter){
547 DLSLiter = ContactFileProcessed.find(dpiter->second);
548 DLSLiter->second = TRUE;
552 for (std::map<int,int>::iterator dpoiter = DataLineProcessOriginal.begin();
553 dpoiter != DataLineProcessOriginal.end(); ++dpoiter){
555 DLSLiter = ContactFileProcessed.find(dpoiter->second);
556 DLSLiter->second = TRUE;
560 DataLineProcess.clear();
561 DataLineProcessOriginal.clear();
563 DataLineSeekOrig = 0;
564 TempSplitPoints.clear();
565 TempSplitLength.clear();
566 TempPropertyData.clear();
578 wxSPropertySub.Clear();
579 wxSPropertySeg1.Clear();
580 wxSPropertySeg2.Clear();
581 wxSPropertySeg1Sub.Clear();
582 wxSPropertySeg2Sub.Clear();
583 wxSPropertyValues.Clear();
584 wxSPropertyData.Clear();
585 wxSPropertyXVCard4Value.Clear();
586 wxSPropertyNameConv.Clear();
587 PropertyData.clear();
588 PropertyLock.clear();
590 ContactLineSub.clear();
591 DataLineProcess.clear();
592 DataLineProcessOriginal.clear();
593 TempSplitPoints.clear();
594 TempSplitLength.clear();
595 wxSPropertyVCARD4.clear();
597 DataLineSeekOrig = 0;
598 XVCard4Value = FALSE;
603 if (FoundData == FALSE){
606 wxSPropertySub.Clear();
607 wxSPropertySeg1.Clear();
608 wxSPropertySeg2.Clear();
609 wxSPropertySeg1Sub.Clear();
610 wxSPropertySeg2Sub.Clear();
611 wxSPropertyValues.Clear();
612 wxSPropertyData.Clear();
613 wxSPropertyXVCard4Value.Clear();
614 wxSPropertyNameConv.Clear();
615 PropertyData.clear();
616 PropertyLock.clear();
618 ContactLineSub.clear();
619 DataLineProcess.clear();
620 DataLineProcessOriginal.clear();
621 TempSplitPoints.clear();
622 TempSplitLength.clear();
623 wxSPropertyVCARD4.clear();
625 DataLineSeekOrig = 0;
626 XVCard4Value = FALSE;
631 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
632 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
633 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
635 wxString FinalPropertyData;
637 FinalPropertyData.Append(wxSPropertyNameConv);
639 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
640 striter != PropertyData.end(); ++striter){
642 FinalPropertyData.Append(wxT(";"));
643 FinalPropertyData.Append(striter->first);
644 FinalPropertyData.Append(wxT("="));
645 FinalPropertyData.Append(striter->second);
649 wxString FinalPropValue;
651 if (wxSPropertyXVCard4Value.IsEmpty()){
653 FinalPropValue = wxSPropertyData;
657 if (wxSPropertyXVCard4Value != wxSPropertyData){
659 FinalPropValue = wxSPropertyXVCard4Value;
665 if (FinalPropertyData.IsEmpty() && FinalPropValue.IsEmpty()){
671 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
674 wxSPropertySub.Clear();
675 wxSPropertySeg1.Clear();
676 wxSPropertySeg2.Clear();
677 wxSPropertySeg1Sub.Clear();
678 wxSPropertySeg2Sub.Clear();
679 wxSPropertyValues.Clear();
680 wxSPropertyData.Clear();
681 wxSPropertyXVCard4Value.Clear();
682 wxSPropertyNameConv.Clear();
683 //FinalPropertyData.clear();
684 //FinalPropValue.clear();
685 PropertyData.clear();
686 PropertyLock.clear();
688 ContactLineSub.clear();
689 DataLineProcess.clear();
690 DataLineProcessOriginal.clear();
691 wxSPropertyVCARD4.clear();
693 DataLineSeekOrig = 0;
694 XVCard4Value = FALSE;
699 // Process the non-itemn values.
701 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
702 iter != ContactFileLines.end(); ++iter){
704 ExtraLineSeek = TRUE;
706 iterbool = ContactFileProcessed.find(iter->first);
708 ContactLine = iter->second;
710 // Ignore certain variables as they are not needed.
712 if (ContactLine == wxT("BEGIN:VCARD") ||
713 ContactLine == wxT("END:VCARD") ||
714 ContactLine.Mid(0, 8) == wxT("VERSION:") ||
715 ContactLine.Mid(0, 7) == wxT("PRODID:") ||
716 ContactLine.Mid(0, 5) == wxT("X-AIM") ||
717 ContactLine.Mid(0, 5) == wxT("X-MSN") ||
718 ContactLine.Mid(0, 5) == wxT("X-ICQ") ||
719 ContactLine.Mid(0, 10) == wxT("X-GADUGADU") ||
720 ContactLine.Mid(0, 7) == wxT("X-YAHOO") ||
721 ContactLine.Mid(0, 7) == wxT("X-SKYPE") ||
722 ContactLine.Mid(0, 8) == wxT("X-JABBER") ||
723 ContactLine.Mid(0, 4) == wxT("REV:")){
725 iterbool->second = TRUE;
730 if (iterbool->second == TRUE){
736 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
742 if (ContactLine.Mid(0, 4) == wxT("item")){
744 // Line is a itemn... so ignore.
750 std::map<int,wxString>::iterator itersub = iter;
752 while (ExtraLineSeek == TRUE){
754 // Check if there is extra data on the next line
755 // (indicated by space or tab at the start) and add data.
757 if (itersub == ContactFileLines.end()){
758 ExtraLineSeekSub = FALSE;
766 iterboolsub = ContactFileProcessedWorking.find(itersub->first);
768 if (iterboolsub == ContactFileProcessedWorking.end()){
774 if (iterboolsub->second == TRUE){
780 if (itersub == ContactFileLines.end()){
786 wxSPropertyNextLine = itersub->second;
788 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
790 wxSPropertyNextLine.Remove(0, 1);
791 //wxSPropertyNextLine.Trim(FALSE);
792 //ContactLine.Trim();
793 ContactLine.Append(wxSPropertyNextLine);
794 iterboolsub->second = TRUE;
798 ExtraLineSeek = FALSE;
804 ContactLineLen = ContactLine.Len();
806 for (int i = 0; i <= ContactLineLen; i++){
808 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
810 PropertyFind = FALSE;
812 } else if (PropertyFind == TRUE){
814 wxSProperty.Append(ContactLine.Mid(i, 1));
818 if (ContactLine.Mid(i, 1) == wxT("\"")){
820 if (QuoteMode == TRUE){
832 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
841 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
842 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
844 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1, wxT(";"));
845 wxSProperty = wxSPropertySegSplit.GetNextToken();
847 std::map<int,int> DataLineProcess;
848 std::map<int, bool>::iterator DLSLiter;
850 // Look for the X-VCARD4-(variablename) equivilant.
852 wxSPropertyVCARD4 = wxT("X-VCARD4-") + wxSProperty;
854 // Sort out remainder of the types.
856 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1, &wxSPropertySeg2,
857 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
858 &wxSPropertyNameConv, &PropertyData, &PropertyLock, FALSE, &VCard3Value, &XVCard4Value);
860 wxString FinalPropertyData;
862 FinalPropertyData.Append(wxSPropertyNameConv);
864 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
865 striter != PropertyData.end(); ++striter){
867 FinalPropertyData.Append(wxT(";"));
868 FinalPropertyData.Append(striter->first);
869 FinalPropertyData.Append(wxT("="));
870 FinalPropertyData.Append(striter->second);
874 wxString FinalPropValue;
876 if (wxSPropertyXVCard4Value.IsEmpty()){
878 FinalPropValue = wxSPropertyData;
882 if (wxSPropertyXVCard4Value != wxSPropertyData){
884 FinalPropValue = wxSPropertyXVCard4Value;
890 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
893 wxSPropertySub.Clear();
894 wxSPropertySeg1.Clear();
895 wxSPropertySeg2.Clear();
896 wxSPropertyValues.Clear();
897 wxSPropertyData.Clear();
898 wxSPropertyXVCard4Value.Clear();
899 wxSPropertyNameConv.Clear();
900 //FinalPropertyData.clear();
901 //FinalPropValue.clear();
902 PropertyData.clear();
903 PropertyLock.clear();
905 XVCard4Value = FALSE;
912 int NicknameCount = 0;
921 int RelatedCount = 0;
926 int CategoryCount = 0;
931 int CalReqAdrCount = 0;
932 int FreeBusyCount = 0;
937 int MaxItemNumber = 0;
939 int ItemUnordered = 0;
941 size_t ItemStringSeekLen = 0;
943 int ItemSeekSecSub = 0;
944 //int intValueSeek = 1;
946 std::map<int, wxString> NumberedName;
947 std::map<int, wxString> NumberedData;
948 std::map<int, wxString> NumberedPropValues;
949 std::map<int, wxString> NumberedPropOldValue;
951 std::map<int, wxString> UnNumberedName;
952 std::map<int, wxString> UnNumberedData;
953 std::map<int, wxString> UnNumberedPropValues;
954 std::map<int, wxString> UnNumberedPropOldValue;
956 // Part 1: Get the itemn number.
958 std::map<int,bool>::iterator iterboolsecsub;
959 std::map<int,wxString>::iterator itersub;
960 std::map<int, wxString> TempData;
961 PropertyData.clear();
962 PropertyLock.clear();
964 wxString ItemStringSeek;
965 wxString ItemPropName;
968 ContactLineSub.clear();
969 ExtraLineSeekSub = 0;
970 wxString wxSPropertyNextLineSub;
971 ContactLineSubLen = 0;
973 PropertFindSub.clear();
974 wxSPropertySub.clear();
975 wxSPropertySeg1Sub.clear();
976 wxSPropertySeg2Sub.clear();
977 wxSPropertyValues.clear();
978 wxSPropertyData.clear();
979 wxSPropertyNameConv.clear();
980 wxSPropertyXVCard4Value.clear();
981 ItemProcString.clear();
983 XVCard4Value = FALSE;
985 SeekItemData = FALSE;
987 std::map<wxString, void*> ItemMapIndex;
988 //std::map<wxString, wxString> ItemNameIndex;
990 // Look for item in the initial line, process into a proper line then
991 // look for other lines with the same item association.
993 for (std::map<int,wxString>::iterator iter = ContactFileLines.begin();
994 iter != ContactFileLines.end(); ++iter){
996 ExtraLineSeek = TRUE;
998 iterbool = ContactFileProcessed.find(iter->first);
1000 if (iterbool->second == TRUE){
1006 ContactLine = iter->second;
1008 if (ContactLine.Mid(0, 1) == wxT(" ") || ContactLine.Mid(0, 1) == wxT("\t")){
1014 if (ContactLine.Mid(0, 4) != wxT("item")){
1022 //ContactLineSeekSub = ContactLineSeek;
1023 std::map<int,wxString>::iterator itersub = iter;
1025 while (ExtraLineSeek == TRUE){
1027 // Check if there is extra data on the next line
1028 // (indicated by space or tab at the start) and add data.
1031 iterboolsub = ContactFileProcessed.find(itersub->first);
1033 if (iterboolsub == ContactFileProcessed.end()){
1039 if (iterboolsub->second == TRUE){
1045 if (itersub == ContactFileLines.end()){
1051 wxSPropertyNextLine = itersub->second;
1053 if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
1055 wxSPropertyNextLine.Remove(0, 1);
1056 //wxSPropertyNextLine.Trim(FALSE);
1057 //ContactLine.Trim();
1058 ContactLine.Append(wxSPropertyNextLine);
1059 iterboolsub->second = TRUE;
1063 ExtraLineSeek = FALSE;
1069 ContactLineLen = ContactLine.Len();
1071 for (int i = 0; i <= ContactLineLen; i++){
1073 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1075 PropertyFind = FALSE;
1077 } else if (PropertyFind == TRUE){
1079 wxSProperty.Append(ContactLine.Mid(i, 1));
1083 if (ContactLine.Mid(i, 1) == wxT("\"")){
1085 if (QuoteMode == TRUE){
1097 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1099 QuoteBreakPoint = i;
1106 wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
1107 wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
1109 // Go through the lines and collect the lines like itemn.
1111 std::map<int,wxString> *ItemListData;
1112 ItemListData = new std::map<int,wxString>;
1114 wxStringTokenizer ItemData(wxSPropertySeg1, wxT("."));
1116 ItemString = ItemData.GetNextToken();
1117 ItemStringSeek = wxT("item") + ItemString.Mid(4);
1119 wxStringTokenizer ItemPropSplit(ItemData.GetNextToken(), wxT(";"));
1121 ItemPropName = ItemPropSplit.GetNextToken();
1123 ItemStringSeekLen = ItemStringSeek.Len();
1127 for (std::map<int,wxString>::iterator itersec = ContactFileLines.begin();
1128 itersec != ContactFileLines.end(); ++itersec){
1130 ExtraLineSeek = TRUE;
1132 iterboolsub = ContactFileProcessed.find(itersec->first);
1134 if (iterboolsub->second == TRUE){
1140 ContactLineSub = itersec->second;
1142 wxStringTokenizer ItemProcData(ContactLineSub, wxT("."));
1143 ItemProcString = ItemData.GetNextToken();
1145 if (ItemStringSeek != ContactLineSub.Mid(0, ItemStringSeekLen)){
1153 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1155 iterboolsub->second = TRUE;
1159 //ItemNameIndex.insert(std::make_pair(ItemStringSeek, ItemPropName));
1160 ItemListData->insert(std::make_pair(ItemIndex, ContactLineSub));
1161 ItemMapIndex.insert(std::make_pair(ItemStringSeek, ItemListData));
1165 // Process each itemn set.
1167 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1168 iter != ItemMapIndex.end(); ++iter){
1170 std::map<int, wxString> *ItemDataPtr;
1172 ItemDataPtr = (std::map<int,wxString>*)iter->second;
1174 for (std::map<int,wxString>::iterator itersub = ItemDataPtr->begin();
1175 itersub != ItemDataPtr->end(); ++itersub){
1177 ContactLine = itersub->second;
1179 ContactLineLen = ContactLine.Len();
1181 for (int i = 0; i <= ContactLineLen; i++){
1183 if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
1185 PropertyFind = FALSE;
1187 } else if (PropertyFind == TRUE){
1189 wxSProperty.Append(ContactLine.Mid(i, 1));
1193 if (ContactLine.Mid(i, 1) == wxT("\"")){
1195 if (QuoteMode == TRUE){
1207 if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
1209 QuoteBreakPoint = i;
1216 wxSPropertySeg1Sub = ContactLine.Mid(0, QuoteBreakPoint);
1217 wxSPropertySeg2Sub = ContactLine.Mid((QuoteBreakPoint + 1));
1219 wxStringTokenizer wxSPropertySegSplit(wxSPropertySeg1Sub, wxT(";"));
1220 wxSProperty = wxSPropertySegSplit.GetNextToken();
1222 // Sort out remainder of the types.
1224 // Skip certain X-* IM variables as they are processed via
1227 if (wxSProperty == wxT("X-AIM") || wxSProperty == wxT("X-MSN") ||
1228 wxSProperty == wxT("X-ICQ") || wxSProperty == wxT("X-GADUGADU") ||
1229 wxSProperty == wxT("X-YAHOO") || wxSProperty == wxT("X-SKYPE") ||
1230 wxSProperty == wxT("X-JABBER")){
1232 wxSProperty.clear();
1233 wxSPropertySub.Clear();
1234 wxSPropertySeg1.Clear();
1235 wxSPropertySeg2.Clear();
1236 wxSPropertyValues.Clear();
1237 wxSPropertyData.Clear();
1238 wxSPropertyXVCard4Value.Clear();
1239 wxSPropertyNameConv.Clear();
1240 //FinalPropertyData.clear();
1241 //FinalPropValue.clear();
1242 PropertyData.clear();
1243 PropertyLock.clear();
1244 ContactLine.clear();
1245 XVCard4Value = FALSE;
1246 VCard3Value = FALSE;
1251 ConvertV4PropertyProc(&wxSProperty, &wxSPropertySeg1Sub, &wxSPropertySeg2Sub,
1252 &wxSPropertyValues, &wxSPropertyData, &wxSPropertyXVCard4Value,
1253 &wxSPropertyNameConv, &PropertyData, &PropertyLock, TRUE, &VCard3Value, &XVCard4Value);
1257 if (wxSPropertyNameConv.IsEmpty()){
1259 wxSProperty.clear();
1260 wxSPropertySub.Clear();
1261 wxSPropertySeg1.Clear();
1262 wxSPropertySeg2.Clear();
1263 wxSPropertyValues.Clear();
1264 wxSPropertyData.Clear();
1265 wxSPropertyXVCard4Value.Clear();
1266 wxSPropertyNameConv.Clear();
1267 //FinalPropertyData.clear();
1268 //FinalPropValue.clear();
1269 PropertyData.clear();
1270 PropertyLock.clear();
1271 ContactLine.clear();
1272 XVCard4Value = FALSE;
1273 VCard3Value = FALSE;
1278 wxString FinalPropertyData;
1280 FinalPropertyData.Append(wxSPropertyNameConv);
1282 for (std::map<wxString, wxString>::iterator striter = PropertyData.begin();
1283 striter != PropertyData.end(); ++striter){
1285 FinalPropertyData.Append(wxT(";"));
1286 FinalPropertyData.Append(striter->first);
1287 FinalPropertyData.Append(wxT("="));
1288 FinalPropertyData.Append(striter->second);
1292 wxString FinalPropValue;
1294 if (wxSPropertyXVCard4Value.IsEmpty()){
1296 FinalPropValue = wxSPropertyData;
1300 if (wxSPropertyXVCard4Value != wxSPropertyData){
1302 FinalPropValue = wxSPropertyData;
1306 FinalPropValue = wxSPropertyXVCard4Value;
1312 vCardOut->AddRaw(FinalPropertyData, FinalPropValue);
1314 wxSProperty.clear();
1315 wxSPropertySub.Clear();
1316 wxSPropertySeg1Sub.Clear();
1317 wxSPropertySeg2Sub.Clear();
1318 wxSPropertyValues.Clear();
1319 wxSPropertyData.Clear();
1320 wxSPropertyXVCard4Value.Clear();
1321 wxSPropertyNameConv.Clear();
1322 FinalPropertyData.clear();
1323 FinalPropValue.clear();
1324 PropertyData.clear();
1325 PropertyLock.clear();
1326 ContactLine.clear();
1327 XVCard4Value = FALSE;
1328 VCard3Value = FALSE;
1331 //PropertyData.clear();
1332 //PropertyLock.clear();
1338 std::map<int, wxString> *ItemEraseData;
1340 for (std::map<wxString, void*>::iterator iter = ItemMapIndex.begin();
1341 iter != ItemMapIndex.end(); ++iter){
1343 ItemEraseData = (std::map<int,wxString>*)iter->second;
1345 delete ItemEraseData;
1346 ItemEraseData = NULL;
1350 ItemMapIndex.clear();
1352 vCardOut->AddRaw(wxT("END"), wxT("VCARD"));