トップ 一覧 検索 ヘルプ RSS ログイン

Palm OS Programmer's Companion Volume II/3-5の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
[[← 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]]