[[← 2 節に戻る|Palm OS Programmer's Companion Volume II/3-2]] [[↑3 章トップへ|Palm OS Programmer's Companion Volume II/3]] [[4 節に進む →|Palm OS Programmer's Companion Volume II/3-4]] ---- !!! 3-3 PDI ライブラリの使用 このセクションでは、PDI 文脈を読み書きするためにどのように PDI ライブラリ関数を使用するか、について説明します。図3.1は、vObject の読み書きを行う際に典型的な一連のコールを示しています。 vObjectを読み取るためには、以下のことが必要です。 *PDI ライブラリへのアクセス *PDI リーダの生成 *入力ストリーム内の各プロパティの読み取り **プロパティ名の読み取り **プロパティの各パラメータの読み取り **プロパティ値の読み取り *PDI リーダの削除 *PDI ライブラリのアンロード vObject に書き込むためには、以下のことが必要です。 *PDI ライブラリへのアクセス *PDI ライタの生成 *入力ストリーム内の各プロパティに書き込み **プロパティ名の書き込み **プロパティの各パラメータの書き込み **プロパティ値の書き込み *PDI ライタの削除 *PDI ライブラリのアンロード このセクションのリマインダは以下の操作を説明します。 *[[PDI ライブラリへのアクセス]] *[[PDI ライブラリのアンロード]] *[[PDI リーダの生成]] *[[プロパティの読み取り]] *[[PDI ライタの生成]] *[[プロパティ値の書き込み]] *[[PDI バージョンの指定]] *[[異なるメディアへの UDA の使用|Palm OS Programmer's Companion Volume II/3-4]] [[「PDI リーダの利用例」|Palm OS Programmer's Companion Volume II/3-5]]セクションでは、PDI リーダの生成及び vCard データのデータベースへのインポートについて、詳細な例を提供します。 [[「PDI ライタの利用例」|Palm OS Programmer's Companion Volume II/3-6]]セクションでは、PDI ライタの生成及びデータベースから vCal フォーマットのエクスポートについて、詳細な例を提供します。 '''図3.1 PDI ライブラリの利用''' {{img PDILibrary.gif}} !!PDI ライブラリのアクセス PDI ライブラリを使用する前に、ライブラリをロードしてその参照値を得る必要があります。ライブラリ内の各関数はこの参照値変数を必要とします。これはシステムコードが共有ライブラリにアクセスするのに使用します。 Listing 3.2 に書かれているサンプル関数 {{span style='color:blue;font-family:monospace;',LoadPdiLibrary}} は、PDI ライブラリがロードされていることを確実にし、その参照値を返します。 '''Listing 3.2 PDI ライブラリのロード''' Static Err LoadPdiLibrary(UInt16 *libRefNum) { Err error error = SysLibFind(kPdiLibName, librefNum); if (error != 0) { error = SysLibLoad(sysResTLibrary, sysFileCPdiLib, libRefNum); } if (error) { ErrNonFatalDisplay(kPdiLibName "not found") return error; } error = PdiLibOpen(*libRefNum); return error; } {{span style='color:blue;font-family:monospace;',LoadPdiLibrary}} 関数は、既にライブラリをロードしている他のアプリケーションがあなたのコードをコールしている場合に備えて、ライブラリが既にロードされているかどうかを決めるために最初に {{span style='color:blue;font-family:monospace;',SysLibFind}} 関数をコールします。{{span style='color:blue;font-family:monospace;',SysLibFind}} のコールは{{span style='color:blue;font-family:monospace;',kPdiLibName}} 定数( {{span style='color:blue;font-family:monospace;',PdiLib.h}} ファイルで以下のように定義されています)を使用することに注意して下さい。 #define kPdiLibName "Pdi.lib" もしライブラリがまだロードされていないなら、ライブラリをロードしてその参照値を得るために {{span style='color:blue;font-family:monospace;',LoadPdiLibrary}} が {{span style='color:blue;font-family:monospace;',SysLibLoad}} 関数をコールします。 ライブラリへの参照値の取得後に、ロード済のライブラリを開くために {{span style='color:blue;font-family:monospace;',LoadPdiLibrary}} は {{span style='color:blue;font-family:monospace;',PdiLibOpen}} 関数をコールします。 !!PDI ライブラリのアンロード ライブラリを使い終わったら、アンロードしなければいけません。Listing 3.3 内のサンプル関数 {{span style='color:blue;font-family:monospace;',UnloadPdiLibrary}} は、PDI ライブラリをアンロードしています。 :訳註:原文では Lisiting 3.2 となっていました。 '''Listing 3.3 PDI ライブラリのアンロード''' static void UnloadPdiLibrary(UInt16 refNum) { if (PdiLibClose(refNum) == 0) { SysLibRemove(refNum); } } {{span style='color:blue;font-family:monospace;',SysLibRemove}} 関数のコール後はライブラリ参照値が無効になることに注意して下さい。 !!PDI リーダの生成 PDI リーダを生成するためには、まずライブラリにアクセスし、その後以下に宣言されているように [[{{span style='color:blue;font-family:monospace;',PdiReaderNew}}]] 関数をコールする必要があります。 PdiReaderType* PdiReaderNew(UInt16 libRefnum, UDAReader *input, UInt16 optionFlags) {{span style='color:blue;font-family:monospace;',PdiReaderNew}}の パラメータは以下の通りです。 *[[「PDIライブラリへのアクセス」]]で説明したライブラリ参照値。 *リーダが使用する UDA(Unified Data Access:統合データアクセス)入力ストリーム。UDA マネージャは、様々なソースからの入力を読み取ることを可能にします。このソースには、文字列や Exchange マネージャも含まれます。詳しくは、[[「異なるメディアへの UDA の使用」]]を参照して下さい。 *リーダの解釈動作をコントロールするオプションフラグ。デフォルトのエンコーディングや互換性の設定を含みます。オプションフラグについては、''Palm OS Programmer's API Reference''の[[第 88 章 個人データ交換ライブラリ]] で説明しています。 一度リーダを生成したなら、それを使って入力ストリームからプロパティを解釈することができます。[[「PDI リーダの利用例」]]セクションで、PDI リーダの生成と利用についての例を提供しています。 !!プロパティの読み取り PDI リーダで PDI プロパティデータを読み取るために、データ読み取り関数をコールする必要があります。 *{{span style='color:blue;font-family:monospace;',PdiReadProperty}} は、入力ストリームからプロパティと全パラメータを読み取ります。 *{{span style='color:blue;font-family:monospace;',PdiReadPropertyName}}は、入力ストリームから次のプロパティの名前だけを読み取ります。もしプロパティのパラメータ読み取りを個別に扱いたいならこの関数をコールできます。 *{{span style='color:blue;font-family:monospace;',PdiReadParameter}} は、入力ストリームから単一のパラメータと値を読み取ります。 *[[「プロパティ値の読み取り」]] 入力データ読み取りの最も一般的な方法は以下のステップです。 *vObject の開始(Begin)プロパティを読み取るために、{{span style='color:blue;font-family:monospace;',PdiReadProperty}} をコールします。例えば、もし vCard を読んでいるなら、入力ストリームから{{span style='color: #000000; font-family: Courier; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; vertical-align: baseline',kPdiPRN_BEGIN_VCARD }}プロパティを読むまで{{span style='color:blue;font-family:monospace;',PdiReadProperty}}をコールすることができます。 *一度オブジェクトの開始を見つけたなら、次のプロパティとそのパラメータを読み取るために{{span style='color:blue;font-family:monospace;',PdiReadProperty}}を繰り返しコールします。 *各プロパティで、プロパティのフィールドを読み取る必要があるときに {{span style='color:blue;font-family:monospace;',PdiReadPropertyField}} 関数をコールします。 *vObject の終了(End)プロパティを読み取るまで、プロパティの読み取りを継続します。vCard では、{{span style='color:blue;font-family:monospace;',PdiReadProperty}} が入力ストリームから{{span style='color:blue;font-family:monospace;',kPdiPRN_END_VCARD}}プロパティを読み取るまで、プロパティを処理します。 !プロパティ情報の検証 プロパティ読み取り関数のコール後、現在のプロパティについての情報を決定するために、{{span style='color:blue;font-family:monospace;',PdiReaderType}} オブジェクトのフィールドにアクセスすることができます。現在のプロパティとは、現在解釈を行なっているもしくは丁度解釈を終えたプロパティです。 例えば、特定のパラメータペアがプロパティ定義に存在するかどうかを決定するために、{{span style='color:blue;font-family:monospace;',PdiParameterPairTest}} マクロの{{span style='color:blue;font-family:monospace;',property}}フィールドを検証することができます。 !!プロパティ値の読み取り 単純な値を持つプロパティもあれば、構造化された値を持つプロパティもあります。構造化されたプロパティ値は、カンマやセミコロンで区切られている複数のフィールドを持っています。 例えば、以下の電話プロパティ定義は単純な値を持っています。 TEL;CELL:+1 (408) 555-4321 電話プロパティは{{span style='color:blue;font-family:monospace;',CELL}}パラメータをプロパティ名と区切るためにセミコロンを含むことに注意して下さい。各プロパティの値は定義内のコロンに続きます。 以下の名前プロパティ定義は、セミコロンで区切られた4つのフィールドを含む構造化された値を持っています。 N:Smith; John;M.;Mr.; Esq. 「Palm OS Programmer's API Reference」の[[第 88 章「個人データ交換ライブラリ」]]にパラメータを渡さなければいけません。 PDI リーダにプロパティ値のフォーマットを決定させるために、{{span style='color:blue;font-family:monospace;',kPdiDefaultFields}} を指定することができます。リーダはプロパティのフォーマットを決定するために、プロパティ名を辞書から探します。 *リーダが値全体を一回の操作で解釈するために、{{span style='color:blue;font-family:monospace;',kPdiNoFields}} を指定します。 *リーダが値の単一のフィールドを解釈するために、{{span style='color:blue;font-family:monospace;',kPdiCommaFields}} または {{span style='color:blue;font-family:monospace;',kPdiSemicolonFields}} を指定します。 *リーダが値の全フィールドを単一の値に解釈するために、{{span style='color:blue;font-family:monospace;',kPdiConvertComma}} または {{span style='color:blue;font-family:monospace;',kPdiConvertSemicolon}} を指定します。 通常は {{span style='color:blue;font-family:monospace;',kPdiDefaultFields}} を指定することで、PDI リーダが値を適切に解釈するために辞書の情報を使用できるようになります。しかし、特に入力ストリームがカスタムプロパティを含む場合は、これはあなたのニーズと常に一致するわけではありません。 表 3.1 は、入力ストリームから同じプロパティを読み取るために異なるフォーマット定数を使用した結果です。セミコロンで区切られた7つのフィールドを含む構造化された値を持つ標準の住所( {{span style='color:blue;font-family:monospace;',ADR}} )プロパティを例としています。 ADRostoffice;extended;street;locale;region;postal_code;country {{span style='color:blue;font-family:monospace;',ADR}} プロパティはセミコロンで区切られた7つのフィールドで構造化された値として vCard 標準に従って定義されているので、PDI ライブラリ辞書はそのデフォルトフォーマットを {{span style='color:blue;font-family:monospace;',kPdiSemicolon}} として定義していることに注意して下さい。 '''表 3.1 異なる値のフォーマット形式で構造化された値の解釈''' ,'''値のフォーマット形式''',"{{span style='color:blue;font-family:monospace;',PdiReadPropertyField}} 結果の詳細" ,"{{span style='color:blue;font-family:monospace;',kPdiNoFields}}","一度のコールで値全体が文字列として返されます。{{br}}""postoffice;extended;street;locale;region;postal_code;country""" ,"{{span style='color:blue;font-family:monospace;',kPdiSemicolon}}",各コールはセミコロンで区切られた単一のフィールドを値から返します。{{br}}・最初のコールは「 postoffice 」を返します。{{br}}・二番目のコールは「 extended 」を返します。{{br}}・三番目のコールは「 street 」を返します。 ,"{{span style='color:blue;font-family:monospace;',kPdiComma}}","各コールはカンマで区切られた単一のフィールドを値から返します。例えば、入力文字列が「postoffice,extended,street,」だった場合は以下のようになります。{{br}}・最初のコールは「 postoffice 」を返します。{{br}}・二番目のコールは「 extended 」を返します。{{br}}・三番目のコールは「 street 」を返します。" ,"{{span style='color:blue;font-family:monospace;',kPdiConvertSemicolon}}",一度のコールで値全体を返します。入力でセミコロンがあった場所に改行文字が入ります。{{br}}"postoffice{{br}}extended{{br}}street{{br}}locale{{br}}region{{br}}postal_code{{br}}country" ,"{{span style='color:blue;font-family:monospace;',kPdiConvertComma}}",一度のコールで値全体を返します。入力でカンマがあった場所に改行文字が入ります。{{br}}"postoffice{{br}}extended{{br}}street{{br}}locale{{br}}region{{br}}postal_code{{br}}country" ,"{{span style='color:blue;font-family:monospace;',kPdiDefaultFields}}","PDI ライブラリ辞書は {{span style='color:blue;font-family:monospace;',ADR}} フィールドのプロパティ値フォーマットを {{span style='color:blue;font-family:monospace;',kPdiSemicolon}} と同じものと定義しているので、{{span style='color:blue;font-family:monospace;',kPdiSemicolon}} と同じです。" !複数の値フィールドを一度に読み取る もし構造化された値の中のフィールドを一度に読み取ろうとするなら、またフィールドの正確な数が分からないなら、ゼロでない結果を返すまで繰り返し {{span style='color:blue;font-family:monospace;',PdiReadPropertyField}} をコールすることができます。 例えば、{{span style='color:blue;font-family:monospace;',DateTransfer.c}}プログラム内の以下のコードセグメントは、{{span style='color:blue;font-family:monospace;',EXDATE}} プロパティ値フィールドの各フィールドを解釈します。 '''Listing 3.4 決定されていない値フィールド数の読み取り''' while (PdiReadPropertyField(pdiRefNum, reader, &tempP, kPdiResizableBuffer, kPdiSemicolonFields) == 0) { // Resize handle to hold exception err = MemHandleResize(exceptionListH, sizeof(ExceptionsListType) + sizeof(DateType) * exceptionCount); ErrFatalDisplayIf(err != 0, "Memory full"); // Lock exception handle exceptionListP = MemHandleLock(exceptionListH); // Calc exception ptr exceptionP = (DateType*)((UInt32)exceptionListP + (UInt32)sizeof(UInt16) + (UInt32)(sizeof(DateType) * exceptionCount)); // Store exception into exception handle MatchDateTimeToken(tempP, exceptionP, NULL); // Increase exception count exceptionCount++; // Unlock exceptions list handle MemHandleUnlock(exceptionListH); } :注:もし構造化された値の中のフィールドを読まないままにするなら、次の {{span style='color:blue;font-family:monospace;',PdiReadProperty}} コールでそのフィールドはスキップされ、次のプロパティの始まりを適切に探します。 !カスタム拡張子の追加 vObject 標準は拡張可能です。つまり、vCard やその他の vObject にカスタムプロパティを追加することができます。PDI ライブラリはこれらのカスタムプロパティを扱います。しかし、各カスタムプロパティごとにエントリをライブラリ辞書に追加するか、プロパティ値を解釈するときに {{span style='color:blue;font-family:monospace;',kPdiDefaultFields}} 以外の定数を指定するか、どちらかをする必要があります。 各 PDI リーダオブジェクトと各 PDI ライタオブジェクトは、それに関連付けられたカスタム辞書を持つことができます。そのカスタム辞書をビルトイン辞書の代わりに標準として置き換えることができます。 カスタム辞書をリーダやライタに関連付けるには、最初に辞書を生成し、辞書をライタオブジェクトに関連付けるための {{span style='color:blue;font-family:monospace;',PdiDefineWriterDictionary}} 関数をコールします。 :注:辞書ツールについて詳しくは http://www.palmos.com/dev/tech/kb を参照して下さい。 !!PDI ライタの生成 PDI ライタを生成するために、最初にライブラリにアクセスし、そして {{span style='color:blue;font-family:monospace;',PdiWriterNew}} 関数をコールする必要があります。これは以下のように宣言します。 PdiWriterType* PdiWriterNew(UInt16 libRefnum, UDAWriter *output, UInt8 optionFlags) {{span style='color:blue;font-family:monospace;',PdiWriterNew}} のパラメータは以下の通りです。 *[[PDI ライブラリのアクセス]]で説明した、ライブラリの参照数値。 *ライタで使用する UDA 出力ストリーム。詳しくは、[[異なるメディアでの UDA の使用]]を参照して下さい。 *ライタが出力を生成する振る舞いをコントロールするオプションフラグ。そのデフォルトエンコーディングと互換性設定を含みます。オプションフラグは ''Palm OS Programmer's API Reference'' の[[第 88 章「個人データ交換ライブラリ」]]で説明しています。 一度ライタを生成したら、出力ストリームのプロパティを生成するのに使用することができます。[[「PDI ライタの使用例」]]は、PDI ライタの生成と使用の例を提供します。 !!プロパティの書き込み PDI データを PDI ライタで書き込むには、データ書き込み関数をコールする必要があります。最も一般的に使用される関数は、以下の通りです。 !!Writing Properties To write PDI data with a PDI writer, you need to call the data writing functions. The most commonly used functions are: *{{span style='color:blue;font-family:monospace;',PdiWriteBeginObject}} は vObject 開始タグを出力ストリームに書き込みます。 *{{span style='color:blue;font-family:monospace;',PdiWriteEndObject}} は vObject 終了タグを出力ストリームに書き込みます。 *{{span style='color:blue;font-family:monospace;',PdiWriteProperty}} はプロパティを出力ストリームに書き込みます。 *{{span style='color:blue;font-family:monospace;',PdiWritePropertyValue}} はプロパティ値を出力ストリームに書き込みます。 出力データを書き込む最も一般的な方法は、以下のステップに従うことです。 *vObject 開始プロパティを書き込むために、{{span style='color:blue;font-family:monospace;',PdiWriteBeginObject}} をコールします。例えば、もし vCard を書き込もうとしているなら、{{span style='color: #000000; font-family: Courier; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; vertical-align: baseline;',>kPdiPRN_BEGIN_VCARD}} プロパティを出力ストリームに書き込むために {{span style='color:blue;font-family:monospace;',PdiWriteBeginObject}} をコールします。 *書き込みたい各プロパティごとに、次のプロパティとそのパラメータを書き込むために {{span style='color:blue;font-family:monospace;',PdiWriteProperty}} をコールします。そして、プロパティの値を書き込むために {{span style='color:blue;font-family:monospace;',PdiWritePropertyValue}} 関数をコールします。 *vObject 終了プロパティを書き込むために、{{span style='color:blue;font-family:monospace;',PdiWriteEndObject}} をコールします。例えば、もし vCard を書き込もうとしているなら、{{span style='color: #000000; font-family: Courier; font-style: normal; font-weight: normal; text-decoration: none; text-transform: none; vertical-align: baseline;',kPdiPRN_END_VCARD}} プロパティを出力ストリームに書き込むために {{span style='color:blue;font-family:monospace;',PdiWriteEndObject}} をコールします。 !!プロパティ値の書き込み 多くの場合、単に {{span style='color:blue;font-family:monospace;',PdiWritePropertyStr}} をコールするだけで、カンマやセミコロンで区切られた複数フィールドを書き込むことができます。 !!PDI バージョンの指定 PDI ライブラリオプション定数は、PDI リーダやライタの操作をコントロールします。これらのオプションは ''Palm OS Programmer's API Reference'' の[[第 88 章「個人データ交換ライブラリ」]]で説明します。 ---- [[← 2 節に戻る|Palm OS Programmer's Companion Volume II/3-2]] [[↑3 章トップへ|Palm OS Programmer's Companion Volume II/3]] [[4 節に進む →|Palm OS Programmer's Companion Volume II/3-4]]