[[← 4 節に戻る|Palm OS Programmer's Companion Volume II/3-4]] [[↑3 章トップへ|Palm OS Programmer's Companion Volume II/3]] [[6 節に進む →|Palm OS Programmer's Companion Volume II/3-6]] ---- !!! 3-5 PDI リーダの利用例   このセクションでは、入力ストリームから PDI データを読み取り、それをデータベースに保存する例を提供します。この例は {{span style='color:blue;font-family:monospace;',Examples/Address/Src}} フォルダ内の {{span style='color:blue;font-family:monospace;',AddressTransfer.c }} ファイルにあります。 Listing 3.5 は、{{span style='color:blue;font-family:monospace;',AddressTransfer.c}} サンプルプログラム内の {{span style='color:blue;font-family:monospace;',TransferReceiveData}} 関数です。この関数は 、以下の操作に従って vCard データをアドレスデータベースに読み取ります。 *リモートデバイスからの接続を受け入れるために、{{span style='color:blue;font-family:monospace;',ExgAccept}} 関数をコールします。 *PDIライブラリを開いてロードするために、ローカル関数 {{span style='color:blue;font-family:monospace;',PrvTransferPdiLoadLibrary}} をコールします。{{span style='color:blue;font-family:monospace;',PrvTransferPdiLoadLibrary}} 関数は、Listing 3.2 の {{span style='color:blue;font-family:monospace;',LoadPdiLibrary}} 関数とほぼ同じです。 *Exchange マネージャと接続する入力データストリームを生成するために、{{span style='color:blue;font-family:monospace;',UDAExchangeReaderNew}} をコールします。 *入力ストリームを読み取る PDI リーダオブジェクトを新しく生成するために、{{span style='color:blue;font-family:monospace;',PdiReaderNew}} 関数をコールします。 *vCard データを読んでアドレスデータベースに保存するために、ローカル関数 {{span style='color:blue;font-family:monospace;',TransferImportVCard}} を繰り返しコールします。この関数は次のセクション([[ vCard データのデータベースへのインポート]])で説明します。 *転送を終了して接続を閉じるために、{{span style='color:blue;font-family:monospace;',ExgDisconnect}} 関数をコールします。 *PDI ライブラリをアンロードするために、{{span style='color:blue;font-family:monospace;',PrvTransferPdiLibUnload}} 関数をコールします。 *PDI リーダと入力ストリームオブジェクトを削除します。 '''Listing 3.5 PDI 入力ストリームの読み取り''' extern Err TransferReceiveData(DmOpenRef dbP, ExgSocketPtr exgSocketP) { volatile Err err; UInt16 pdiRefNum = sysInvalidRefNum; PdiReaderType* reader = NULL; UDAReader* stream = NULL; Boolean loaded; if ((err = ExgAccept(exgSocketP)) != 0) return err; if ((err = PrvTransferPdiLibLoad(&pdiRefNum, &loaded))) { pdiRefNum = sysInvalidRefNum; goto errorDisconnect; } if ((stream = UDAExchangeReaderNew(exgSocketP)) == NULL) { err = exgMemError; goto errorDisconnect; } if ((reader = PdiReaderNew(pdiRefNum, stream, kPdiOpenParser)) == NULL) { err = exgMemError; goto errorDisconnect; } reader->appData = exgSocketP; ErrTry { while(TransferImportVCard(dbP, pdiRefNum, reader, false, false)){}; } ErrCatch(inErr) { err = inErr; } ErrEndCatch if (err == errNone && exgSocketP->goToParams.uniqueID == 0) err = exgErrBadData; errorDisconnect: if (reader) PdiReaderDelete(pdiRefNum, &reader); if (stream) UDADelete(stream); if (pdiRefNum != sysInvalidRefNum) PrvTransferPdiLibUnload(pdiRefNum, loaded); ExgDisconnect(exgSocketP, err); // closes transfer dialog err = errNone; // error was reported, so don't return it return err; } !vCard データのデータベースへのインポート {{span style='color:blue;font-family:monospace;',TransferImportVCard}} 関数は、入力ストリームから vCard レコードをインポートします。Listing 3.6 は {{span style='color:blue;font-family:monospace;',TransferImportVCard}} 関数の基本的な概要です。関数全体をレビューするには、{{span style='color:blue;font-family:monospace;',AddressTransfer.c}} ファイルを参照して下さい。このファイルは {{span style='color:blue;font-family:monospace;',Examples/Address/Src}} フォルダ内にあります。 '''Listing 3.6 vCard データのデータベースへのインポート''' Boolean TransferImportVCard(DmOpenRef dbP, UInt16 pdiRefNum, PdiReaderType* reader, Boolean obeyUniqueIDs, Boolean beginAlreadyRead) { ... // local declarations and initialization code ErrTry { phoneField = firstPhoneField; if (!beginAlreadyRead) { PdiReadProperty(pdiRefNum, reader); beginAlreadyRead = reader->property == kPdiPRN_BEGIN_VCARD; } if (!beginAlreadyRead) ErrThrow(exgErrBadData); PdiEnterObject(pdiRefNum, reader); PdiDefineResizing(pdiRefNum, reader, 16, tableMaxTextItemSize); while (PdiReadProperty(pdiRefNum, reader) == 0 && (property = reader->property) != kPdiPRN_END_VCARD) { switch(property) { case kPdiPRN_N: PdiReadPropertyField(pdiRefNum, reader, (Char **) &newRecord.fields[name], kPdiResizableBuffer, kPdiDefaultFields); PdiReadPropertyField(pdiRefNum, reader, (Char **) &newRecord.fields[firstName], kPdiResizableBuffer, kPdiDefaultFields); break; case kPdiPRN_NOTE: PdiDefineResizing(pdiRefNum, reader, 16, noteViewMaxLength); PdiReadPropertyField(pdiRefNum, reader, Char **) &newRecord.fields[note], kPdiResizableBuffer, kPdiNoFields); PdiDefineResizing(pdiRefNum, reader, 16, tableMaxTextItemSize); break; ,,, // other cases here for other properties } } // end while if (newRecord.fields[name] != NULL && newRecord.fields[company] != NULL && newRecord.fields[firstName] != NULL && StrCompare(newRecord.fields[name], newRecord.fields[company]) == 0) { // if company & name fields are identical, assume company only MemPtrFree(newRecord.fields[name]); newRecord.fields[name] = NULL; } AddRecord: err = AddrDBNewRecord(dbP, (AddrDBRecordType*) &newRecord, &indexNew); if (err) ErrThrow(exgMemError); ... // handle category assignment here } //end of ErrTry if (error == exgErrBadData) return false; if (error != errNone) ErrThrow(error); return ((reader->events & kPdiEOFEventMask) == 0); } {{span style='color:blue;font-family:monospace;',TransferImportVCard}} 関数は以下の操作を行ないます。 *入力ストリームから {{span style='color:blue;font-family:monospace;',BEGIN:VCard}} プロパティを読み取るために、{{span style='color:blue;font-family:monospace;',PdiReadProperty}} 関数をコールします。 *入力ストリームからの新しいオブジェクトの読み取りであることをPDI ライブラリに通知するために、{{span style='color:blue;font-family:monospace;',PdiEnterObject}} 関数をコールします。 *読み取ろうとするアドレスカードのプロパティに対する最大バッファサイズをセットするために、{{span style='color:blue;font-family:monospace;',PdiDefineResizing}} 関数をコールします。 *アドレスカードのプロパティを読み取るために、{{span style='color:blue;font-family:monospace;',PdiReadProperty}} 関数を繰り返しコールします。この繰り返しは、{{span style='color:blue;font-family:monospace;',PdiReadProperty}} が {{span style='color:blue;font-family:monospace;',END:VCard}} プロパティを読み取るまで続きます。このプロパティはアドレスカードのデータの終わりを示します。 *各アドレスカードプロパティについて、{{span style='color:blue;font-family:monospace;',PdiReadPropertyField}} をコールします。これは、プロパティに関連づけられた値を読み取るために必要です。例えば、{{span style='color:blue;font-family:monospace;',kPdiPRN_N}} 名前プロパティを読み取るとき、{{span style='color:blue;font-family:monospace;',AddrImportVCard}} は {{span style='color:blue;font-family:monospace;',PdiReadPropertyField}} を2回コールします。最初に姓を読み取り、次に名を読み取ります。 *新しいアドレスレコードを生成し、それをアドレスブックデータベースに追加します。 *他のクリーンアップ操作を行なう際に割り当てられたメモリを解放します。 繰り返しますが、Listing 3.6 はこの関数の概要に過ぎないことに注意して下さい。関数全体を {{span style='color:blue;font-family:monospace;',AddressTransfer.c}} ファイルで確認することができます。   ---- [[← 4 節に戻る|Palm OS Programmer's Companion Volume II/3-4]] [[↑3 章トップへ|Palm OS Programmer's Companion Volume II/3]] [[6 節に進む →|Palm OS Programmer's Companion Volume II/3-6]]