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