Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Initial import of code already done for Xestia Address Book
[xestiaab/.git] / source / vcard / vcard.cpp
1 #include "vcard.h"
2 #include <wx/file.h>
3 #include <wx/ffile.h>
4 #include <wx/tokenzr.h>
5 #include <cmath>
7 // vcard.cpp - Deals with vCard 4.0 formatted files meeting the
8 // RFC 6350 specification.
10 vCard::vCard(){
11     vCardBegin = FALSE;
12     vCardEnd = FALSE;
13     vCardFN = FALSE;
14     vCardVersion = 0.0;
15     SettingCount = 0;
16 }
18 void vCard::Add(wxString SettingName, wxString SettingValue, bool ReplaceMode){  
19     
20     // Check for backslashes used for commas, newlines and
21     // backslashes used for values.
22     
23     if (ReplaceMode == TRUE){
24     
25         SettingValue.Replace(wxT("\\n"), wxT("\n"));
26         SettingValue.Replace(wxT("\\,"), wxT(","));
27         SettingValue.Replace(wxT("\\:"), wxT(":"));
28         SettingValue.Replace(wxT("\\\\"), wxT("\\"));
29     
30     } else {
32         SettingValue.Replace(wxT("\\"), wxT("\\\\"));
33         SettingValue.Replace(wxT("\n"), wxT("\\n"));
34         SettingValue.Replace(wxT(","), wxT("\\,"));
35         SettingValue.Replace(wxT(":"), wxT("\\:"));
36         SettingValue = SettingValue + wxT("\n");
37     
38     }
39   
40     // Check data to make sure that it meets the required
41     // vCard 4.0 specifications.
42     
43         if (SettingName == wxT("BEGIN") && SettingValue == wxT("VCARD")){
44                 vCardBegin = TRUE;
45         }
46     
47         if (SettingName == wxT("END") && SettingValue == wxT("VCARD")){
48                 vCardEnd = TRUE;
49         }
50     
51         if (SettingName == wxT("FN")){
52                 vCardFN = TRUE;
53         }
54     
55         if (SettingName == wxT("VERSION") && SettingValue == wxT("4.0")){
56                 vCardVersion = 4.0;
57         }
58     
59         if (SettingName == wxT("VERSION") && SettingValue == wxT("3.0")){
60                 vCardVersion = 3.0;
61         }
62     
63         if (SettingName == wxT("VERSION") && SettingValue == wxT("3.0")){
64                 vCardVersion = 2.0;
65         }
66     
67     SettingValue.Trim();    
68     
69     if (SettingValue.Right(2) != wxT("\r\n")){
70     
71         SettingValue.Append(wxT("\r\n"));
72     
73     }
74     
75     SettingNames.Add(SettingName, 1);
76     SettingValues.Add(SettingValue, 1);      
77     
78     ++SettingCount;
79 }
81 void vCard::AddRaw(wxString SettingName, wxString SettingValue){  
82   
83     // Check data to make sure that it meets the required
84     // vCard 4.0 specifications.
85     
86     if (SettingName == wxT("BEGIN") && SettingValue == wxT("VCARD")){
87         vCardBegin = TRUE;
88     }
89     
90     if (SettingName == wxT("END") && SettingValue == wxT("VCARD")){
91         vCardEnd = TRUE;
92     }
93     
94     if (SettingName == wxT("FN")){
95         vCardFN = TRUE;
96     }
97     
98     if (SettingName == wxT("VERSION") && SettingValue == wxT("4.0")){   
99         vCardVersion = 4.0;
100     }
102     if (SettingName == wxT("VERSION") && SettingValue == wxT("3.0")){   
103         vCardVersion = 3.0;
104     }
105     
106     if (SettingName == wxT("VERSION") && SettingValue == wxT("3.0")){   
107         vCardVersion = 2.0;
108     }
109     
110     SettingValue.Trim();
111     
112     if (SettingValue.Right(2) != wxT("\r\n")){
113     
114         SettingValue.Append(wxT("\r\n"));
115     
116     }
117         
118     SettingNames.Add(SettingName, 1);
119     SettingValues.Add(SettingValue, 1);      
120     
121     ++SettingCount;
124 wxString vCard::Get(wxString SettingName){
125   
126     wxString SettingValue;
127     
128     // Look for the setting name.
129     
130     for (int i = 0; i < SettingCount; i++){
131       
132         if (SettingNames[i] == SettingName){
133         
134             SettingValue = SettingValues[i];
135             SettingValue.Trim(TRUE);
136                     
137             while (SettingValues[(i + 1)].Mid(0, 1) == wxT(" ") || SettingValues[(i + 1)].Mid(0, 1) == wxT("\t")){
138                 
139                 SettingValue.Trim();
140                 SettingValue.Append(SettingValues[(i + 1)]);
141                 
142                 i++;
143             }
144             
145             return SettingValue;
146         }
147     }
149         return wxEmptyString;
153 vCardName vCard::GetName(){
155         vCardName NameData;
156         ArrayvCardOutData NameArray = this->GetByPartial(wxT("N"));
157         //wxString NameDataGet = NameArray.PropValues[0];
158         wxString NameDataGet = NameArray.PropValues[0];
159         std::map<int, int> SplitPoints;
160         std::map<int, int> SplitLength;
161         std::map<int, int>::iterator SLiter;
162         
163         // Process the name data to get the required information.
164         
165         int intPropertyLen = NameDataGet.Len();
166         int intSplitSeek = 0;
167         int intSplitsFound = 0;
168         int intSplitSize = 0;
169         int intPrevValue = 0;                                   
170         
171         for (int i = 0; i <= intPropertyLen; i++){
173                 intSplitSize++;
174         
175                 if (NameDataGet.Mid(i, 1) == wxT(";") && NameDataGet.Mid((i - 1), 1) != wxT("\\")){
176         
177                         intSplitsFound++;
178                         SplitPoints.insert(std::make_pair(intSplitsFound, (i + 1)));
179                         
180                         if (intSplitsFound == 4){ 
181                         
182                                 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
183                                 break; 
184                                 
185                         } else {
186                         
187                                 SplitLength.insert(std::make_pair(intSplitsFound, (intSplitSize - 1)));
188                         
189                         }
190                         
191                         intSplitSize = 0;                                       
192         
193                 }
195         }
196         
197         for (std::map<int, int>::iterator intiter = SplitPoints.begin(); 
198         intiter != SplitPoints.end(); ++intiter){
199         
200                 if (intiter->first == 1){
201                 
202                         // Deal with family name.
203                         
204                         SLiter = SplitLength.find(1);
206                         NameData.Surname = NameDataGet.Mid(0, SLiter->second);                          
207                         intPrevValue = intiter->second;
208                 
209                 } else if (intiter->first == 2){
210                 
211                         // Deal with given names.
212                         
213                         SLiter = SplitLength.find(2);
215                         NameData.Forename = NameDataGet.Mid(intPrevValue, SLiter->second);                      
216                         intPrevValue = intiter->second;
218                 
219                 } else if (intiter->first == 3){
220                 
221                         // Deal with additional names.
222                         
223                         SLiter = SplitLength.find(3);
225                         NameData.OtherNames = NameDataGet.Mid(intPrevValue, SLiter->second);
226                         intPrevValue = intiter->second;
227                 
228                 } else if (intiter->first == 4){
229                 
230                         // Deal with honorifix prefixes and suffixes.
231                         SLiter = SplitLength.find(4);
233                         NameData.Title = NameDataGet.Mid(intPrevValue, SLiter->second);                 
234                         intPrevValue = intiter->second;
235                         NameData.Suffix = NameDataGet.Mid(intPrevValue);
236                 
237                 }
238         
239         }
240         
241         return NameData;
242         
246 ArrayvCardOutData vCard::GetByPartial(wxString SettingName){
248     ArrayvCardOutData vCardOutData;
249     wxArrayString SettingList;
250     wxString SettingValueCurrent;
251     wxString SettingValue;
252     int SettingNameLen;
253     int SettingNameSeek;
254     bool FirstToken = TRUE;
255     
256     SettingNameLen = SettingName.Len();
258     for (int i = 0; i < SettingCount; i++){
259     
260         if (SettingNames[i].Mid(0, SettingNameLen) == SettingName){
261             
262             SettingValue = SettingValues[i];
263             SettingNameSeek = i;            
264             
265             while (SettingValues[(i + 1)].Mid(0, 1) == wxT(" ") || SettingValues[(i + 1)].Mid(0, 1) == wxT("\t")){
266                 
267                 if (FirstToken == TRUE){
268                 
269                         SettingValue.Trim(FALSE);
270                         SettingValue.Trim(TRUE);                                
271                         FirstToken = FALSE;
272                 
273                 }
274                 
275                 SettingValueCurrent = SettingValues[(i + 1)];
276                 SettingValueCurrent.Trim(FALSE);
277                 SettingValueCurrent.Trim(TRUE);         
278                 
279                 SettingValue.Append(SettingValueCurrent);
280                 
281                 i++;
282                 
283             }
284             
285             //SettingList.Add(SettingNames[SettingNameSeek] + wxT(":") + SettingValue);
286             vCardOutData.PropData.Add(SettingNames[SettingNameSeek]);
287             vCardOutData.PropValues.Add(SettingValue);
288             vCardOutData.PropCount++;
289             
290         }
291     }
292     
293     /*for (int i = 0; i < SettingCount; i++){
294         if (SettingNames[i].Mid(0, SettingNameLen) == SettingName){
295             
296             SettingValue = SettingValues[i];
297             SettingNameSeek = i;            
298             
299             while (SettingValues[(i + 1)].Mid(0, 1) == wxT(" ") || SettingValues[(i + 1)].Mid(0, 1) == wxT("\t")){
300                 
301                 SettingValueCurrent = SettingValues[(i + 1)];
302                 SettingValueCurrent.Trim(FALSE);
303                 SettingValueCurrent.Trim(TRUE);         
304                 
305                 SettingValue.Append(SettingValueCurrent);
306                 
307                 i++;
308                 
309             }
310             
311             //SettingList.Add(SettingNames[SettingNameSeek] + wxT(":") + SettingValue);
312             vCardOutData.PropData.Add(SettingName);
313             vCardOutData.PropData.Add(SettingValue);
314             
315         }
316     }*/
317     
318     return vCardOutData;
322 wxString vCard::GetById(int id){
323         // Unimplemented.
324         return wxT("");
327 int vCard::WriteFile(wxString WriteFilename){
329     // Open the file and begin writing data into the file.
330     
331     wxString SettingName;
332     wxString SettingValue;
333     wxString SettingLine;
334     
335     SettingCount = SettingNames.GetCount();
336     
337     wxFile ContactFile;
338     if (ContactFile.Create(WriteFilename, TRUE, wxS_DEFAULT) == FALSE){
339         return 1;
340     }
341     
342     for (int i = 0; i < SettingCount; i++){
343     
344         SettingLine = SettingNames[i] + wxT(":") + SettingValues[i];
345     
346         int SettingLineLen = SettingLine.Len();
347         int intDivider = 74;
348         int intTimes = floor((SettingLine.Len() / intDivider));
349         int intSeek = 0;
350         int intLineSeek = 0;
351         int intPrevLine;
352         bool FirstLine = TRUE;
353     
354         // Remember to round down the calculation.
356         while (intSeek < SettingLineLen){
357         
358                 if ((intLineSeek == intDivider && FirstLine == TRUE) ||
359                 (intLineSeek == (intDivider - 1) && FirstLine == FALSE)){
360                 
361                         SettingLine.insert(intSeek, wxT("\r\n "));
362                         intSeek = intSeek + 3;
363                         SettingLineLen = SettingLineLen + 3;
364                         intLineSeek = 0;
365                         intPrevLine = intSeek;
366                         FirstLine = FALSE;
367                 
368                 }
369         
370                 intSeek++;
371                 intLineSeek++;
372         
373         }
375         /*
377         for (int x = 0; x < intTimes; x++){     
378         
379             if (x == 0){
380                 SettingLine.insert((intDivider - 1), wxT("\r\n "));
381             } else if (x == intTimes){
382             
383             } else {
384                 if (x < intDivider){
385                         SettingLine.insert((intDivider * (x+1)) + (x * 3), wxT("\r\n "));
386                 }
387             }
388             
389             intTimes = floor(SettingLine.Len() / intDivider);
390         
391         }
392         
393         */
394         
395         ContactFile.Write(SettingLine);
396         
397     }
398     
399     ContactFile.Close();
401     return 0;
405 int vCard::LoadFile(wxString LoadFilename){
407     wxFFile ContactFile;
408   
409     wxString wxSContactString;
410   
411     vCardFilename = LoadFilename;
412         
413     // Check if we are using wxWidgets version 2.8 or less and
414     // execute the required command accordingly.
415     
416 #if wxABI_VERSION < 20900
417     ContactFile.Open(LoadFilename.c_str(), wxT("r"));
418 #else
419     ContactFile.Open(LoadFilename, wxT("r"));
420 #endif  
421         
422     if (ContactFile.IsOpened() == FALSE){
423         
424                 return 1;
425         
426     }
427         
428     ContactFile.ReadAll(&wxSContactString, wxConvAuto());
429     
430     ContactFile.Close();
431     
432     ProcessString(&wxSContactString);
434         return 0;
438 int vCard::LoadString(wxString ContactData){
440     ProcessString(&ContactData);
442         return 0;
446 void vCard::ProcessString(wxString *ContactDataInc){
448     // Split the vCards (if there are more than one vCard in the file).
450     wxString ContactLine;
452     int ContactLineLen;
453     bool ExtraLineSeek = FALSE;
454     int QuoteBreakPoint = 0;
455     
456     bool PropertyFind = FALSE;
457     bool QuoteMode = FALSE;
458    
459     wxString wxSPropertyNextLine;
460     wxString wxSProperty;
461     wxString wxSPropertySeg1;
462     wxString wxSPropertySeg2;
463     
464     bool FoundBegin = FALSE;
465     bool FoundEnd = FALSE;
466     bool FirstContact = TRUE;
467     wxString FirstContactData;
468     wxString ContactData;
469     int ContactCount = 0;
470     
471     wxStringTokenizer wSTContactFileLines(*ContactDataInc, wxT("\r\n"));
472     
473     while(wSTContactFileLines.HasMoreTokens() == TRUE){
474     
475         ContactLine = wSTContactFileLines.GetNextToken();
476         
477         if (ContactLine == wxT("BEGIN:VCARD")){
478                 
479                 if (FoundBegin == TRUE){
480                 
481                         // No END:VCARD was found so discard current data.
482                         
483                         ContactData.Clear();
484                 
485                         if (FirstContact == TRUE){
486                         
487                                 FirstContactData.Clear();
488                         
489                         }
490                 
491                 }
492                 
493                 FoundBegin = TRUE;
494                 
495                 FirstContactData.Append(ContactLine + wxT("\r\n"));
496                 ContactData.Append(ContactLine + wxT("\r\n"));
497                 
498         } else if (ContactLine == wxT("END:VCARD") && FoundBegin == TRUE){
499         
500                 if (FirstContact == TRUE){
501                 
502                         FirstContact = FALSE;
503                         FirstContactData.Append(ContactLine + wxT("\r\n"));
504                 
505                 }
506                 
507                 ContactData.Append(ContactLine + wxT("\r\n"));
508                                 
509                 Cards.insert(std::make_pair(ContactCount, ContactData));
510         
511                 ContactCount++;
512         
513         } else if (FoundBegin == TRUE){
514         
515                 if (FirstContact == TRUE){
516                 
517                         FirstContactData.Append(ContactLine + wxT("\r\n"));
518                 
519                 }
520                 
521                 ContactData.Append(ContactLine + wxT("\r\n"));
522         
523         }
524     
525     }
527     ContactLine.Clear();
528     
529     // Split the lines.
530         
531     std::map<int, wxString> ContactFileLines;
532     std::map<int, wxString>::iterator striter;
533         
534     wxStringTokenizer wSTFirstContactLines(FirstContactData, wxT("\r\n"));
536     int ContactLineSeek = 0;
538     while (wSTFirstContactLines.HasMoreTokens() == TRUE){
540         ContactLine = wSTFirstContactLines.GetNextToken();
541         ContactFileLines.insert(std::make_pair(ContactLineSeek, ContactLine));
542         ContactLineSeek++;              
543         
544     }
545     
546     for (std::map<int,wxString>::iterator iter = ContactFileLines.begin(); 
547         iter != ContactFileLines.end(); ++iter){
549         // Find the colon which splits the start bit from the data part.
550         
551         ContactLine = iter->second;
552         
553         while (ExtraLineSeek == TRUE){
554         
555             // Check if there is extra data on the next line 
556             // (indicated by space or tab at the start) and add data.
557         
558             iter++;
559                 
560             if (iter == ContactFileLines.end()){
561                 
562                 iter--;
563                 break;
564                 
565             }                   
566         
567             wxSPropertyNextLine = iter->second;
568                 
569         
570             if (wxSPropertyNextLine.Mid(0, 1) == wxT(" ") || wxSPropertyNextLine.Mid(0, 1) == wxT("\t")){
571         
572                 wxSPropertyNextLine.Remove(0, 1);
573                 //wxSPropertyNextLine.Trim(FALSE);
574                 //ContactLine.Trim();
575                 ContactLine.Append(wxSPropertyNextLine);
576         
577             } else {
578                 
579                 iter--;
580                 ExtraLineSeek = FALSE;
581                 
582             }
583         
584         }
586         ContactLineLen = ContactLine.Len();
587         
588         // Make sure we are not in quotation mode.
589         // Make sure colon does not have \ or \\ before it.
590         
591         for (int i = 0; i <= ContactLineLen; i++){
592         
593             if ((ContactLine.Mid(i, 1) == wxT(";") || ContactLine.Mid(i, 1) == wxT(":")) && PropertyFind == TRUE){
594                 
595                         PropertyFind = FALSE;
596                 
597             } else if (PropertyFind == TRUE){
598                 
599                         wxSProperty.Append(ContactLine.Mid(i, 1));
600                 
601             }           
602         
603             if (ContactLine.Mid(i, 1) == wxT("\"")){
604                 
605                 if (QuoteMode == TRUE){
606                         
607                     QuoteMode = FALSE;
608                         
609                 } else {
610                 
611                     QuoteMode = TRUE;
612                                 
613                 }
614                 
615             }
616                 
617             if (ContactLine.Mid(i, 1) == wxT(":") && ContactLine.Mid((i - 1), 1) != wxT("\\") && QuoteMode == FALSE){
618                 
619                 QuoteBreakPoint = i;
620                 break;
621                 
622             }
623         
624         }
625         
626         // Split that line at the point into two variables (ignore the colon).
627         
628         wxSPropertySeg1 = ContactLine.Mid(0, QuoteBreakPoint);
629         wxSPropertySeg2 = ContactLine.Mid((QuoteBreakPoint + 1));
630         
631         // Insert both into the vCard data file.
632         
633         AddRaw(wxSPropertySeg1, wxSPropertySeg2);
634         
635         QuoteMode = FALSE;
636         PropertyFind = TRUE;
637         ExtraLineSeek = TRUE;
638         ContactLineLen = 0;
639         QuoteBreakPoint = 0;
640         ContactLine.Clear();
641         wxSProperty.Clear();
642         
643     }
648 wxString vCard::WriteString(){
650     // Open the file and begin writing data into the file.
651     
652     wxString SettingName;
653     wxString SettingValue;
654     wxString SettingLine;
655     wxString SettingFinal;
656     
657     SettingCount = SettingNames.GetCount();
658     
659     for (int i = 0; i < SettingCount; i++){
660     
661         SettingLine = SettingNames[i] + wxT(":") + SettingValues[i];
662     
663         int SettingLineLen = SettingLine.Len();
664         int intDivider = 74;
665         int intTimes = floor((SettingLine.Len() / intDivider));
666         int intSeek = 0;
667         int intLineSeek = 0;
668         int intPrevLine;
669         bool FirstLine = TRUE;
670     
671         // Remember to round down the calculation.
673         while (intSeek < SettingLineLen){
674         
675                 if ((intLineSeek == intDivider && FirstLine == TRUE) ||
676                 (intLineSeek == (intDivider - 1) && FirstLine == FALSE)){
677                 
678                         SettingLine.insert(intSeek, wxT("\r\n "));
679                         intSeek = intSeek + 3;
680                         SettingLineLen = SettingLineLen + 3;
681                         intLineSeek = 0;
682                         intPrevLine = intSeek;
683                         FirstLine = FALSE;
684                 
685                 }
686         
687                 intSeek++;
688                 intLineSeek++;
689         
690         }
691         
692         SettingFinal.Append(SettingLine);
693         
694     }
695     
696     return SettingFinal;
700 bool vCard::MeetBaseSpecification(){
701     // Check and see if the vCard object meets the base specification
702     // of vCard 4.0.
703     
704     if (vCardBegin == TRUE && vCardEnd == TRUE && vCardFN == TRUE &&
705         vCardVersion == 4.0){
706         return TRUE;
707     } else {
708         return FALSE;
709     }
710     
713 wxString vCard::Convert(wxString SettingValue, bool ReplaceMode){  
714     
715     // Check for backslashes used for commas, newlines and
716     // backslashes used for values.
717     
718     if (ReplaceMode == TRUE){
719     
720         SettingValue.Replace(wxT("\\n"), wxT("\n"));
721         SettingValue.Replace(wxT("\\,"), wxT(","));
722         SettingValue.Replace(wxT("\\;"), wxT(";"));
723         SettingValue.Replace(wxT("\\\\"), wxT("\\"));
724     
725     } else {
727         SettingValue.Replace(wxT("\\"), wxT("\\\\"));
728         SettingValue.Replace(wxT("\n"), wxT("\\n"));
729         SettingValue.Replace(wxT(","), wxT("\\,"));
730         SettingValue.Replace(wxT(";"), wxT("\\;"));
731         SettingValue = SettingValue + wxT("\n");
732     
733     }
734     
735     return SettingValue;
736     
739 wxString vCard::GetFilename(){
741     return vCardFilename;
745 std::map<int,wxString>* vCard::GetAllCards(){
747     return &Cards;
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy