Technote 1181
Sherlock's Find by Content Text Extractor Plug-ins
|
目次
概要
Text Extractor
プラグインの定義
プラグインが認識できる MIME
タイプの登録
プラグインによって使用される構造体
Text Extractor
が定義する必要のあるルーチン
サンプルプラグイン
アプリケーションからの Text
Extractor プラグインの呼び出し
コードリストの索引
参考文献
|
このテクニカルノートでは、コンテンツ検索
Text Extractor プラグインの作成に使用する API
について説明します。Text Extractor
プラグインはコンテンツ検索によって使用され、索引の作成やファイルの要約を行うときに書類に格納されているテキスト情報を取り出します。これにより、ユーザは、書式設定コマンドや
HTML
タグなどの周辺データや、書類に格納されている情報とは直接関係のないその他のデータの索引作成を避けることができます。書類のタイプに対応した
Text Extractor
プラグインを作成することで、デベロッパは、ユーザがアプリケーションによって作成された書類に格納されている情報を対象に意味のある検索を実行することを可能します。
Text Extractor プラグインは、Mac OS 8.6
またはそれ以降とともに使用することを前提に作成できます。Mac
OS 8.6 には、「HTML Text Extractor」、「PDF Text
Extractor」という 2 つの Text Extractor
プラグインが付属していました。「HTML Text Extractor」は HTML
ファイルから HTML タグを取り去り、HTML
ファイルに格納されているテキストのみを返します。また、「PDF
Text Extractor」は Adobe の PDF (Portable Document Format)
ファイルからテキスト情報だけを取得します。Mac OS 8.5 で HTML
ファイルの索引を作成すると、書類に格納されているテキストと
HTML タグの両方が索引の中に組み込まれていました。さらに、PDF
ファイルは索引作成の対象から除外されていました。Mac OS 8.6
では、これらのファイルから取り出された意味のあるテキスト情報だけが、コンテンツ検索によって使用される索引ファイルの中に組み込まれるようになりました。
このテクニカルノートでは、Text Extractor
プラグインの作成とインストールに必要な情報を提供します。また、詳細なコメントを加えた「サンプル
Text Extractor
プラグイン」も用意されています。デベロッパは、このサンプルに修正を加えるだけで、独自のファイルフォーマットに対応した独自のプラグインを作成することができます。
|
|
概要
Text Extractor
は、ファイルの索引作成と要約の精度を向上させます。例として、リスト
1 のような HTML ファイルがあるとします。
<!--この HTML ファイルには、HTML タグと ASCII テキストの両方
が含まれている。索引を作成するためには、タグを無視し、書類に
含まれるテキストだけを索引に組み込むことが望ましい-->
<HTML>
<BODY>
This is a sample document.
</BODY>
</HTML>
|
ハ
リスト 1 サンプル HTML ファイル
HTML
フォーマットを認識できないと、上記の書類に含まれるすべての単語が索引に組み込まれます。このため、コンテンツ検索で「body」を検索すると上記の書類が検出されますが、ユーザがブラウザでファイルを開いても「body」という単語を見つけることはできません。同様に、HTML
書類を要約すると、要約の中には HTML
タグが表示されてしまいます。HTML Text Extractor は HTML
ファイルのフォーマットを正しく認識できるため、HTML
タグを無視して、書類を開いたときにユーザから見えるテキストだけを返します。上記の例では、「This
is a sample
document.」というテキストだけが索引に組み込まれます。
|
ページの先頭に戻る
|
Text Extractor プラグインの定義
Text Extractor
プラグインは、以下のような特性を持つコードフラグメントです。
- ファイルタイプ:
'fbce'
- クリエータタイプ:
'fndf'
- コードフラグメント名: 「IATextExtractor」
- システム内の位置:
「機能拡張」フォルダの「検索」フォルダ内にある「コンテンツ検索プラグイン」フォルダ。フォルダタイプ
kFindByContentPluginsFolderType
('fbcp') は、フォルダを検索する
FindFolder 関数に渡すことができます。
- エクスポートされる関数 -- Text Extractor
プラグインでは、次の関数をすべてインプリメントしてエクスポートする必要があります。
IAPluginInit
-- Text Extractor
プラグインがオープンされるとき、IAPluginInit
エクスポート関数が呼び出されます。
IAPluginTerm
-- Text Extractor
プラグインを使ったセッションが終了するとき、IAPluginTerm
関数が呼び出されます。この時点で、プラグインは必要なクリーンアップ操作を実行することができます。
IAGetExtractorVersion
-- プラグインが対応している Text Extractor
インタフェースのバージョンを返します。
IACountSupportedDocTypes
--
プラグインが処理方法を認識できる書類タイプの数を返します。この呼び出しは、IAGetIndSupportedDocType
呼び出しに対する有効なインデックスの最大数を返します。
IAGetIndSupportedDocType
-- プラグインがサポートする n
番目の書類タイプを返します (先頭の項目のインデックスは
0 ではなく 1)。それぞれの書類は、MIME (Multipurpose
Internet Mail Extension)
タイプおよびサブタイプによって識別されます。たとえば、HTML
書類は「text/html」という MIME タイプを持ちます。
IAOpenDocument
--
書類のテキストへの参照を作成します。IADocRef
型は、書類を参照するためにプラグインによって定義される
opaque データ型です。IADocAccessorPtr
には、書類への参照と、その書類にアクセスするために使用する関数へのポインタが含まれます。書類アクセッサポインタは、IACloseDocument
が呼び出されるまでに返される IADocRef
を使用するすべての呼び出しに対して有効です。
IACloseDocument
-- プラグイン定義の IADocRef
オブジェクトに必要なクリーンアップ操作を実行します。
IAGetNextTextRun
--
オープンされている書類の参照が存在する場合に、項目に関連づけられたテキストの次のランを取得します。テキストの次のランでバッファを埋めます。入力時、ioSize
はバッファのサイズですが、出力時には
ioSize
はバッファに書き込まれたバイト数になります。書類のエンコーディングまたは言語が変更されると、errIAEndOfTextRun
が返されます。なお、errIAEndOfTextRun
という実行結果は、このルーチンが空のバッファを返すということを必ずしも意味するものではありません。
IAGetTextRunInfo
-- 直前の IAGetNextTextRun
呼び出しによって返されたテキストのエンコーディングと言語を取得します。
Text Extractor
プラグインのリソースファイルには、プラグインが処理できるファイルの種類を知らせる
1 つまたは複数の 'mimp'
リソースが含まれます。これらのリソースのフォーマットについては、次の「プラグインが認識できる
MIME タイプの登録」を参照してください。
|
ページの先頭に戻る
|
プラグインが認識できる MIME タイプの登録
Text Extractor のクライアントは書類を MIME
タイプにマップする必要があります。クライアントによるプラグインが認識できる書類タイプを判断する際に役に立つように、プラグインのリソースファイルには
1 つまたは複数の 'mimp'
リソースを組み込むことができます。独自の 'mimp'
リソースは、「IAExtractor.r」ファイルを参考にして定義することができます。リスト
2 に示すように、'mimp' リソースには、ファイルの
Finder タイプと MIME
タイプにマップするファイル拡張子に関する情報が含まれます。
|
/* PDF (Portable Document Format) 書類に対するサンプル 'mimp' リソース */
#include "IAExtractor.r"
resource 'mimp' (128) {
kIACurrentMIMEMappingVersion,
'PDF ', /* ファイルタイプ */
'CARO', /* ファイルクリエータ */
".pdf," /* ファイル拡張子 */
"application/pdf," /* MIME タイプ */
"Portable Document Format" /* 説明 */
};
|
ハ
リスト 2 PDF ファイルに対するサンプル
'mimp' リソース
索引を作成するとき、コンテンツ検索は Internet Config
の呼び出しを使って、ファイルの MIME
タイプを検出します。ファイルの MIME
タイプが検出されると、そのファイルからテキストを取り出すことができる
Text Extractor プラグインが自動的に使用されます (Text
Extractor プラグインがその 'mimp'
リソースの中でデコードが可能であることを通知している MIME
タイプに基づいて)。
|
ページの先頭に戻る
|
プラグインによって使用される構造体
コンテンツ検索には、Text Extractor
プラグインによって使用されるいくつかのルーチンとコールバックが用意されています。これらのコールバックはメモリ割り当てとファイル入力へのアクセスを提供します。以下のセクションでは、これらのコールバックを提供するためにコンテンツ検索によって使用される構造体と、それらのコールバックそのものについて説明します。
独自のコードの中から Text Extractor
プラグインを呼び出そうとするアプリケーションデベロッパは、自分自身でこれらの構造体の作成と初期化を行うこともできます。これを行う方法については、後述の「アプリケーションからの
Text Extractor
プラグインの呼び出し」のセクションを参照してください。
IAPluginInitBlock 構造体
IAPluginInitBlock レコードは、Text Extractor
プラグインがオープンされている間、常に使用できるコールバックルーチンを提供します。この構造体へのポインタは、プラグインの
IAPluginInit
ルーチンにパラメータとして渡されます。また、IAPluginTerm
ルーチンが呼び出される前であれば、プラグインがこの構造体へのポインタを保存したり、この構造体を介してコールバックを行っても安全です。リスト
3 は、IAPluginInitBlock
構造体の内容と、この構造体によって使用可能となるコールバックのプロトタイプを示しています。この構造体とコールバックを行うためのマクロ
(説明を目的としてリスト 3
の中にルーチンプロトタイプとして示されている)
は、「IAExtractor.h」ファイルの中で定義されています。
|
/* IAPluginInitBlock 構造体の定義 */
typedef struct IAPluginInitBlock* IAPluginInitBlockPtr;
struct IAPluginInitBlock {
IAAllocUPP Alloc;
IAFreeUPP Free;
IAIdleUPP Idle;
};
typedef struct IAPluginInitBlock IAPluginInitBlock;
/* ルーチンプロトタイプ */
void* CallIAAllocProc(IAAllocUPP Alloc, UInt32 inSize);
void CallIAFreeProc(IAFreeUPP Free, void* object);
UInt8 CallIAIdleProc(IAIdleUPP Idle);
|
リスト 3 IAPluginInitBlock
構造体と、この構造体の中で参照されているルーチンの呼び出しに使用できるプロトタイプの宣言
IAPluginInitBlock
は、メモリを割り当てるコールバックと、時間のかかる処理の実行中に呼び出すことのできるアイドルコールバックを提供します。プラグインは、Memory
Manager
を直接呼び出す代わりに、この構造体によって提供されるメモリ割り当てルーチンを使用する必要があります。次に、この構造体によって提供されるコールバックについて説明します。
CallIAAllocProc
|
|
void* CallIAAllocProc(
IAAllocUPP Alloc,
UInt32 inSize);
Alloc --
IAPluginInitBlock 構造体の
Alloc
フィールドに格納されている値。
inSize -- 割り当てるバイト数。
result --
メモリブロックへのポインタ、またメモリが割り当てられない場合は
NULL。
|
CallIAAllocProc は、IAPluginInitBlock
構造体によって提供されるコールバックプロシージャで、メモリを割り当てるためにプラグインによって呼び出されます。
CallIAAllocProc
はメモリを割り当てるために使用できます。プラグインでは、すべてのメモリリクエストに対してこのコールバックを使用する必要があります。正常に実行されると、リクエストされたバイト数を含むブロックへのポインタが返されます。エラーが発生するか、リクエストを満たすために十分なメモリが存在しないと、NULL
が返されます。
CallIAFreeProc
|
|
void CallIAFreeProc(
IAFreeUPP Free,
void* object);
Free --
IAPluginInitBlock 構造体の
Free
フィールドに格納されている値。
object --
CallIAAllocProc
コールバックによって割り当てられたメモリブロックへのポインタ。
|
CallIAFreeProc は、IAPluginInitBlock
構造体によって提供されるコールバックプロシージャで、CallIAAllocProc
ルーチンによって割り当てられたメモリを解放するためにプラグインによって呼び出されます。
CallIAFreeProc
は、CallIAAllocProc
コールバックの呼び出しによって割り当てられたメモリの割り当て解除を行うために使用できます。
CallIAIdleProc
|
|
UInt8 CallIAIdleProc(
IAIdleUPP Idle);
Idle --
IAPluginInitBlock 構造体の
idle
フィールドに格納されている値。
result --
現在の処理がキャンセルされる場合はゼロでない値、処理を継続する場合はゼロ。
|
CallIAIdleProc は、IAPluginInitBlock
構造体によって提供されるコールバックプロシージャで、プラグインが時間のかかるタスクを処理しているときにプラグインによって呼び出されます。
CallIAIdleProc
は、時間のかかるタスクの実行中にプラグインによって呼び出されます。このルーチンを呼び出すことで、プラグインは他のタスクに
CPU
時間の使用を許可します。このコールバックがゼロ以外の値を返す場合、プラグインでは即座に処理を中止して、実行結果として
errIACanceled
を返してください。一方、アイドルコールバックがゼロを返す場合は処理を継続し、必要に応じて再度アイドルプロシージャを呼び出してください。
独自のアプリケーション内部から Text Extractor
プラグインを呼び出そうとするアプリケーションデベロッパは、自分自身でこの構造体を初期化して、必要なコールバックを定義する必要があります。IAPluginInitBlock
構造体のセットアップ方法を示すサンプルについては、このテクニカルノートの後半にある「IAPluginInitBlock
構造体のセットアップ」のセクションを参照してください。
ページの先頭に戻る
IADocAccessorRecord 構造体
IADocAccessorRecord
はファイル内の情報にアクセスするためのコールバックを提供します。プラグインがオープンされている間
(IAPluginInit 呼び出しと
IAPluginTerm
呼び出しの間)、IAPluginInitBlock
の内容が一定であるとしても、プラグインには異なるファイルを参照する
1 つまたは複数の IADocAccessorRecord
構造体が渡される可能性があります。ただし、プラグインの
IACloseDocument
ルーチンが呼び出されるまで、プラグインの
IAOpenDocument ルーチンに渡された
IADocAccessorRecord
構造体はそのまま変わらないと考えるのが妥当です。リスト 4
は、IADocAccessorRecord
の定義と、この構造体を介したコールバックに使用できるマクロ
(説明を目的としてルーチンプロトタイプとして示されている)
について説明します。
/* IADocAccessorRecord 構造体の定義 */
typedef struct IADocAccessorRecord* IADocAccessorPtr;
struct IADocAccessorRecord {
/* docAccessor はファイルを追跡するためにコンテンツ検索によって使用される opaque 型の値。プラグインがこの情報にアクセスすることはできない */
IADocAccessorRef docAccessor;
IADocAccessorOpenUPP OpenDoc;
IADocAccessorCloseUPP CloseDoc;
IADocAccessorReadUPP ReadDoc;
IASetDocAccessorReadPositionUPP SetReadPosition;
IAGetDocAccessorReadPositionUPP GetReadPosition;
IAGetDocAccessorEOFUPP GetEOF;
};
typedef struct IADocAccessorRecord IADocAccessorRecord;
/* ルーチンプロトタイプ */
OSStatus CallIADocumentAccessorOpen(IADocAccessorRef inAccessor);
OSStatus CallIADocumentAccessorClose(IADocAccessorRef inAccessor);
OSStatus CallIADocumentAccessorRead(IADocAccessorRef inAccessor,
void* buffer, UInt32* ioSize);
OSStatus CallIASetDocumentAccessorReadPosition(IADocAccessorRef inAccessor,
SInt32 inMode, SInt32 inOffset);
OSStatus CallIAGetDocumentAccessorReadPosition(IADocAccessorRef inAccessor,
SInt32* outPosition);
OSStatus CallIAGetDocumentAccessorEOF(IADocAccessorRef inAccessor, SInt32* outEOF);
/* 上記のルーチンプロトタイプに対応するマクロ */
#define CallIADocumentAccessorOpen(accessor) \
InvokeIADocAccessorOpenUPP((accessor)->docAccessor, \
(accessor)->OpenDoc)
#define CallIADocumentAccessorClose(accessor) \
InvokeIADocAccessorCloseUPP((accessor)->docAccessor,\
(accessor)->CloseDoc)
#define CallIADocumentAccessorRead(accessor, buffer, size) \
InvokeIADocAccessorReadUPP((accessor)->docAccessor, (buffer),\
(size), (accessor)->ReadDoc)
#define CallIASetDocumentAccessorReadPosition(accessor, mode, offset) \
InvokeIASetDocAccessorReadPositionUPP((accessor)->docAccessor,\
(mode), (offset), (accessor)->SetReadPosition)
#define CallIAGetDocumentAccessorReadPosition(accessor,\
outPosition) \
InvokeIAGetDocAccessorReadPositionUPP((accessor)->docAccessor,\
(outPosition), (accessor)->GetReadPosition)
#define CallIAGetDocumentAccessorEOF(accessor, outEOF) \
InvokeIAGetDocAccessorEOFUPP((accessor)->docAccessor, \
(outEOF), accessor)->GetEOF)
|
ハ
リスト 4 IADocAccessorRecord
構造体と、この構造体の中で参照されているルーチンの呼び出しに使用できるプロトタイプの宣言
リスト 4 で定義されている
IADocAccessorRecord
は、ファイルへのアクセスに必要なすべてのリソースをプラグインに提供します。プラグインでは
File Manager を直接呼び出さないでください。File Manager
を呼び出す代わりに、これらのコールバックを介して、ファイルへのアクセスに必要なすべてのファイル入力操作を実行してください。次に、この構造体で定義されているフィールドとコールバックについて説明します。
CallIADocumentAccessorOpen
|
|
OSStatus CallIADocumentAccessorOpen(
IADocAccessorRef inAccessor);
inAccessor --
IAOpenDocument ルーチンに渡された
IADocAccessorRecord へのポインタ。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
CallIADocumentAccessorOpen は、IADocAccessorRecord
構造体によって提供されるコールバックプロシージャで、入力を行うファイルをオープンするためにプラグインによって呼び出されます。
CallIADocumentAccessorOpen
は読み込みを行うために書類をオープンします。プラグインでは、以下に示すいずれかの入力呼び出しを実行する前に、このルーチンを呼び出して、読み込みの対象となる書類をオープンする必要があります。
CallIADocumentAccessorClose
|
|
OSStatus CallIADocumentAccessorClose(
IADocAccessorRef inAccessor);
inAccessor --
IAOpenDocument ルーチンに渡された
IADocAccessorRecord
へのポインタ。このルーチンが呼び出されるとき、inAccessor
はオープンされた状態になっていなければなりません。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
CallIADocumentAccessorClose は、IADocAccessorRecord
構造体によって提供されるコールバックプロシージャで、CallIADocumentAccessorOpen
呼び出しによってオープンされたファイルをクローズするためにプラグインによって呼び出されます。
CallIADocumentAccessorClose
は、CallIADocumentAccessorOpen
呼び出しでオープンしたファイルをクローズするために呼び出してください。
CallIADocumentAccessorRead
|
|
OSStatus CallIADocumentAccessorRead(
IADocAccessorRef inAccessor,
void* buffer,
UInt32* ioSize);
inAccessor --
IAOpenDocument ルーチンに渡された
IADocAccessorRecord
へのポインタ。このルーチンが呼び出されるとき、inAccessor
はオープンされた状態になっていなければなりません。
buffer --
データが格納されるバッファへのポインタ。
ioSize --
読み込まれるバイト数を含んだ 32
ビット整数へのポインタ。このルーチンが値を返すとき、この値は実際に読み込まれたバイト数に更新されます。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
CallIADocumentAccessorRead は、IADocAccessorRecord
構造体によって提供されるコールバックプロシージャで、ファイルからデータを読み込むためにプラグインによって呼び出されます。
CallIADocumentAccessorRead
は、現在の読み込みファイル位置から *ioSize
バイトを読み込みます。値が返されるとき、*ioSize
は実際に読み込まれたバイト数を反映し、ルーチンの戻り値は呼び出しが正常に実行されたかどうかを表します。このコールバックが
eofErr
エラーを返す場合は、ファイルの末尾に達するまでに何バイトかがバッファに読み込まれた可能性があるため、必ず
*ioSize
に格納されている値をチェックしてください。CallIADocumentAccessorRead
を呼び出すと、ファイルの読み込み位置は読み込まれたバイトの直後まで移動します。次に
CallIADocumentAccessorRead
を呼び出すと、直前の読み込みが終了した位置から次の読み込みが開始されます。
CallIASetDocumentAccessorReadPosition
|
|
OSStatus CallIASetDocumentAccessorReadPosition(
IADocAccessorRef inAccessor,
SInt32 inMode,
SInt32 inOffset);
inAccessor --
IAOpenDocument ルーチンに渡された
IADocAccessorRecord
へのポインタ。このルーチンが呼び出されるとき、inAccessor
はオープンされた状態になっていなければなりません。
inMode --
次の位置決め定数のいずれかを含みます。
kIAFromStartMode --
inOffset
にはファイルの先頭からのオフセットと解釈される値が含まれます。
kIAFromCurrMode --
inOffset
には現在の読み込み位置からのオフセットと解釈される値が含まれます。
kIAFromEndMode --
inOffset
にはファイルの末尾からのオフセットと解釈される値が含まれます。
inOffset --
読み込み位置のオフセットを指定するために使用される符号なし
32 ビット整数を含みます。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
CallIASetDocumentAccessorReadPosition
は、IADocAccessorRecord
構造体によって提供されるコールバックプロシージャで、CallIADocumentAccessorRead
が呼び出されたときに次の読み込みを行う位置を設定するためにプラグインによって呼び出されます。
CallIASetDocumentAccessorReadPosition
は、次の CallIADocumentAccessorRead
がファイルの読み込みを開始する位置を設定するために使用できます。ファイルがはじめてオープンされるとき、その読み込み位置はファイルの先頭に設定されています。
CallIAGetDocumentAccessorReadPosition
|
|
OSStatus CallIAGetDocumentAccessorReadPosition(
IADocAccessorRef inAccessor,
SInt32* outPostion);
inAccessor --
IAOpenDocument ルーチンに渡された
IADocAccessorRecord
へのポインタ。このルーチンが呼び出されるとき、inAccessor
はオープンされた状態になっていなければなりません。
outPosition --
ファイルの先頭から現在の読み込み位置までのオフセットに相当する
32 ビット値へのポインタ。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
CallIAGetDocumentAccessorReadPosition
は、IADocAccessorRecord
構造体によって提供されるコールバックプロシージャで、CallIADocumentAccessorRead
が呼び出されたときに次の読み込みを行う位置を取得するためにプラグインによって呼び出されます。
CallIAGetDocumentAccessorReadPosition
は、次の読み込み操作が行われる位置を
*outPosition
に返します。返された値はファイルの先頭からのオフセットです。
CallIAGetDocumentAccessorEOF
|
|
OSStatus CallIAGetDocumentAccessorEOF(
IADocAccessorRef inAccessor,
SInt32* outEOF);
inAccessor --
IAOpenDocument ルーチンに渡された
IADocAccessorRecord
へのポインタ。このルーチンが呼び出されるとき、inAccessor
はオープンされた状態になっていなければなりません。
outEOF --
ファイルに含まれるバイト数に相当する 32
ビット値へのポインタ。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
CallIAGetDocumentAccessorEOF
は、IADocAccessorRecord
構造体によって提供されるコールバックプロシージャで、入力ファイルの長さを取得するためにプラグインによって呼び出されます。
CallIAGetDocumentAccessorEOF
はファイルの長さを検出するために使用できます。値が返されるとき、*outEOF
の値はファイルに含まれる総バイト数に設定されます。
独自のアプリケーション内部から Text Extractor
プラグインを呼び出そうとするアプリケーションデベロッパは、自分自身でこの構造体を初期化して、必要なコールバックを定義する必要があります。IADocAccessorRecord
構造体のセットアップ方法を示すサンプルについては、このテクニカルノートの後半にある「IADocAccessorRecord
構造体のセットアップ」のセクションを参照してください。
ページの先頭に戻る
|
|
Text Extractor が定義する必要のあるルーチン
このセクションでは、すべての Text Extractor
プラグインによってエクスポートされる必要のあるルーチンについて説明します。このセクションでは、それぞれのルーチンの詳細な説明とあわせて、それぞれのルーチンに関連する重要事項も示します。
IAPluginInit
|
|
OSStatus IAPluginInit(
IAPluginInitBlockPtr initBlock,
IAPluginRef *outPluginRef);
initBlock -- IAPluginInitBlock
構造体へのポインタ。
outPluginRef --
プラグインがオープンされているときに、他のプラグインルーチンに渡される
32 ビット値へのポインタ。プラグインはこの値をその
IAPluginInit
ルーチンに設定します。IAPluginTerm
が呼び出されるまでこの値は変わることなくそのまま保持されます。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAPluginInit
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
プラグインのコードフラグメントが実行の準備を整えた後、プラグインの
IAPluginInit
ルーチンが呼び出されます。このルーチンは、プラグインが必要な初期化操作を実行できるようにします。
initBlock パラメータによってポイントされる
IAPluginInitBlock
内のコールバックは、プラグインがオープンしている間
(IAPluginTerm
が呼び出されるまで)
有効であり続け、プラグインの他のルーチンから呼び出されます。*outPluginRef
に格納される値はプラグインによって使用され、プラグインの呼び出しの間に変化せずにそのまま保持される持続的なステータス情報を格納するために使用されることがあります
(この値はプラグインがクローズした後には保存されません)。
このルーチンをインプリメントする具体的な方法については、「リスト
6」を参照してください。
ページの先頭に戻る
IAPluginTerm
|
|
OSStatus IAPluginTerm(IAPluginRef inPluginRef);
inPluginRef -- プラグインが使用する
32 ビット値。この値は、IAPluginInit
呼び出しで *outPluginRef
パラメータに設定された値と同じです。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAPluginTerm
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
プラグインの Code Fragment Manager
との接続がクローズする前に、プラグインの
IAPluginTerm
ルーチンが呼び出されます。このルーチンは、プラグインがメモリの割り当て解除、リソースファイルのクローズなどの、必要なクリーンアップ操作を実行できるようにします。このルーチンが呼び出されると、次の
IAPluginInit
呼び出しによってプラグインが再度オープンされるまで、プラグインの他の呼び出しは行われなくなります。
このルーチンをインプリメントする具体的な方法については、「リスト
7」を参照してください。
ページの先頭に戻る
IAGetExtractorVersion
|
|
OSStatus IAGetExtractorVersion(
IAPluginRef inPluginRef,
UInt32 outPluginVersion);
inPluginRef -- プラグインが使用する
32 ビット値。この値は、IAPluginInit
呼び出しで *outPluginRef
パラメータに設定された値と同じです。
outPluginVersion -- 32
ビット値へのポインタ。作成するルーチンでは、この値に
kIAExtractorCurrentVersion
を設定する必要があります。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAGetExtractorVersion
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
このルーチンの中で、プラグインは
*outPluginVersion
の値にそのコンパイルに使用した Text Extractor
プラグインインタフェースのバージョンを設定する必要があります。「IAExtractor.h」で定義されている
kIAExtractorCurrentVersion 定数には、Text
Extractor
プラグインインタフェースの現在のバージョンが含まれます。
このルーチンをインプリメントする具体的な方法については、「リスト
8」を参照してください。
ページの先頭に戻る
IACountSupportedDocTypes
|
|
OSStatus IACountSupportedDocTypes(
IAPluginRef inPluginRef,
UInt32* outCount);
inPluginRef -- プラグインが使用する
32 ビット値。この値は、IAPluginInit
呼び出しで *outPluginRef
パラメータに設定された値と同じです。
outCount -- 32
ビット整数へのポインタ。プラグインは、この整数にそれが処理できる書類タイプの数を設定する必要があります。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IACountSupportedDocTypes
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
このルーチンでは、*outCount
にプラグインが処理できる書類タイプの数を設定する必要があります。*outCount
に格納される値は、IAGetIndSupportedDocType
呼び出しのインデックスとして指定できる、有効なインデックスの最大値と解釈されます。
このルーチンをインプリメントする具体的な方法については、「リスト
9」を参照してください。
ページの先頭に戻る
IAGetIndSupportedDocType
|
|
OSStatus IAGetIndSupportedDocType(
IAPluginRef inPluginRef,
UInt32 inIndex,
char** outMIMEType);
inPluginRef -- プラグインが使用する
32 ビット値。この値は、IAPluginInit
呼び出しで *outPluginRef
パラメータに設定された値と同じです。
inIndex --
返される書類タイプのインデックスを指定する 32
ビット整数。インデックス値の範囲は、1 から
IACountSupportedDocTypes
によって返された最大のインデックス値までです。
*outMIMEType -- char*
型のポインタ値。プラグインはこの値を設定して、MIME
タイプ文字列を含む文字列をポイントする必要があります。この文字列が占有するメモリ領域はプラグインに属します。したがって、このメモリ領域がプラグインによって割り当てられた場合、その割り当て解除もプラグインが行わなければなりません。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAGetIndSupportedDocType
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
IAGetIndSupportedDocType ルーチンは
*outMIMEType を設定して、プラグインが認識できる
n 番目の MIME
タイプを含む文字列をポイントします。inIndex
パラメータで指定できるインデックス値は、1 (0 ではなく) から
IACountSupportedDocTypes
呼び出しによって返される最大値までの範囲です。
このルーチンをインプリメントする具体的な方法については、「リスト
10」を参照してください。
ページの先頭に戻る
IAOpenDocument
|
|
OSStatus IAOpenDocument(
IAPluginRef inPluginRef,
IADocAccessorPtr inAccessor,
IADocRef* outDoc);
inPluginRef -- プラグインが使用する
32 ビット値。この値は、IAPluginInit
呼び出しで *outPluginRef
パラメータに設定された値と同じです。
inAccessor --
ファイルから情報を読み込むために必要なコールバックを含んだ
IAPluginInitBlock
へのポインタ。
outDoc --
プラグインが書類に固有の情報を格納するために使用できる
32
ビット値へのポインタ。通常、プラグインは書類に固有のステータス変数へのポインタをこのパラメータに格納します。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAOpenDocument
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
IAOpenDocument
は、プラグインが新しい書類からテキストを取り出すために使用される前に呼び出されます。このルーチンは、プラグインがファイルからテキストの読み込みを開始する前に必要となる初期化操作を実行できるようにします。ファイルの処理に必要なステータス変数またはデータバッファはメモリブロックの中に格納される必要があり、そのブロックへのポインタは
*outDoc
の中に格納される必要があります。この値は、書類がオープンしているときに
IAGetNextTextRun
または IAGetTextRunInfo
ルーチンに渡され、必要なテキストが書類からすべて取り出された後で
IACloseDocument
に渡されます。inAccessor
パラメータによってポイントされる IAPluginInitBlock
と *outDoc
に格納されている値は両方とも、IACloseDocument
が呼び出されるまで有効です。
このルーチンをインプリメントする具体的な方法については、「リスト
11」を参照してください。
ページの先頭に戻る
IACloseDocument
|
|
OSStatus IACloseDocument(
IADocRef inDoc);
inDoc -- プラグインの IAOpenDocument
呼び出しによって作成された書類参照値で、ファイルの処理に必要なステータス変数またはデータバッファへのポインタを含みます。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IACloseDocument
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
IACloseDocument
は必要なテキスト情報がすべて書類から取り出された後で呼び出されます。この呼び出しで、プラグインは、ファイルを処理するために作成され、inDoc
パラメータによって参照されるステータス変数またはバッファを破棄する必要があります。
このルーチンをインプリメントする具体的な方法については、「リスト
12」を参照してください。
ページの先頭に戻る
IAGetNextTextRun
|
|
OSStatus IAGetNextTextRun(
IADocRef inDoc,
void* buffer,
UInt32* ioSize);
inDoc -- プラグインの IAOpenDocument
呼び出しによって作成された書類参照値で、ファイルの処理に必要なステータス変数またはデータバッファへのポインタを含みます。
buffer --
メモリブロックへのポインタ。
ioSize -- 32
ビット整数値へのポインタ。ルーチンが呼び出されるとき、この値は
buffer
パラメータによってポイントされるメモリ領域で使用可能なバイト数と等しい値です。テキストをこのメモリバッファにコピーした後、プラグインはこの値にコピーされた実際のバイト数を設定する必要があります。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAGetNextTextRun
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
IAGetNextTextRun
ルーチンは、メモリバッファがいっぱいになるか、取り出すテキストがなくなるまで、書類から
buffer
パラメータによってポイントされるメモリバッファにテキストをコピーする必要があります。テキストのデコード中に言語エンコーディングがある言語から別の言語に変更されると、プラグインは結果コード
errIAEndOfTextRun
を返すことで、テキストストリーム内にその位置をマーキングします。
このルーチンをインプリメントする具体的な方法については、「#IAGetNextTextRunExample」を参照してください。
ページの先頭に戻る
IAGetTextRunInfo
|
|
OSStatus IAGetTextRunInfo(
IADocRef inDoc,
char** outEncoding,
char** outLanguage);
inDoc -- プラグインの IAOpenDocument
呼び出しによって作成された書類参照値で、ファイルの処理に必要なステータス変数またはデータバッファへのポインタを含みます。
outEncoding -- char*
型の変数へのポインタ。これは省略可能なパラメータで、呼び出し元がこの値を必要としない場合は
NULL
を設定してもかまいません。プラグインは、このパラメータによってポイントされた変数に含まれる文字列へのポインタを格納する必要があります。この文字列には、ファイルから取り出されるテキストの現在の文字エンコーディングに対応するインターネット名が含まれます。
outLanguage -- char*
型の変数へのポインタ。これは省略可能なパラメータで、呼び出し元がこの値を必要としない場合は
NULL
を設定してもかまいません。プラグインは、このパラメータによってポイントされた変数に含まれる文字列へのポインタを格納する必要があります。この文字列には、ファイルから取り出されるテキストの言語名が含まれます。言語は
ISO-639
で定義されているインターネット標準に準拠します。
result --
処理が正常に実行された場合は
errIANoErr、処理が正常に終了しなかった場合はその他のエラーコード。
|
IAGetTextRunInfo
は、プラグインのコードフラグメントの中で指定する必要のあるルーチンです。
IAGetTextRunInfo は、IAGetNextTextRun
によって返された最新のバッファの文字エンコーディングと言語に関する情報を取得します。
2
つのパラメータは省略可能で、呼び出し元のリクエストに応じて指定しても指定しなくてもかまいません。パラメータが必要としない場合は
NULL が設定されます。
プラグインが文字列へのポインタを割り当て、そのポインタを
*outEncoding または *outLanguage
に格納した場合、そのメモリ領域の割り当てを解除するのはプラグインの責任です。
いずれかの値を認識できない場合、プラグインは
*outEncoding または *outLanguage
の値として NULL
を格納します。この値は、プラグインが現在の文字エンコーディングまたは言語を認識できないことを呼び出し元に通知します。
文字エンコーディングに対応するインターネット名を含んだ文字列へのポインタは
*outEncoding
パラメータに返されます。文字エンコーディングに対応するインターネット名とは、「iso-8859-1」、「x-mac-roman」、「euc-jp」などのことです。
このルーチンをインプリメントする具体的な方法については、「リスト
14」を参照してください。
ページの先頭に戻る
|
|
サンプルプラグイン
以下の詳細なコメントを含むサンプルは、「text/plain」MIME
タイプに対応した Text Extractor
プラグインを作成する方法ついて具体的に説明します。このプラグインの機能はファイルから取り出したテキストを呼び出し元に渡すということですが、そのインプリメントは非常に容易です。デベロッパはこのサンプルに簡単な修正を加えるだけで、独自のファイルフォーマットからテキストを取り出ことができます。
|
/* ファイル: PlainTextExtractor.c
Text Extractor プラグインのサンプル/シェル */
/* IAExtractor.h ファイルには、Text Extractor プラグインの作
成に必要な定義と構造体が含まれている */
#include "IAExtractor.h"
/* 次の定数は、プラグインの呼び出し元が保守する参照値に格納さ
れたデータ値として、このサンプルの中で使用される。この定数は
プラグインの作成に必ずしも必要としないが、説明を容易にするた
めに役に立つ */
enum {
kPlainTextExtractorRefType = 'text'
};
/* 次のマクロは、参照値がサンプル内で変更されることなくそのま
ま保持されていることを検証するために使用される */
#define VerifyType(x) ((UInt32)(x)==(UInt32)kPlainTextExtractorRefType)
|
ハ
リスト 5 Text Extractor
プラグインのファイルヘッダおよびインポート
上記のサンプルリストでただ 1
つの重要な側面は、ヘッダファイルがインクルードされるということです。ここでは、必要な定数と構造体の定義を含む「IAExtractor.h」ファイルがインクルードされます。
/* IAPluginInit のインプリメント例 */
OSStatus IAPluginInit(
IAPluginInitBlockPtr initBlock,
IAPluginRef* outPluginRef) {
/* パラメータを検証する */
if (outPluginRef == NULL) return errIAParamErr;
/* 参照値を初期化する。メモリ割り当てを必要とするプ
ラグインは、ここで initBlock の情報をキャッシュに格納
する必要がある */
*outPluginRef = (IAPluginRef)kPlainTextExtractorRefType;
/* ノーエラーを返す */
return errIANoErr;
}
|
ハ
リスト 6 IAPluginInit
のサンプル
IAPluginInit
はプラグインに加えられる最初の呼び出しです。この呼び出しの間に、プラグインは必要な変数またはテーブルをセットアップする必要があります。また、実行中のプラグインが
initBlock パラメータによってポイントされる
IAPluginInitBlock
のコールバックをその後、必要とする場合は、このポインタのコピーを保存することも必要です。
ページの先頭に戻る
/* IAPluginTerm のインプリメント例 */
OSStatus IAPluginTerm(IAPluginRef inPluginRef) {
/* パラメータを検証する */
if (!VerifyType(inPluginRef))
return errIAParamErr;
/* ここでその他の破棄操作を実行する... */
....
/* ノーエラーを返す */
return errIANoErr;
}
|
ハ
リスト 7 IAPluginTerm
のサンプル
通常、IAPluginTerm
ルーチンは、プラグインによって割り当てられたメモリの割り当て解除、リソースファイルのクローズ、および実行する必要のあるその他のクリーンアップタスクを行うために使用されます。
ページの先頭に戻る
/* IAGetExtractorVersion のインプリメント例 */
OSStatus IAGetExtractorVersion(
IAPluginRef inPluginRef,
UInt32* outPluginVersion) {
/* パラメータを検証する */
if (!VerifyType(inPluginRef) || !outPluginVersion )
return errIAParamErr;
/* 戻り値に、このコードのコンパイルに使用した
インタフェースのバージョンを設定する */
*outPluginVersion = kIAExtractorCurrentVersion;
/* ノーエラーを返す */
return errIANoErr;
}
|
ハ
リスト 8 IAGetExtractorVersion
のサンプル
kIAExtractorCurrentVersion
値には、常に「IAExtractor.h」ファイル内の宣言に対応する現在のバージョンが含まれます。現在のインプリメンテーションでは、この値は
kIAExtractorVersion1 に設定されています。
ページの先頭に戻る
/* IACountSupportedDocTypes のインプリメント例 */
OSStatus IACountSupportedDocTypes(
IAPluginRef inPluginRef,
UInt32* outCount) {
/* パラメータを検証する */
if (!VerifyType(inPluginRef) || ! outCount)
return errIAParamErr;
/* 定数は IAGetIndSupportedDocType にインデックスとして渡される最大値 */
*outCount = 1;
/* ノーエラーを返す */
return errIANoErr;
}
|
ハ
リスト 9 IACountSupportedDocTypes
のサンプル
このサンプルでは、ただ 1
つの書類タイプ、つまりプレーンテキスト書類だけがサポートされます。
ページの先頭に戻る
/* IAGetIndSupportedDocType のインプリメント例 */
OSStatus IAGetIndSupportedDocType(
IAPluginRef inPluginRef,
UInt32 inIndex,
char **outMIMEType) {
/* ローカル変数をセットアップする */
static char* supportedDocType = "text/plain";
/* パラメータを検証する */
if (!VerifyType(inPluginRef) || !outMIMEType || inIndex != 1)
return errIAParamErr;
/* 戻り値を設定する */
*outMIMEType = supportedDocType;
/* 処理を正常に終了する */
return errIANoErr;
}
|
ハ
リスト 10 IAGetIndSupportedDocType
のサンプル
IAGetIndSupportedDocType
の上記の宣言では、MIME
タイプ文字列はプラグインのグローバルの中にスタティック変数として格納されています。
ページの先頭に戻る
/* IAOpenDocument のインプリメント例 */
OSStatus IAOpenDocument(
IAPluginRef inPluginRef,
IADocAccessorPtr inDocAccessor,
IADocRef* outDoc) {
/* ローカル変数 */
OSStatus err;
/* パラメータを検証する */
if (!VerifyType(inPluginRef) || !inDocAccessor || !outDoc)
return errIAParamErr;
/* オープニングルーチンを呼び出す */
err = CallIADocumentAccessorOpen(inDocAccessor);
if (err != errIANoErr)
return err;
/* IADocRef はプラグインによって定義されている。このサンプル
では、アクセッサから直接的に読み込みを行っているだけなので、
IADocAccessorPtr という IADocRef opaque データ型を定義してい
る */
*outDoc = (IADocRef)inDocAccessor;
/* 処理を正常に終了する */
return errIANoErr;
}
|
ハ
リスト 11 IAOpenDocument
のサンプル
上に示した IAOpenDocument
呼び出しで、プラグインは、書類参照パラメータ
(*outDoc) に含まれる inDocAccessor
のコピーをキャッシュに格納する前に、inDocAccessor
パラメータによってポイントされる IAPluginInitBlock
レコードを介してコールバックを行っています。この値は、次に続くサンプルリストの中で書類を参照するために使用されます。
ページの先頭に戻る
/* IACloseDocument のインプリメント例 */
OSStatus IACloseDocument(IADocRef inDoc) {
/* ローカル変数 */
IADocAccessorPtr docAccessor;
OSStatus err;
/* パラメータを検証する */
if (inDoc == NULL)
return errIAParamErr;
/* IADocRef を IAOpenDocument で定義したもの (このサンプルで
は IADocAccessorPtr) にキャストする */
docAccessor = (IADocAccessorPtr)inDoc;
/* コールバックを使ってファイルをクローズする */
err = CallIADocumentAccessorClose(docAccessor);
/* 最後のクローズのステータスを返す */
return err;
}
|
ハ
リスト 12 IACloseDocument
のサンプル
上に示した IACloseDocument
呼び出しでは、プラグインは IAPluginInitBlock
構造体を介してコールバックを行い、ファイルをクローズしています。IAPluginInitBlock
構造体へのポインタは、リスト
11 に示した IAOpenDocument
呼び出しの実行中にコピーが保存された inDoc
パラメータから強制的に持ち込まれます。
ページの先頭に戻る
/* IAGetNextTextRun のインプリメント例 */
OSStatus IAGetNextTextRun(
IADocRef inDoc,
void* buffer,
UInt32* size) {
/* ローカル変数 */
IADocAccessorPtr docAccessor;
OSStatus err;
/* パラメータを検証する */
if (!inDoc)
return errIAParamErr;
/* IADocRef を IAOpenDocument で定義したもの (このサンプルで
は IADocAccessorPtr) にキャストする */
docAccessor = (IADocAccessorPtr)inDoc;
/* ファイルからの読み込みをコールバックする */
err = CallIADocumentAccessorRead(docAccessor, buffer, size);
/* 読み込み操作の結果を返す */
return err;
}
|
ハ
リスト 13 IAGetNextTextRun
のサンプル
上に示した IACloseDocument
呼び出しでは、プラグインは IAPluginInitBlock
構造体を介してコールバックを行い、ファイルからデータバイトを読み込んでいます。IAPluginInitBlock
構造体へのポインタは、リスト
11 に示した IAOpenDocument
呼び出しの実行中にコピーが保存された inDoc
パラメータから強制的に持ち込まれます。
ページの先頭に戻る
/* IAGetTextRunInfo のインプリメント例 */
OSStatus IAGetTextRunInfo(
IADocRef inDoc,
char** outEncoding,
char** outLanguage) {
/* ファイルのエンコーディングと言語がわからないため NULL に設定する */
if (outEncoding != NULL) *outEncoding = NULL;
if (outLanguage != NULL) *outLanguage = NULL;
/* ローカル変数 */
return errIANoErr;
}
|
ハ
リスト 14 IAGetTextRunInfo
のサンプル
このサンプルでは、テキストエンコーディングと言語の両方が認識できないことを示す
NULL が返されます。
ページの先頭に戻る
|
|
アプリケーションからの Text Extractor
プラグインの呼び出し
次に、クライアントが Text Extractor
プラグインを使って書類からテキストを取り出す方法についてサンプルを示します。アプリケーションでは、これらのルーチンまたはこれらのルーチンに修正を加えたものを使用して
Text Extractor
プラグインを呼び出し、事実上あらゆる書類タイプからテキストを取り出すことができます。
以下の各ステップでは、プラグインのコードフラグメントをセットアップする方法、コールバック構造体をセットアップする方法、そして最後にテキストの取り出しを実行するためにプラグインを呼び出す方法について説明します。なお、このサンプルでは、特定の書類に対応した適切なプラグインを検索または判断する方法については説明しません。
Text Extractor プラグインのセットアップ
まず、実行を準備するためにプラグインのコードフラグメントをセットアップし、呼び出したいルーチンへのポインタをプラグインへのアクセスに使用する構造体に格納することから始めます。リスト
15には、このタスクの実行に使用するルーチンと宣言が含まれています。
|
/* 次の typedef は Text Extractor プラグインによってエクス
ポートされるルーチンに対応している。このサンプルでは、コード
内からプラグインの呼び出しを行うためにこれらのルーチンを使用
する */
typedef OSStatus (*PluginInitCallPtr)(IAPluginInitBlockPtr initBlock,
IAPluginRef* outPluginRef);
typedef OSStatus (*PluginTermCallPtr)(IAPluginRef inPluginRef);
typedef OSStatus (*GetExtractorVersionCallPtr)(IAPluginRef inPluginRef,
UInt32* outPluginVersion);
typedef OSStatus (*CountSupportedDocTypesCallPtr)(IAPluginRef inPluginRef,
UInt32* outCount);
typedef OSStatus (*GetIndSupportedDocTypeCallPtr)(IAPluginRef inPluginRef,
UInt32 inIndex, char** outMIMEType);
typedef OSStatus (*OpenDocumentCallPtr)(IAPluginRef inPluginRef,
IADocAccessorPtr inDoc, IADocRef* outDoc);
typedef OSStatus (*CloseDocumentCallPtr)(IADocRef inDoc);
typedef OSStatus (*GetTextRunInfoCallPtr)(IADocRef inDoc,
char** outEncoding, char** outLanguage);
typedef OSStatus (*GetNextTextRunCallPtr)(IADocRef inDoc, void* buffer,
UInt32* size);
/* ExtractorRec はプラグインのコードフラグメントそのものに関
する情報を格納するために使用される。この中には、フラグメント
のルーチンへのポインタ、およびフラグメントの CFM 接続 ID 番号
が含まれる */
typedef struct {
ConnectionID connID;
PluginInitCallPtr PluginInit;
PluginTermCallPtr PluginTerm;
GetExtractorVersionCallPtr GetExtractorVersion;
CountSupportedDocTypesCallPtr CountSupportedDocTypes;
GetIndSupportedDocTypeCallPtr GetIndSupportedDocType;
OpenDocumentCallPtr OpenDocument;
CloseDocumentCallPtr CloseDocument;
GetTextRunInfoCallPtr GetNextTextRun;
GetNextTextRunCallPtr GetTextRunInfo;
} ExtractorRec, *ExtractorRecPtr;
/* OpenExtractor は、spec パラメータで参照される FSSpec レ
コードによって参照される Text Extractor プラグインに属する
コードフラグメントをロードする。処理が正常に終了すると、プラ
グインのルーチンへのポインタを含む構造体が返される。エラーが
発生すると、NULL が返される */
ExtractorRecPtr OpenExtractor(FSSpec *spec) {
ExtractorRecPtr extr;
Str63 fragName;
Ptr mainAddr;
Str255 errName;
Boolean fragmentExists; /* fragConnID の内容を追跡する */
ConnectionID fragConnID;
CFragSymbolClass symbolClass;
/* ローカル変数を既知のステータスにセットアップする */
extr = NULL;
fragmentExists = false;
/* プラグインに関する情報を保存するためにメモリを割り当てる */
extr = (ExtractorRecPtr) NewPtrClear(sizeof(ExtractorRec));
if (extr == NULL) goto bail;
/* 使用できるようにプラグインのコードフラグメントをセットアップする */
err = GetDiskFragment(spec, 0, kWholeFork, fragName, kLoadNewCopy,
&fragConnID, &mainAddr, errName);
if (err != noErr) goto bail;
fragmentExists = true;
extr->connID = fragConnID;
/* 呼び出したいルーチンへのポインタを保存する */
err = FindSymbol(fragConnID, "\pIAPluginInit",
(Ptr*) &extr->PluginInit, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIAPluginTerm",
(Ptr*) &extr->PluginTerm, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIAGetExtractorVersion",
(Ptr*) &extr->GetExtractorVersion, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIACountSupportedDocTypes",
(Ptr*) &extr->CountSupportedDocTypes, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIAGetIndSupportedDocType",
(Ptr*) &extr->GetIndSupportedDocType, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIAOpenDocument",
(Ptr*) &extr->OpenDocument, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIACloseDocument",
(Ptr*) &extr->CloseDocument, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIAGetNextTextRun",
(Ptr*) &extr->GetNextTextRun, &symbolClass);
if (err != noErr) goto bail;
err = FindSymbol(fragConnID, "\pIAGetTextRunInfo",
(Ptr*) &extr->GetTextRunInfo, &symbolClass);
if (err != noErr) goto bail;
/* 正常に処理を終了する */
return extr;
bail:
if (fragmentExists) CloseConnection(&fragConnID);
if (extr != NULL) DisposePtr(Ptr) extr);
return NULL;
}
/* CloseExtractor はプラグインのコードフラグメントをアンロー
ドし、プラグインをオープンするときに割り当てたメモリを解放す
る */
void CloseExtractor(ExtractorRecPtr extr) {
/* プラグインのファイルへの Code Fragment Manager 接続をクローズする */
CloseConnection(&extr->connID);
/* プラグインのコードフラグメントを追跡するために使用していた
メモリを解放する */
DisposePtr((Ptr) extr);
}
|
ハ
リスト 15 実行に使用する Text Extractor
プラグインのコードフラグメントをセットアップするルーチン
リスト 15
に示したプロトタイプを使用すると、プラグインのコールバックを行えるようになります。これらのルーチンへのポインタは
ExtractorRec
構造体に格納されています。
ページの先頭に戻る
IAPluginInitBlock 構造体のセットアップ
リスト 16 に、IAPluginInitBlock
構造体をセットアップするルーチンを示します。ここで、プラグインによって使用されるコールバックは、構造体に含まれるそれらのコールバックを参照するルーチンディスクリプタを保存する構造体の中で参照されます。
|
/* NewIAPluginInitBlock は、プラグインが呼び出すことのできる
メモリ割り当てルーチンとアイドルルーチンを含む新しい
InitBlock レコードを割り当てる。エラーが発生すると、NULL が返
される */
IAPluginInitBlockPtr NewIAPluginInitBlock(void) {
IAPluginInitBlockPtr iBlock;
iBlock = NULL;
iBlock = (IAPluginInitBlockPtr) NewPtrClear(sizeof(IAPluginInitBlock));
if (iBlock == NULL) goto bail;
iBlock->Alloc = NewIAAllocProc(MyIAAlloc);
if (iBlock->Alloc == NULL) goto bail;
iBlock->Free = NewIAFreeProc(MyIAFreeProc);
if (iBlock->Free == NULL) goto bail;
iBlock->Idle = NewIAIdleProc(MyIAIdleProc);
if (iBlock->Idle == NULL) goto bail;
return iBlock;
bail:
if (iBlock != NULL) {
if (iBlock->Alloc != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) iBlock->Alloc);
if (iBlock->Free != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) iBlock->Free);
if (iBlock->Idle != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) iBlock->Idle);
DisposePtr((Ptr) iBlock);
}
return NULL;
}
/* DisposeIAPluginInitBlock は、NewIAPluginInitBlock で割り当
てられた InitBlock レコードが占有するメモリを解放する */
void DisposeIAPluginInitBlock(IAPluginInitBlockPtr iBlock) {
DisposeRoutineDescriptor((UniversalProcPtr) iBlock->Alloc);
DisposeRoutineDescriptor((UniversalProcPtr) iBlock->Free);
DisposeRoutineDescriptor((UniversalProcPtr) iBlock->Idle);
DisposePtr((Ptr) iBlock);
}
|
ハ
リスト 16 IAPluginInitBlock
構造体の割り当てと初期化を行うルーチン
リスト 16 に示したルーチンは、Memory Manager
を呼び出すルーチンを使用するため、IAPluginInitBlock
構造体の割り当てと割り当て解除を行います。
ページの先頭に戻る
IADocAccessorRecord 構造体のセットアップ
リスト 17
のルーチンと宣言は、プラグインのファイルアクセスコールバックをセットアップする方法について具体的に説明します。ここでは、コールバック構造体と、ファイルそのものを継続的に追跡するもう
1 つの構造体を割り当てます。
/* MyDocumentReference には、プラグインによって使用される入力
ソースを追跡するために呼び出し元によって使用される情報が含ま
れる。ここでは、Mac OS ファイルを使用している */
typedef struct {
FSSpec spec; /* FSSpec レコードのコピー */
Boolean docOpen; /* 書類がオープンされているときは true */
short refnum; /* ファイル参照番号 */
} MyDocumentReference, *MyDocRefPtr;
/* このサンプルでは、IADocAccessorRecord のフィールドに、Mac
OS ファイルシステムを介して呼び出されるルーチンを参照するルー
チンディスクリプタを書き込む。これらのルーチンは以下のように
定義されている */
static OSStatus MyIADocAccessorOpenProc(IADocAccessorRef inAccessor) {
MyDocRefPtr refptr;
IADocAccessorPtr accPtr;
OSErr err;
accPtr = (IADocAccessorPtr) inAccessor;
refptr = (MyDocRefPtr) accPtr->docAccessor;
err = FSpOpenDF(&refptr->spec, fsRdPerm, &refptr->refnum);
if (err == noErr)
refptr->docOpen = true;
return (OSStatus) err;
}
static OSStatus MyIADocAccessorCloseProc(IADocAccessorRef inAccessor) {
MyDocRefPtr refptr;
IADocAccessorPtr accPtr;
accPtr = (IADocAccessorPtr) inAccessor;
refptr = (MyDocRefPtr) accPtr->docAccessor;
if ( ! refptr->docOpen)
return errIAParamErr;
FSClose(refptr->refnum);
refptr->docOpen = false;
return errIANoErr;
}
static OSStatus MyIADocAccessorReadProc(IADocAccessorRef inAccessor,
void* buffer, UInt32* ioSize) {
MyDocRefPtr refptr;
IADocAccessorPtr accPtr;
OSErr err;
accPtr = (IADocAccessorPtr) inAccessor;
refptr = (MyDocRefPtr) accPtr->docAccessor;
if ( ! refptr->docOpen)
return errIAParamErr;
err = FSRead(refptr->refnum, ioSize, buffer);
return (OSStatus) err;
}
static OSStatus MyIASetDocAccessorReadPositionProc(
IADocAccessorRef inAccessor, SInt32 inMode, SInt32 inOffset) {
MyDocRefPtr refptr;
IADocAccessorPtr accPtr;
OSErr err;
accPtr = (IADocAccessorPtr) inAccessor;
refptr = (MyDocRefPtr) accPtr->docAccessor;
if ( ! refptr->docOpen)
return errIAParamErr;
case (inMode) {
case kIAFromStartMode:
err = SetFPos(refptr->refnum, fsFromStart, inOffset);
break;
case kIAFromCurrMode:
err = SetFPos(refptr->refnum, fsFromMark, inOffset);
break;
case kIAFromEndMode:
err = SetFPos(refptr->refnum, fsFromLEOF, inOffset);
break;
default:
err = errIAParamErr;
break;
}
return (OSStatus) err;
}
static OSStatus MyIAGetDocAccessorReadPositionProc(
IADocAccessorRef inAccessor, SInt32* outPosition) {
MyDocRefPtr refptr;
IADocAccessorPtr accPtr;
OSErr err;
accPtr = (IADocAccessorPtr) inAccessor;
refptr = (MyDocRefPtr) accPtr->docAccessor;
if ( ! refptr->docOpen)
return errIAParamErr;
err = GetFPos(refptr->refnum, outPosition);
return (OSStatus) err;
}
static OSStatus MyIAGetDocAccessorEOFProc(
IADocAccessorRef inAccessor, SInt32* outEOF) {
MyDocRefPtr refptr;
IADocAccessorPtr accPtr;
OSErr err;
accPtr = (IADocAccessorPtr) inAccessor;
refptr = (MyDocRefPtr) accPtr->docAccessor;
if ( ! refptr->docOpen)
return errIAParamErr;
err = GetEOF(refptr->refnum, outEOF);
return (OSStatus) err;
}
/* NewIADocAccessorRec は、Mac OS ファイルシステムを介して呼
び出されるルーチンを参照するルーチンディスクリプタを含む
IADocAccessorRecord を初期化する。NewIADocAccessorRec は、
ファイルに関する情報を含むレコードを IADocAccessorRecord レ
コードの docAccessor フィールドに格納する。エラーが発生する
と、NULL が返される */
IADocAccessorPtr NewIADocAccessorRec(FSSpec *targetFile) {
IADocAccessorPtr docAcc;
MyDocRefPtr refptr;
iBlock = NULL;
refptr = NULL;
refptr = (MyDocRefPtr) NewPtr(sizeof(MyDocumentReference));
if (refptr == NULL) goto bail;
refptr->spec = *targetFile;
refptr->docOpen = false;
refptr->refnum = 0;
docAcc = (IADocAccessorPtr) NewPtrClear(sizeof(IADocAccessorRecord));
if (docAcc == NULL) goto bail;
docAcc->docAccessor = (IADocAccessorRef) refptr;
docAcc->OpenDoc = NewIADocAccessorOpenProc(MyIADocAccessorOpenProc);
if (docAcc->OpenDoc == NULL) goto bail;
docAcc->CloseDoc = NewIADocAccessorCloseProc(MyIADocAccessorCloseProc);
if (docAcc->CloseDoc == NULL) goto bail;
docAcc->ReadDoc = NewIADocAccessorReadProc(MyIADocAccessorReadProc);
if (docAcc->ReadDoc == NULL) goto bail;
docAcc->SetReadPosition = NewIASetDocAccessorReadPositionProc(
MyIASetDocAccessorReadPositionProc);
if (docAcc->SetReadPosition == NULL) goto bail;
docAcc->GetReadPosition = NewIAGetDocAccessorReadPositionProc(
MyIAGetDocAccessorReadPositionProc);
if (docAcc->GetReadPosition == NULL) goto bail;
docAcc->GetEOF = NewIAGetDocAccessorEOFProc(
MyIAGetDocAccessorEOFProc);
if (docAcc->GetEOF == NULL) goto bail;
return docAcc;
bail:
if (refptr != NULL) DisposePtr((Ptr) refptr);
if (docAcc != NULL) {
if (docAcc->OpenDoc != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->OpenDoc);
if (docAcc->CloseDoc != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->CloseDoc);
if (docAcc->ReadDoc != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->ReadDoc);
if (docAcc->SetReadPosition != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->SetReadPosition);
if (docAcc->GetReadPosition != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->GetReadPosition);
if (docAcc->GetEOF != NULL)
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->GetEOF);
DisposePtr((Ptr) docAcc);
}
return NULL;
}
/* DisposeIADocAccessorRec は、NewIADocAccessorRec によって割
り当てられた IADocAccessorRecord を解放する。すべてのサブ
フィールドの割り当ても解除される。ファイルがオープンされてい
る場合は、構造体の割り当てを解除する前にファイルがクローズさ
れる */
void DisposeIADocAccessorRec(IADocAccessorPtr docAcc) {
MyDocRefPtr refptr;
/* 書類参照を破棄する */
refptr = (MyDocRefPtr) docAcc->docAccessor;
/* ファイルがクローズされていることを確認する -- そうでなければクローズする */
if (refptr->docOpen) FSClose(refptr->refnum);
DisposePtr((Ptr) refptr);
/* アクセッサ構造体を解放する */
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->OpenDoc);
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->CloseDoc);
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->ReadDoc);
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->SetReadPosition);
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->GetReadPosition);
DisposeRoutineDescriptor((UniversalProcPtr) docAcc->GetEOF);
DisposePtr((Ptr) docAcc);
}
|
ハ
リスト 17 IADocAccessorRecord
の割り当てと初期化を行うルーチン
リスト 17 では、File Manager
の呼び出しを使ってファイルにアクセスしています。File Manager
によって使用される情報を追跡するため、その情報を含むプライベート構造体へのポインタを
IADocAccessorRecord
の docAccessor フィールドに格納しています。
ページの先頭に戻る
Text Extractor プラグインの呼び出し
リスト 18 のルーチンは Text Extractor
プラグインを呼び出して、ファイルからテキスト情報を収集します。ファイルから収集されたテキストは、呼び出し元がパラメータとして指定しているルーチンを介して呼び出し元に渡されます。
|
/* kETBufferSize は、テキストのチャンクを取得するために割り当
てられているバッファのサイズを決定する */
#define kETBufferSize (1024*1)
/* TextSinkProc は呼び出し元によって提供されるコールバック
ルーチン。ファイルから取り出されたテキストは、そのままこの
ルーチンに渡される */
typedef OSErr (*TextSinkProc)(void* text, long length, long refcon);
/* ExtractTextFromFile は、*theExtractor によって参照されてい
る Text Extractor プラグインを呼び出して、*targetFile によっ
て参照されているファイルからテキストを取り出す。テキストの取
り出しと並行して、取り出されたテキストは textsink パラメータ
で指定されている TextSinkProc に送信される。refcon は、
TextSinkProc の refcon パラメータに渡される値 */
OSErr ExtractTextFromFile(FSSpec *targetFile, FSSpec *theExtractor,
TextSinkProc textsink, long refcon) {
ExtractorRecPtr extractor;
IAPluginInitBlockPtr initblock;
IADocAccessorPtr accRec;
IAPluginRef inPluginRef;
UInt32 pluginVersion;
Boolean exInited, docOpen;
IADocRef docRef;
Ptr etBuffer;
/* ローカル変数を既知のステータスにセットアップする */
extractor = NULL;
initblock = NULL;
accRec = NULL;
exInited = false;
docOpen = false;
etBuffer = NULL;
UInt32 bytecount;
/* プラグインを初期化する */
extractor = OpenExtractor(theExtractor);
if (extractor == NULL) goto bail;
/* 基本的なメモリタスクを実行するため、プラグインによって使用
されるコールバックを初期化する */
initblock = NewIAPluginInitBlock();
if (initblock == NULL) goto bail;
/* プラグインの初期化ルーチンを呼び出す */
err = extractor->PluginInit(initBlock, &pluginRef);
if (err != noErr) goto bail;
exInited = true;
/* プラグインに問合せを行い、現在使用しているインタフェースの
バージョンとプラグインの構築に使用したインタフェースのバー
ジョンが同期していることを確認する */
err = extractor->GetExtractorVersion(pluginRef, &pluginVersion);
if (err != noErr) goto bail;
if (pluginVersion != kIAExtractorVersion1) { err = errIAParamErr; goto bail; }
/* 目的の書類を対象としたファイル入力を行うため、プラグインに
よって使用されるコールバックを初期化する */
accRec = NewIADocAccessorRec(targetFile);
if (accRec == NULL) goto bail;
/* 読み込みに使用するメモリバッファを割り当てる */
etBuffer = NewPtr(kETBufferSize);
if (etBuffer == NULL) { err = memFullErr; goto bail; }
/* プラグインを呼び出し、入力のために書類をオープン
するように要求する */
err = extractor->OpenDocument(pluginRef, accRec, &docRef);
if (err != noErr) goto bail;
docOpen = true;
/* ここで、プラグインがそれ以上バイトを返さなくなるまでループに入る */
while (true) {
/* バッファ全体にテキストを書き込んでみる */
bytecount = kETBufferSize;
err = extractor->GetNextTextRun(docRef, etBuffer, &bytecount);
/* eofErr などのその他のエラーが発生した場合はループを抜ける */
if (err != noErr) goto bail;
/* 言語エンコーディングが変更されると、errIAEndOfTextRun が返
される。この場合は何も行わない。しかし、場合によってはいくつ
かの追加処理を行う必要もある */
if (err == errIAEndOfTextRun) {
/* たいてい、errIAEndOfTextRun は、直前の呼び出しが直前のエン
コーディングランからすべての文字を読み込んでいる場合に新しい
文字エンコーディングの範囲の先頭を示すためだけに、サイズがゼ
ロのバッファとともに返されるため、ここでは bytecount をチェッ
クしない */
/* ゼロバイトが返されたときは通常の終了処理を行う */
} else if (bytecount == 0)
break;
/* この時点で書類からテキストのチャンクを取得した。ここで、
それを呼び出し元のシンクに渡す */
err = textsink(etBuffer, bytecount, refcon);
if (err != noErr) goto bail;
}
/* この時点で書類に含まれるすべてのテキストが読み込まれた。こ
こで、プラグインにクローズを要求し、メモリバッファの破棄と
ファイル入力コールバック構造体の破棄を行って、書類をクローズ
する。DisposeIADocAccessorRec はリスト 17 で定義されている */
extractor->CloseDocument(docRef);
docOpen = false;
DisposePtr(etBuffer);
etBuffer = NULL;
DisposeIADocAccessorRec(docAcc);
docAcc = NULL;
/* 書類をクローズした後、プラグインは解放される。これは、プラ
グインの終了プロシージャの呼び出し、メモリ割り当てコールバッ
クの解放 (DisposeIAPluginInitBlock はリスト 16 で定義されてい
る)、そしてプラグインのコードフラグメントの解放
(CloseExtractor はリスト 15 で定義されている) によって実行さ
れる */
extractor->PluginTerm(pluginRef);
exInited = false;
DisposeIAPluginInitBlock(initblock);
initblock = NULL;
CloseExtractor(extractor);
extractor = NULL;
/* 処理を正常に終了する */
return noErr;
bail:
/* エラー処理コード。回復ステートメントの順序が重要であることに注意 */
if (docOpen) extractor->CloseDocument(docRef);
if (etBuffer != NULL) DisposePtr(etBuffer);
if (docAcc != NULL) DisposeIADocAccessorRec(docAcc);
if (exInited) extractor->PluginTerm(pluginRef);
if (initblock != NULL) DisposeIAPluginInitBlock(initblock);
if (extractor != NULL) CloseExtractor(extractor);
return err;
}
|
ハ
リスト 18 Text Extractor
ルーチンを呼び出すルーチンのサンプル
リスト 18
に示したルーチンは、プラグインのルーチンを直接呼び出すことで実際のテキストの取り出しを実行します。このサンプルでは、言語エンコーディングまたは文字エンコーディングに関心が払われていません。ただし、このサンプルに若干の修正を加えるだけで、この情報を簡単に取得できるようになります。このルーチンでは、リスト
15、リスト 16、およびリスト
17
で定義されている構造体とルーチンを使用しています。
ページの先頭に戻る
|
|
コードリストの索引
次に、このテクニカルノートに含まれているコードリストの一覧を示します。リスト
5 から 14
はサンプルプラグインの内容を定義しています。また、リスト 15
から 18
はアプリケーションからプラグインを呼び出すための具体的な方法を示しています。
|
ページの先頭に戻る
Further References
ページの先頭に戻る
更新日: 1999 年 10 月 5 日
|