1 #include "CalendarObject.h"
2 #include "../../common/file.h"
6 CalendarObjectLoadResult CalendarObject::LoadFile(std::string LoadFilename){
8 // Check if the file exists and return
9 // CALENDAROBJECTLOAD_CANNOTOPEN if not.
11 if (!FileExists(LoadFilename)){
12 return CALENDAROBJECTLOAD_MISSING;
16 string ReceivedStringData = "";
18 FileStream.open(LoadFilename, ifstream::in);
20 if (FileStream.rdstate() & ifstream::failbit){
21 return CALENDAROBJECTLOAD_CANNOTOPEN;
24 if (FileStream.rdstate() & ifstream::badbit){
25 return CALENDAROBJECTLOAD_CANNOTOPEN;
28 // Read the data into a string.
30 char *BufferRead = new char[256];
32 while (!FileStream.eof()){
34 FileStream.getline(BufferRead, 256);
35 ReceivedStringData.append(BufferRead);
36 ReceivedStringData.append("\n");
42 CalendarObjectLoadResult StringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL;
44 StringProcResult = LoadString(&ReceivedStringData);
46 return StringProcResult;
50 CalendarObjectLoadResult CalendarObject::LoadString(std::string *LoadStringData){
53 bool SkipMode = false;
54 bool ColonFound = false;
55 bool QuoteMode = false;
57 int StringDataSize = LoadStringData->size();
62 while (SeekCount < StringDataSize){
64 // Check if character is blank or a tab and is the first character
67 if (((*LoadStringData)[SeekCount] == ' ' ||
68 (*LoadStringData)[SeekCount] == '\t')
71 // Character is on a new line and it is a space or
72 // tab. Ignore this character as it is not part
77 } else if ((*LoadStringData)[SeekCount] == '\"'){
79 if (QuoteMode == false){
85 BufferChar = (*LoadStringData)[SeekCount];
87 if (ColonFound == false){
88 PropertyName += BufferChar;
90 PropertyValue += BufferChar;
93 } else if (NewLine == true){
95 // Character is on a new line but not a space or
96 // tab so check if the colon has been found
97 // and add the property name and value to
100 if (ColonFound == true){
101 ObjectName.push_back(PropertyName);
102 ObjectData.push_back(PropertyValue);
107 PropertyName.clear();
108 PropertyValue.clear();
110 BufferChar = (*LoadStringData)[SeekCount];
111 PropertyName += BufferChar;
113 } else if ((*LoadStringData)[SeekCount] == '\n'){
115 // Character is the new line character so mark
116 // the NewLine boolean as true.
120 } else if ((*LoadStringData)[SeekCount] == ':' &&
123 // Character is the colon. Set the colon
124 // found boolen to true.
126 BufferChar = (*LoadStringData)[SeekCount];
128 if (ColonFound == true){
129 PropertyValue += BufferChar;
136 // Character is not part of a new line and is not
137 // the new line character itself.
139 BufferChar = (*LoadStringData)[SeekCount];
141 if (ColonFound == false){
142 PropertyName += BufferChar;
144 PropertyValue += BufferChar;
153 // Finish off processing any data that wasn't processed
154 // when the end of the string was reached.
156 if (ColonFound == true &&
157 PropertyName.size() > 0 &&
158 PropertyValue.size() > 0){
160 ObjectName.push_back(PropertyName);
161 ObjectData.push_back(PropertyValue);
165 // Check that the object contains valid data.
167 CalendarObjectLoadResult StringProcResult = CALENDAROBJECTLOAD_UNITTESTFAIL;
168 CalendarObjectValidResult BaseDataResult = ValidBaseObject();
169 CalendarObjectValidResult EventDataResult = ValidObject();
171 if (BaseDataResult != CALENDAROBJECTVALID_OK ||
172 EventDataResult != CALENDAROBJECTVALID_OK){
174 StringProcResult = CALENDAROBJECTLOAD_INVALIDFORMAT;
178 StringProcResult = CALENDAROBJECTLOAD_OK;
185 return StringProcResult;
189 CalendarObjectValidResult CalendarObject::ValidBaseObject(){
191 bool ValidBegin = false;
192 bool ValidAlarmBegin = false;
193 bool ValidVersion = false;
194 bool ValidEnd = false;
196 vector<int> DeleteLines;
197 vector<string> AlarmObjectName;
198 vector<string> AlarmObjectData;
200 // Check that the first line contains BEGIN:VCALENDAR
201 // and it only appears once.
203 for (vector<string>::iterator iter = ObjectName.begin();
204 iter != ObjectName.end(); iter++){
206 if (ObjectName[SeekCount] == "BEGIN" &&
207 ObjectData[SeekCount] == "VCALENDAR"){
209 if (ValidBegin == false){
212 return CALENDAROBJECTVALID_INVALIDFORMAT;
217 if (ObjectName[SeekCount] == "END" &&
218 ObjectData[SeekCount] == "VCALENDAR" &&
219 ValidBegin == false){
221 return CALENDAROBJECTVALID_INVALIDFORMAT;
223 } else if (ObjectName[SeekCount] == "END" &&
224 ObjectData[SeekCount] == "VALARM" &&
225 ValidAlarmBegin == false){
227 return CALENDAROBJECTVALID_INVALIDFORMAT;
229 } else if (ObjectName[SeekCount] == "END" &&
230 ObjectData[SeekCount] == "VCALENDAR" &&
231 ValidAlarmBegin == true){
233 return CALENDAROBJECTVALID_INVALIDFORMAT;
237 // Look for any VALARM sections.
239 if (ValidAlarmBegin == true){
241 AlarmObjectName.push_back(ObjectName[SeekCount]);
242 AlarmObjectData.push_back(ObjectData[SeekCount]);
243 DeleteLines.push_back(SeekCount);
247 if (ObjectName[SeekCount] == "END" &&
248 ObjectData[SeekCount] == "VALARM" &&
249 ValidAlarmBegin == true){
251 EventAlarmName.push_back(AlarmObjectName);
252 EventAlarmData.push_back(AlarmObjectData);
254 AlarmObjectName.clear();
255 AlarmObjectData.clear();
257 ValidAlarmBegin = false;
261 if (ObjectName[SeekCount] == "BEGIN" &&
262 ObjectData[SeekCount] == "VALARM" &&
265 if (ValidAlarmBegin == false){
266 ValidAlarmBegin = true;
268 return CALENDAROBJECTVALID_INVALIDFORMAT;
271 AlarmObjectName.push_back(ObjectName[SeekCount]);
272 AlarmObjectData.push_back(ObjectData[SeekCount]);
273 DeleteLines.push_back(SeekCount);
283 // Check that the last line contains END:VCALENDAR
284 // and it only appears once.
286 for (vector<string>::iterator iter = ObjectName.begin();
287 iter != ObjectName.end(); iter++){
289 if (ObjectName[SeekCount] == "END" &&
290 ObjectData[SeekCount] == "VCALENDAR"){
292 if (ValidEnd == false){
295 return CALENDAROBJECTVALID_INVALIDFORMAT;
306 // Check that the VERSION value contains 2.0 and that
307 // it only appears once.
309 for (vector<string>::iterator iter = ObjectName.begin();
310 iter != ObjectName.end(); iter++){
312 if (ObjectName[SeekCount] == "VERSION" &&
313 ObjectData[SeekCount] == "2.0"){
315 if (ValidVersion == false){
318 return CALENDAROBJECTVALID_INVALIDFORMAT;
327 // Remove lines that aren't needed as they have
328 // been moved to the EventAlarm section.
330 for (vector<int>::reverse_iterator deliter = DeleteLines.rbegin();
331 deliter != DeleteLines.rend(); deliter++){
333 ObjectName.erase(ObjectName.begin()+(*deliter));
334 ObjectData.erase(ObjectData.begin()+(*deliter));
338 if (ValidBegin == true &&
340 ValidVersion == true &&
341 ValidAlarmBegin == false){
343 return CALENDAROBJECTVALID_OK;
347 return CALENDAROBJECTVALID_INVALIDFORMAT;
353 void CalendarObject::ProcessBaseData(){
355 // Process the base object data.
357 multimap<string,string> DataReceived;
359 // Get the method (METHOD).
361 DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "METHOD");
363 if (DataReceived.begin() != DataReceived.end()){
366 MethodTokens = DataReceived.begin()->first.substr(7);
369 catch(const out_of_range &oor){
370 // Do nothing as there is no data.
373 MethodData = DataReceived.begin()->second;
377 // Get the calendar scale (CALSCALE).
379 DataReceived = ProcessTextVectors(&ObjectName, &ObjectData, false, "CALSCALE");
381 if (DataReceived.begin() != DataReceived.end()){
384 CalendarScaleTokens = DataReceived.begin()->first.substr(9);
387 catch(const out_of_range &oor){
388 // Do nothing as there is no data.
391 CalendarScaleData = DataReceived.begin()->second;