BREW Scheduler Supporting vCalendar - 2 / 7 -
Overview
About vCalendar
vCalendar ( and its updated version iCalendar ) is the de facto standard format for importing and exporting calendar data between different kinds of schedulers.
Related Information : vCard and vCalendar
Related Information : VCalendar - Wikipedia / ICalendar - Wikipedia
Format of vCalendar
Basic format of vCalendar is as follows.
BEGIN:VCALENDAR VERSION:1.0 BEGIN:VEVENT SUMMARY:meeting DTSTART:20050324T113450Z DTEND:20050324T120000Z LAST-MODIFIED:20050717T005300Z END:VEVENT END:VCALENDAR
- Data of vCalendar starts from "BEGIN:VCALENDAR" and ends in "END:VCALENDAR".
- Each line has the format of "item name : value".
- "SUMMARY:" describes the contents of a schedule.
- "DTSTART:" is the starting time, "DTEND:" is the ending time, and "LAST-MODIFIED:" is the last time it was updated.
- Format of time is like "20050324T113450Z". This means "2005/3/24, 11:34:50".
In this application, the data components of vCalendar are handled by the VCalendar class.
class VCalendar { private: SFXAnsiString _version; // for VERSION: SFXDate _startDate; // for DTSTART: SFXDate _endDate; // for DTEND: SFXDate _lastModifiedDate; // for LAST-MODIFIED: SFXAnsiString _summary; // for SUMMARY: SFXAnsiString _others; // for others public: // member functions below this ... };
Date is handled by the SFXDate class.
_others is for data items that are not used in this application such as PUBLIC.
Analyzing vCalendar
The Import() function is responsible for importing vCalendar data into the VCalendar class, and the Export() function exports VCalendar data from vCalendar class data members.
Void Import(SFXAnsiStringConstRef str); Void Export(SFXAnsiStringPtr str);
To set the value of a member variable of the VCalendar class, you should call the Import() function with SFXAnsiString text data in the vCalendar format as an argument.
The Export() function exports member variables of the VCalendar class as data in vCalendar format.
* In both Import() and Export(), there is no overhead of copying strings.
Implementation of Import()
- Check whether the first line is "BEGIN:VCALENDAR"
- Execute 3. and 4. for each line
- Split the line into the left side field and the right side value by ':'
- Set value to the member variable of field
_startDate, endDate, _lastModifiedDate are instance variables of the SFXDate class. Parse() analyzes a date string and converts it into an SFXDate object.
// import string in vCalendar format Void VCalendar::Import(SFXAnsiStringConstRef string) { SInt32 c1, c2; SFXAnsiStringConst format("YYYYMMDD%Thhmmss"); SFXAnsiString field, value; _others.Clear(); // Error if "BEGIN:VCALENDAR" does not exists at the beginning c1 = string.IndexOf("BEGIN:VCALENDAR"); if (c1 < 0) { c1 = string.IndexOf("begin:vcalendar"); if (c1 < 0) { return; } } c2 = string.IndexOf('\n', c1); while (true) { // Look for the next : c1 = string.IndexOf(':', c2); if (c1 < 0) { // if not found break; // end } // get the left side of the colon "****:****" // and cut any blank characters at the end field = string.Substring(c2 + 1, c1).Trim(); c2 = string.IndexOf('\n', c1); // Search for next end of line if (c2 < 0) { // if not found c2 = string.GetLength(); // Make it the end of the string } // Get the right side of "****:****" by ':' // And cut any blank characters at the end value = string.Substring(c1 + 1, c2).Trim(); if (field.Equals("begin", false)) { ; // If field is "begin", disregard } else if (field.Equals("end", false)){ if (value.Equals("vcalendar"), false) { // End when "END:VCALENDAR" found break; // end } // Disregard anything else } else if (field.Equals("version", false)) { _version = value; // Set version } else if (field.Equals("dtstart", false)) { _startDate.Parse(format, value); // Parse and set Start } else if (field.Equals("dtend", false)) { _endDate.Parse(format, value); // Parse and set End } else if (field.Equals("last-modified", false)) { _lastModifiedDate.Parse(format, value); // Parse and set // Last Modified // Event data } else if (field.Substring(0, 7).Equals("summary", false)) { _summary = value; } else { //Others data _others << field << ":" << value << "\r\n"; } } return; }
Implement Export()
// export data in vCalendar format Void VCalendar::Export(SFXAnsiStringPtr string) const { SFXAnsiString format("YYYYMMDD%Thhmmss%Z"); string->Set("BEGIN:VCALENDAR\r\nVERSION:"); *string += _version; *string += "\r\nBEGIN:VEVENT\r\nCLASS:PUBLIC\r\nDTSTART:"; *string += _startDate.Format(format); *string += "\r\nDTEND:"; *string += _endDate.Format(format); *string += "\r\nSUMMARY;ENCODING=QUOTED-PRINTABLE:"; *string += _summary; *string += "\r\nLAST-MODIFIED:"; *string += _lastModifiedDate.Format(format); *string += "\r\n"; *string += _others; *string += "END:VEVENT\r\nEND:VCALENDAR\r\n"; return; }
The operator '+=' is used to append strings at the end of data.
To the inverse of the Parse() function, the Format() function of the SFXDate class converts SFXDate objects into date strings.