Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
camelCase: Converted code in calendarobject directory
[xestiacalendar/.git] / source / objects / calendarobject / CalendarObject.cpp
1 // CalendarObject.cpp - CalendarObject class functions
2 //
3 // (c) 2016-2017 Xestia Software Development.
4 //
5 // This file is part of Xestia Calendar.
6 //
7 // Xestia Calendar 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 Calendar 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 Calendar. If not, see <http://www.gnu.org/licenses/>
19 #include "CalendarObject.h"
20 #include "../../common/file.h"
22 using namespace std;
24 CalendarObjectLoadResult CalendarObject::LoadFile(std::string loadFilename){
26         // Check if the file exists and return 
27         // CALENDAROBJECTLOAD_CANNOTOPEN if not.
28         
29         if (!FileExists(loadFilename)){
30                 return CALENDAROBJECTLOAD_MISSING;
31         }
32         
33         ifstream fileStream;
34         string receivedStringData = "";
35         
36         fileStream.open(loadFilename, ifstream::in);
37         
38         if (fileStream.rdstate() & ifstream::failbit){
39                 return CALENDAROBJECTLOAD_CANNOTOPEN;
40         }
42         if (fileStream.rdstate() & ifstream::badbit){
43                 return CALENDAROBJECTLOAD_CANNOTOPEN;
44         }
45         
46         // Read the data into a string.
47         
48         char *bufferRead = new char[256];
49         
50         while (!fileStream.eof()){
51                 
52                 fileStream.getline(bufferRead, 256);
53                 receivedStringData.append(bufferRead);
54                 receivedStringData.append("\n");
55                 
56         }
57         
58         delete[] bufferRead;
59         
60         CalendarObjectLoadResult stringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL;
61         
62         stringProcResult = LoadString(&receivedStringData);
63         
64         return stringProcResult;
65         
66 }
68 CalendarObjectLoadResult CalendarObject::LoadString(std::string *loadStringData){
70         bool newLine = false;
71         bool skipMode = false;
72         bool colonFound = false;
73         bool quoteMode = false;
74         char bufferChar = 0;
75         int stringDataSize = LoadStringData->size();
76         int seekCount = 0;
77         string propertyName;
78         string propertyValue;
80         while (seekCount < stringDataSize){
81                 
82                 // Check if character is blank or a tab and is the first character
83                 // on a new line.
84                 
85                 if (((*loadStringData)[seekCount] == ' ' || 
86                         (*loadStringData)[seekCount] == '\t')
87                         && newLine == true){
88                         
89                         // Character is on a new line and it is a space or
90                         // tab. Ignore this character as it is not part
91                         // of the value.
93                         newLine = false;
94                                 
95                 } else if ((*loadStringData)[seekCount] == '\"'){
96                         
97                         if (quoteMode == false){
98                                 quoteMode = true;
99                         } else {
100                                 quoteMode = false;
101                         }
102                         
103                         bufferChar = (*loadStringData)[seekCount];
104                         
105                         if (colonFound == false){
106                                 propertyName += bufferChar;
107                         } else {
108                                 propertyValue += bufferChar;
109                         }
110                         
111                 } else if (newLine == true){
112                 
113                         // Character is on a new line but not a space or
114                         // tab so check if the colon has been found
115                         // and add the property name and value to
116                         // the lists.
118                         if (colonFound == true){
119                                 objectName.push_back(propertyName);
120                                 objectData.push_back(propertyValue);
121                         }
122                         
123                         colonFound = false;
124                         newLine = false;
125                         propertyName.clear();
126                         propertyValue.clear();
127                         
128                         bufferChar = (*loadStringData)[seekCount];
129                         propertyName += bufferChar;
130                         
131                 } else if ((*loadStringData)[seekCount] == '\n'){
132                 
133                         // Character is the new line character so mark
134                         // the NewLine boolean as true.
135                         
136                         newLine = true;
137                         
138                 } else if ((*loadStringData)[seekCount] == ':' &&
139                                 quoteMode == false){
140                 
141                         // Character is the colon. Set the colon
142                         // found boolen to true.
143                         
144                         bufferChar = (*loadStringData)[seekCount];
145                                         
146                         if (colonFound == true){
147                                 propertyValue += bufferChar;
148                         } else {
149                                 colonFound = true;
150                         }
151                         
152                 } else {
153                         
154                         // Character is not part of a new line and is not
155                         // the new line character itself.
156                         
157                         bufferChar = (*loadStringData)[seekCount];
158                         
159                         if (colonFound == false){
160                                 propertyName += bufferChar;
161                         } else {
162                                 propertyValue += bufferChar;
163                         }
164                         
165                 }
166                 
167                 seekCount++;
168                 
169         }
170         
171         // Finish off processing any data that wasn't processed
172         // when the end of the string was reached.
173         
174         if (colonFound == true && 
175                 propertyName.size() > 0 &&
176                 propertyValue.size() > 0){
177                 
178                 objectName.push_back(propertyName);
179                 objectData.push_back(propertyValue);
180                         
181         }
182         
183         // Check that the object contains valid data.
184         
185         CalendarObjectLoadResult stringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL;
186         CalendarObjectValidResult baseDataResult = ValidBaseObject();
187         CalendarObjectValidResult eventDataResult = ValidObject();
188         
189         if (baseDataResult != CALENDAROBJECTVALID_OK || 
190                 eventDataResult != CALENDAROBJECTVALID_OK){
191                         
192                 stringProcResult = CALENDAROBJECTLOAD_INVALIDFORMAT;
193                         
194         } else {
195                 
196                 stringProcResult = CALENDAROBJECTLOAD_OK;
197                 
198         }
199         
200         processBaseData();
201         processData();
202         
203         return stringProcResult;
204         
207 CalendarObjectValidResult CalendarObject::ValidBaseObject(){
208         
209         bool validBegin = false;
210         bool validAlarmBegin = false;
211         bool validVersion = false;
212         bool validEnd = false;
213         int seekCount = 0;
214         vector<int> deleteLines;
215         vector<string> alarmObjectName;
216         vector<string> alarmObjectData;
217         
218         // Check that the first line contains BEGIN:VCALENDAR
219         // and it only appears once.
220         
221         for (vector<string>::iterator iter = objectName.begin();
222                 iter != objectName.end(); iter++){
224                 if (objectName[seekCount] == "BEGIN" &&
225                         objectData[seekCount] == "VCALENDAR"){
226                         
227                         if (validBegin == false){
228                                 validBegin = true;
229                         } else {
230                                 return CALENDAROBJECTVALID_INVALIDFORMAT;
231                         }
232                                 
233                 }
234                 
235                 if (objectName[seekCount] == "END" &&
236                         objectData[seekCount] == "VCALENDAR" &&
237                         validBegin == false){
238                 
239                         return CALENDAROBJECTVALID_INVALIDFORMAT;
240                                 
241                 } else if (objectName[seekCount] == "END" &&
242                         objectData[seekCount] == "VALARM" &&
243                         validAlarmBegin == false){
245                         return CALENDAROBJECTVALID_INVALIDFORMAT;
246                                 
247                 } else if (objectName[seekCount] == "END" &&
248                         objectData[seekCount] == "VCALENDAR" &&
249                         validAlarmBegin == true){
251                         return CALENDAROBJECTVALID_INVALIDFORMAT;
252                                 
253                 }
254                 
255                 // Look for any VALARM sections.
256                 
257                 if (validAlarmBegin == true){
258                         
259                         alarmObjectName.push_back(objectName[seekCount]);
260                         alarmObjectData.push_back(objectData[seekCount]);
261                         deleteLines.push_back(seekCount);
262                         
263                 }
264                 
265                 if (objectName[seekCount] == "END" &&
266                         objectData[seekCount] == "VALARM" && 
267                         validAlarmBegin == true){
268                                 
269                         eventAlarmName.push_back(AlarmObjectName);
270                         eventAlarmData.push_back(AlarmObjectData);
271                         
272                         alarmObjectName.clear();
273                         alarmObjectData.clear();
275                         validAlarmBegin = false;
276                                 
277                 }
278                 
279                 if (objectName[seekCount] == "BEGIN" &&
280                         objectData[seekCount] == "VALARM" && 
281                         validBegin == true){
282                                 
283                         if (validAlarmBegin == false){
284                                 validAlarmBegin = true;
285                         } else {
286                                 return CALENDAROBJECTVALID_INVALIDFORMAT;
287                         }
288                         
289                         alarmObjectName.push_back(objectName[seekCount]);
290                         alarmObjectData.push_back(objectData[seekCount]);
291                         deleteLines.push_back(seekCount);
292                         
293                 }
294                 
295                 seekCount++;
296                         
297         }
298         
299         seekCount = 0;
300         
301         // Check that the last line contains END:VCALENDAR
302         // and it only appears once.
303         
304         for (vector<string>::iterator iter = objectName.begin();
305                 iter != objectName.end(); iter++){
306                 
307                 if (objectName[seekCount] == "END" &&
308                         objectData[seekCount] == "VCALENDAR"){
309                         
310                         if (validEnd == false){
311                                 validEnd = true;
312                         } else {
313                                 return CALENDAROBJECTVALID_INVALIDFORMAT;
314                         }
315                                 
316                 }
317                         
318                 seekCount++;
319                         
320         }
321         
322         seekCount = 0;
323         
324         // Check that the VERSION value contains 2.0 and that
325         // it only appears once.
326         
327         for (vector<string>::iterator iter = objectName.begin();
328                 iter != objectName.end(); iter++){
329                 
330                 if (objectName[seekCount] == "VERSION" &&
331                         objectData[seekCount] == "2.0"){
332                         
333                         if (validVersion == false){
334                                 validVersion = true;
335                         } else {
336                                 return CALENDAROBJECTVALID_INVALIDFORMAT;
337                         }
338                                 
339                 }
340                 
341                 seekCount++;
342                         
343         }
345         // Remove lines that aren't needed as they have
346         // been moved to the EventAlarm section.
347         
348         for (vector<int>::reverse_iterator deliter = deleteLines.rbegin();
349                 deliter != deleteLines.rend(); deliter++){
351                 objectName.erase(objectName.begin()+(*deliter));
352                 objectData.erase(objectData.begin()+(*deliter));
353                         
354         }
356         if (validBegin == true && 
357                 validEnd == true && 
358                 validVersion == true &&
359                 validAlarmBegin == false){
360         
361                 return CALENDAROBJECTVALID_OK;
362                         
363         } else {
364                 
365                 return CALENDAROBJECTVALID_INVALIDFORMAT;
366                 
367         }
368         
371 void CalendarObject::ProcessBaseData(){
372         
373         // Process the base object data.
374         
375         multimap<string,string> dataReceived;
376         
377         // Get the method (METHOD).
378         
379         dataReceived = ProcessTextVectors(&objectName, &objectData, false, "METHOD");
380         
381         if (dataReceived.begin() != dataReceived.end()){
382                 
383                 try {
384                         methodTokens = dataReceived.begin()->first.substr(7);
385                 }
386                 
387                 catch(const out_of_range &oor){
388                         // Do nothing as there is no data.
389                 }               
390                 
391                 methodData = dataReceived.begin()->second;
392                 
393         }
394         
395         // Get the calendar scale (CALSCALE).
396         
397         dataReceived = ProcessTextVectors(&objectName, &objectData, false, "CALSCALE");
398         
399         if (dataReceived.begin() != dataReceived.end()){
400                 
401                 try {
402                         calendarScaleTokens = dataReceived.begin()->first.substr(9);
403                 }
404                 
405                 catch(const out_of_range &oor){
406                         // Do nothing as there is no data.
407                 }               
408                 
409                 calendarScaleData = dataReceived.begin()->second;
410                 
411         }
412         
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