ホーム > 製品情報 > SophiaFramework UNIVERSE > チュートリアル > BREW vCalendar スケジューラー

BREW スケジューラー 〜 BREW C++ vCalendar プログラミング 〜

vCalendar とは

vCalendar は、異なるスケジューラーアプリ間でデータをインポートやエクスポートするための、カレンダー情報に関する標準フォーマットです。

vCalendar のフォーマット

vCalendar データの基本フォーマットは次の通りです。

BEGIN:VCALENDAR
VERSION:1.0
BEGIN:VEVENT
SUMMARY:meeting
DTSTART:20050324T113450Z
DTEND:20050324T120000Z
LAST-MODIFIED:20050717T005300Z
END:VEVENT
END:VCALENDAR
  1. vCalendar データは "BEGIN:VCALENDAR" で始まり、"END:VCALENDAR" で終わります。
  2. 各行は"項目名:値" の形式となっています。
  3. "SUMMARY:" はスケジュールの内容を表します。
  4. "DTSTART:" は開始時刻、 "DTEND:" は終了時刻、"LAST-MODIFIED:" はデータの最終更新時刻です。
  5. 時刻のフォーマットは "20050324T113450Z" 形式で表現します。これは "2005年3月24日11時34分50秒" を意味します。

本アプリでは vCalendar データを VCalendar クラスで処理します。

class VCalendar {
private:
    SFXAnsiString _version;   // VERSION:
    SFXDate _startDT;         // DTSTART:
    SFXDate _endDT;           // DTEND:
    SFXDate _lastModifiedDT;  // LAST-MODIFIED:
    SFXAnsiString _summary;   // SUMMARY:
    SFXAnsiString _others;    // その他
public:
    //以下、メンバ関数
};

日付データは SFXDate クラスを使います。

_others には、このアプリで使わないデータを格納します。

vCalendar フォーマットの解析

Import()vCalendar データを VCalendar クラスに取り込むための関数、Export()VCalendar クラスから vCalendar データを書き出すための関数です。

Void Import(SFXAnsiStringConstRef str);
Void Export(SFXAnsiStringPtr str);

Import 関数の引数に vCalendar 形式のテキストデータを SFXAnsiString 文字列として渡すことで、メンバ変数に値を設定します。

Export 関数は VCalendar クラスのメンバ変数の値を vCalendar 形式のデータとして書き出します。

Import 関数、Export 関数では、文字列コピーのオーバーヘッドは起きません。

Import 関数の実装

  1. 最初の行が "BEGIN:VCALENDAR" であるかチェックする
  2. 3. 4. の処理を各行について実行する
  3. 一行の文字列をコロン ':' の左側 ( field ) と右側 ( value ) に分ける
  4. field の値に対応するメンバ変数に value の値を代入する

_startDateendDate_lastModifiedDate は 日付 ( SFXDate ) のインスタンス変数です。Parse 関数は文字列の日付を解析して SFXDate オブジェクトに変換します。

// vCalendar形式の文字列を取り込む
Void VCalendar::Import(SFXAnsiStringConstRef string)
{
    SInt32 c1, c2;
    SFXAnsiStringConst format("YYYYMMDD%Thhmmss");
    SFXAnsiString field, value;

    _others.Clear();
    // BEGIN:VCALENDARが最初に存在しなければエラー
    c1 = string.IndexOf("BEGIN:VCALENDAR");
    if (c1 < 0) {
        c1 = string.IndexOf("begin:vcalendar");
        if (c1 < 0) {
            return;
        }
    }
    c2 = string.IndexOf('\n', c1);
    while (true) {
        c1 = string.IndexOf(':', c2); // 次のコロンを探す
        if (c1 < 0) { // 見つからないなら
            break; // 終了
        }
        // ****:**** のコロンの左側を取得して、文字の後ろの空白文字はカット
        field = string.Substring(c2 + 1, c1).Trim();
        c2 = string.IndexOf('\n', c1); // 次の行末を探す
        if (c2 < 0) { // 見つからないなら
            c2 = string.GetLength(); // 文字列の最後尾とする
        }
        // ****:**** のコロンの右側を取得して、文字の後ろの空白文字はカット
        value = string.Substring(c1 + 1, c2).Trim();

        if (field.Equals("begin", false)) { // 
            ; // 
        } else if (field.Equals("end", false)){
            if (value.Equals("vcalendar"), false) {
                break; // END:VCALENDARのとき、終了
            } // 
        } else if (field.Equals("version", false)) { // バージョン
            _version = value;
        } else if (field.Equals("dtstart", false)) { // 開始時刻
            _startDate.Parse(format, value); // 時刻を解析して設定
        } else if (field.Equals("dtend", false)) { // 終了時刻
            _endDate.Parse(format, value); // 時刻を解析して設定
        } else if (field.Equals("last-modified", false)) { // 更新時刻
            _lastModifiedDate.Parse(format, value); // 時刻を解析して設定
        // イベントデータ
        } else if (field.Substring(0, 7).Equals("summary", false)) {
            _summary = value;
        } else { // その他のデータ
            _others << field << ":" << value << "\r\n";
        }
    }
    return;
}

Export 関数の実装

// vCalendar形式のデータを書き出す
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;
}

文字列を += 演算子で末尾に追加しています。

SFXDate クラスの Format 関数は Parse 関数の逆で、 SFXDate オブジェクトを文字列の日付に変換します。