英語フランス語スペイン語

OnWorksファビコン

perliol - クラウドでオンライン

Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、または MAC OS オンライン エミュレーターを介して、OnWorks の無料ホスティング プロバイダーで perliol を実行します。

これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、MAC OS オンライン エミュレーターなど、複数の無料オンライン ワークステーションのいずれかを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド perliol です。

プログラム:

NAME


perliol - レイヤーでの Perl の IO 実装のための C API.

SYNOPSIS


/* レイヤーを定義中 ... */
#含む

DESCRIPTION


このドキュメントでは、PerlIO 抽象化の動作と実装について説明します
"USE_PERLIO" が定義されている場合、perlapio に記述されます。

歴史 および 経歴
PerlIO の抽象化は perl5.003_02 で導入されましたが、単なる
perl5.7.0 までの抽象化。 しかし、その間に多くの perl 拡張機能が切り替わった
そのため、API は (ソース) 互換性を維持するためにほとんど修正されています。

実装の目的は、柔軟なプラットフォームで PerlIO API を提供することです。
ニュートラルな態度。 また、「vtables を使用したオブジェクト指向 C」アプローチの試みでもあります。
Perl 6 に適用される可能性があります。

Basic Structure
PerlIO はレイヤーのスタックです。

低レベルのスタックは、低レベルのオペレーティング システム コール (ファイル
C の記述子) バイトの入出力、スタック バッファーの上位レイヤー、フィルター、
そうでなければ I/O を操作し、文字 (またはバイト) を Perl に返します。 条項 上記の.
および 以下 スタック層の相対的な位置を参照するために使用されます。

レイヤーには、I/O 操作のテーブルである「vtable」が含まれています (C レベルでは、関数のテーブル
ポインター)、およびステータスフラグ。 vtable の関数は、次のような操作を実装します
「開く」「読む」「書く」。

「読み取り」などの I/O が要求されると、要求は最初に Perl から
各レイヤーの「読み取り」関数を使用してスタックし、下部で入力が要求されます
オペレーティング システム サービスの場合、結果がスタックに返され、最終的に
Perl データとして解釈されます。

リクエストは、必ずしもオペレーティング システムにまで届くとは限りません。
ここで PerlIO バッファリングの出番です。

を行うとき 開いた() デプロイする追加の PerlIO レイヤーを指定します。
指定は、既存のデフォルト スタックの上に「プッシュ」されます。 それを見る一つの方法は、
「左側がオペレーティング システム」、「右側が Perl」です。

このデフォルト スタックに含まれる正確なレイヤーは、多くのことに依存します。
システム、Perl バージョン、Perl コンパイル時構成、および Perl ランタイム構成。
詳細については、PerlIO、perlrun の「PERLIO」、および open を参照してください。

binmode() と同様に動作します 開いた(): デフォルトでは、指定されたレイヤーが一番上にプッシュされます
既存のスタックの。

ただし、指定されたレイヤーが「上にプッシュ」されている場合でも、 開いた() および
binmode()、これは効果が「トップ」に限定されているという意味ではありません: PerlIO レイヤーは
非常に「アクティブ」になり、スタックのより深いレイヤーも検査して影響を与えます。 例として
最初に到達するまでレイヤーを繰り返し「ポップ」する「生」と呼ばれるレイヤーがあります
バイナリ データを処理できると宣言したレイヤー。 「プッシュされた」レイヤーは
左から右の順に処理されます。

sysopen() よりもスタック内の下位レベルで (当然のことながら) 動作します。 開いた()。 のために
Unix または Unix ライクなシステムでの例 sysopen() ファイルのレベルで直接動作します
記述子: PerlIO レイヤーに関しては、"unix" レイヤーのみを使用します。
Unix ファイル記述子の上のかなり薄いラッパー。

vs 分野
用語を使用した IO ストリームの動作を変更する機能に関する最初の説明
追加されたエンティティの「規律」。 これは(私が信じている)の使用から来ました
「sfio」の用語であり、Unix 端末の「ライン分野」から借用したものです。
ただし、このドキュメント (および C コード) では、「レイヤー」という用語を使用しています。

これは、実装を考えると自然な用語であり、暗示を避ける必要があります。
かなり異なるものに対する「規律」の以前の使用に固有のものです。

Rescale データ 構造
基本的なデータ構造は PerlIOl です:

typedef struct _PerlIO PerlIOl;
typedef struct _PerlIO_funcs PerlIO_funcs;
typedef PerlIOl *PerlIO;

構造体 _PerlIO
{
PerlIOl * 次; /* 下層 */
PerlIO_funcs * タブ; /* このレイヤーの関数 */
U32 フラグ; /* 状態のさまざまなフラグ */
};

"PerlIOl *" は構造体へのポインターであり、 レベル "PerlIO *" は
"PerlIOl *" へのポインター - つまり、構造体へのポインターへのポインター。 これにより、
アプリケーションレベル "PerlIO *" は一定のままで、実際の "PerlIOl *" はその下にあります
変化します。 (「sv_any」フィールドが
スカラーの型が変更されます。) IO ストリームは、一般に、へのポインターとして表されます。
この「レイヤー」のリンクリスト。

"PerlIO *" の二重の間接指定のため、
「&(perlio->next)」「は」「PerlIO *」なので、ある程度、少なくとも XNUMX つのレイヤーで
次のレイヤーの「標準」API。

「レイヤー」は次の XNUMX つの部分で構成されます。

1.「レイヤークラス」の機能と属性。

2. 特定のハンドルのインスタンスごとのデータ。

機能 および Attributes
関数と属性は、"PerlIOl" の "tab" (テーブル) メンバーを介してアクセスされます。
関数 (レイヤー「クラス」のメソッド) は固定されており、
「PerlIO_funcs」タイプ。 これらは、パブリックな "PerlIO_" 関数とほぼ同じです:

構造体 _PerlIO_funcs
{
サイズ_t fsize;
文字 * 名前;
Size_t サイズ;
IV種;
IV (*プッシュ)(pTHX_ PerlIO *f,const char *mode,SV *arg, PerlIO_funcs *tab);
IV (*ポップ)(pTHX_ PerlIO *f);
PerlIO * (*開く)(pTHX_ PerlIO_funcs *tab,
PerlIO_list_t *レイヤー、IV n、
const char *モード、
int fd、int imode、int perm、
PerlIO *古い、
int narg、SV **args);
IV (*Binmode)(pTHX_ PerlIO *f);
SV * (*Getarg)(pTHX_ PerlIO *f、CLONE_PARAMS *param、int フラグ)
IV (*ファイル番号)(pTHX_ PerlIO *f);
PerlIO * (*Dup)(pTHX_ PerlIO *f、PerlIO *o、CLONE_PARAMS *param、int フラグ)
/* Unix ライクな関数 - SFIO ライン分野を参照 */
SSize_t (*Read)(pTHX_ PerlIO *f, void *vbuf, Size_t カウント);
SSize_t (*未読)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
SSize_t (*Write)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
IV (*Seek)(pTHX_ PerlIO *f, Off_t オフセット, int whence);
Off_t (*Tell)(pTHX_ PerlIO *f);
IV (*閉じる)(pTHX_ PerlIO *f);
/* Stdio のようなバッファリングされた IO 関数 */
IV (*フラッシュ)(pTHX_ PerlIO *f);
IV (*Fill)(pTHX_ PerlIO *f);
IV (*Eof)(pTHX_ PerlIO *f);
IV (*エラー)(pTHX_ PerlIO *f);
void (*Clearerr)(pTHX_PerlIO *f);
void (*Setlinebuf)(pTHX_PerlIO *f);
/* Perl のスヌーピング関数 */
STDCHAR * (*Get_base)(pTHX_ PerlIO *f);
Size_t (*Get_bufsiz)(pTHX_ PerlIO *f);
STDCHAR * (*Get_ptr)(pTHX_ PerlIO *f);
SSize_t (*Get_cnt)(pTHX_ PerlIO *f);
void (*Set_ptrcnt)(pTHX_ PerlIO *f,STDCHAR *ptr,SSize_t cnt);
};

構造体の最初のいくつかのメンバーは、互換性チェックのために関数テーブルのサイズを指定します
レイヤーの「name」、インスタンスごとのデータの「malloc」へのサイズ、およびいくつかのフラグ
クラス全体の属性 (バッファリング層であるかどうかなど)、
次の XNUMX つの基本グループに分類される機能に従ってください。

1. オープニングとセットアップ機能

2. 基本的な IO 操作

3. Stdio クラスのバッファリング オプション。

4. バッファーへの Perl の伝統的な「高速」アクセスをサポートする関数。

レイヤーはすべての関数を実装する必要はありませんが、テーブル全体が実装されている必要があります。
現在。 未実装のスロットは NULL (呼び出されたときにエラーになります) または
「基本クラス」から動作を「継承」するためにスタブを入力できます。 この「継承」
レイヤーのすべてのインスタンスに対して固定されていますが、レイヤーが入力するスタブを選択するため、
テーブルでは、限定的な「多重継承」が可能です。

インスタンスごと Rescale データ
インスタンスごとのデータは、基本的な PerlIOl 構造体を超えてメモリに保持されます。
したがって、レイヤーの構造体の最初のメンバーである PerlIOl は次のようになります。

typedef構造体
{
struct _PerlIO ベース; /* 基本「クラス」情報 */
STDCHAR * buf; /* バッファの開始 */
STDCHAR * 終わり; /* バッファの有効部分の終わり */
STDCHAR * ptr; /* バッファ内の現在位置 */
Off_t posn; /* buf のファイルへのオフセット */
Size_t bufsiz; /* バッファの実サイズ */
IV 一言; /* 緊急バッファ */
PerlIOBuf;

このようにして (perl のスカラーと同様に) PerlIOBuf へのポインターをポインターとして扱うことができます。
PerlIOl に。

in をご利用ください。
テーブルパーリオUNIX
| |
+----------+ +----------+ +--------+
PerlIO ->| |--->| 次 |--->| ヌル |
+----------+ +----------+ +--------+
| | | | | | バッファー | | | fd |
+---------+ | | | +--------+
| | | | +---------+

上記は、単純なケースでレイヤースキームがどのように機能するかを示しています。 アプリケーションの
"PerlIO *" は、開いている (割り当てられた) ハンドルを表すテーブル内のエントリを指します。 為に
たとえば、テーブルの最初の XNUMX つのスロットは、「stdin」、「stdout」、および「stderr」に対応します。
テーブルは、ハンドルの現在の「トップ」レイヤーを指します。この場合、
汎用バッファリング層「perlio」のインスタンス。 そのレイヤーは次のレイヤーを指します
下層 - この場合、低レベルの「unix」層。

上記は、「stdio」のバッファリングされたストリームとほぼ同等ですが、さらに多くの機能があります
柔軟性:

· Unix レベルの "read"/"write"/"lseek" が (たとえば) ソケットに適していない場合、
「unix」レ​​イヤーは、「ソケット」レイヤーで(オープン時または動的に)置き換えることができます。

· 異なるハンドルは、異なるバッファリング スキームを持つことができます。 「トップ」レイヤーは
ディスクファイルの読み取りが「読み取り」よりも「mmap」を使用したほうが速い場合は「mmap」レイヤー。 アン
「バッファリングされていない」ストリームは、バッファ層を持たないことで簡単に実装できます。

· 余分なレイヤーを挿入して、データが流れるときにデータを処理できます。 これは
perl 5.7.0+ にスキームを含める必要性を駆り立てる - 許可するメカニズムが必要でした
perl の内部エンコーディング (概念的には少なくとも Unicode) 間で変換されるデータ
UTF-8 として)、およびシステムで使用される「ネイティブ」形式。 これは、
":encoding(xxxx)" レイヤーは通常、バッファリング レイヤーの上にあります。

· "\n" を CRLF に変換するレイヤーを追加できます。 このレイヤーは、任意のレイヤーで使用できます
プラットフォーム、通常そのようなことを行うものだけではありません。

インスタンスごと フラグ ビット
汎用フラグ ビットは、モード文字列から推定される "O_XXXXX" スタイル フラグのハイブリッドです。
"PerlIO_open()" に渡され、典型的なバッファ層の状態ビット。

PERLIO_F_EOF
ファイルの終わり。

PERLIO_F_CANWRITE
書き込みが許可されます。つまり、「w」、「r+」、「a」などとして開かれます。

PERLIO_F_CANREAD
読み取りは許可されます。つまり、"r" または "w+" (または "a+" - ick) が開かれます。

PERLIO_F_ERROR
エラーが発生しました ("PerlIO_error()" の場合)。

PERLIO_F_TRUNCATE
オープン モードで提案されたファイルを切り捨てます。

PERLIO_F_APPEND
すべての書き込みは追加する必要があります。

PERLIO_F_CRLF
レイヤーは、出力用に CR,LF にマッピングされ、CR,LF にマッピングされた Win32 のような "\n" を実行しています。
入力の場合は「\n」。 通常、提供された「crlf」レイヤーは、面倒な必要がある唯一のレイヤーです
これについて。 "PerlIO_binmode()" は、レイヤーを追加/削除するのではなく、このフラグを台無しにします
レイヤークラスに「PERLIO_K_CANCRLF」ビットが設定されている場合。

PERLIO_F_UTF8
このレイヤーに書き込まれるデータは、UTF-8 でエンコードされている必要があります。 この層によって提供されるデータは
UTF-8 エンコードと見なされます。 ":utf8" ダミーレイヤーで任意のレイヤーに設定可能。 こちらもセット
":encoding" 層。

PERLIO_F_UNBUF
レイヤーはバッファリングされていません。つまり、書き込みごとに次のレイヤーへの書き込みが発生する必要があります。
このレイヤー。

PERLIO_F_WRBUF
このレイヤーのバッファーは現在、書き込まれたデータを保持していますが、次のレイヤーには送信されていません
層。

PERLIO_F_RDBUF
このレイヤーのバッファーには、現在、下のレイヤーから読み取られた未使用のデータが保持されています。

PERLIO_F_LINEBUF
レイヤーは行バッファーされます。 書き込みデータは、「\n」
見られます。 「\n」を超えるデータはすべて処理する必要があります。

PERLIO_F_TEMP
ファイルは「unlink()」されているか、「close()」で削除する必要があります。

PERLIO_F_OPEN
ハンドルが開いています。

PERLIO_F_FASTGETS
この層のこのインスタンスは、「高速「取得」」インターフェースをサポートします。 通常設定ベース
クラスの「PERLIO_K_FASTGETS」で、および関数の存在によって
テーブル。 ただし、通常そのインターフェイスを提供するクラスは、それを回避する必要がある場合があります。
特定のインスタンス。 「保留」レイヤーは、レイヤーの上にプッシュされたときにこれを行う必要があります。
インターフェイスをサポートしていないレイヤー。 (Perl の "sv_gets()" は、
XNUMX 回の「取得」中に変更される高速な「取得」動作をストリーミングします。)

メソッド in Detail
サイズ
サイズ_t fsize;

関数テーブルのサイズ。 これは、PerlIO コードが「知っている」値と比較されます。
互換性チェック。 将来のバージョン かもしれません に対してコンパイルされたレイヤーを許容できる
古いバージョンのヘッダー。


文字 * 名前;

そのレイヤーの名前 開いた() Perl が呼び出すべきメソッド 開いた()。 例えば
層が APR と呼ばれる場合、次のように呼び出します。

open $fh, ">:APR", ...

Perl は、それが呼び出さなければならないことを知っています。 PerlIOAPR_open() によって実装されたメソッド
APRレイヤー。

サイズ
Size_t サイズ;

インスタンスごとのデータ構造のサイズ。例:

サイズ(PerlIOAPR)

このフィールドがゼロの場合、"PerlIO_pushed" は何も malloc せず、
レイヤーの Pushed 関数は、必要なレイヤースタック操作を行います - 回避するために使用されます
ダミー層の malloc/free オーバーヘッド。 フィールドがゼロ以外の場合、少なくとも
「PerlIOl」、「PerlIO_pushed」のサイズは、レイヤーのデータにメモリを割り当てます
構造を作成し、新しいレイヤーをストリームのスタックにリンクします。 (レイヤーの Pushed メソッドが
レイヤーが再びポップされたことを示すエラーを返します。)

種類
IV種;

· PERLIO_K_BUFFERED

レイヤーはバッファリングされます。

· PERLIO_K_RAW

レイヤーは、binmode(FH) スタックに含めることができます。つまり、そうではありません (または
通過するバイトを変換しないように設定します。

· PERLIO_K_CANCRLF

レイヤーは、"\n" と CRLF 行末の間で変換できます。

· PERLIO_K_FASTGETS

レイヤーはバッファ スヌーピングを許可します。

· PERLIO_K_MULTIARG

レイヤーの 開いた() 通常よりも多くの引数を受け入れます。 余分な
引数は、「MODE」引数の前に来てはなりません。 このフラグを使用すると、
引数を検証するレイヤーまで。

プッシュ
IV (*プッシュ)(pTHX_ PerlIO *f,const char *mode, SV *arg);

絶対に必須の唯一の方法。 レイヤーがスタックにプッシュされたときに呼び出されます。
これがオープン後に発生する場合、「モード」引数は NULL である可能性があります。 「arg」は非「NULL」になります
引数文字列が渡された場合。 ほとんどの場合、これは "PerlIOBase_pushed()" を呼び出すべきです
「モード」を適切な「PERLIO_F_XXXXX」フラグに変換します。
レイヤー自体が実行するアクション。 レイヤーが引数を期待していない場合は、必要です
渡されたものを保存することも、「Getarg()」を提供することもありません (おそらく
引数が予期しないものだったことを「Perl_warn」します)。

成功すると 0 を返します。 失敗すると -1 が返され、errno を設定する必要があります。

ポップ
IV (*ポップ)(pTHX_ PerlIO *f);

レイヤーがスタックからポップされるときに呼び出されます。 通常、レイヤーは次の後にポップされます
「Close()」が呼び出されます。 ただし、プログラムが次の場合、レイヤーを閉じずにポップできます
ストリーム上のレイヤーを動的に管理します。 そのような場合、「Popped()」はすべてを解放する必要があります
レイヤーの構造体に直接保持されていないリソース (バッファー、変換テーブルなど)。
また、サーバーから読み取られてバッファリングされた未使用のデータを「Unread()」する必要があります。
その下のレイヤーをそのレイヤーに戻して、今までのものに再提供できるようにします
上記。

成功と失敗で 0 を返します。 "Popped()" が返された場合 true その後 ペルリオ.c と仮定する
レイヤー自体がポップしたか、レイヤーが非常に特殊であり、
その他の理由で保持されます。 ほとんどの場合、元に戻るはずです false.

Open
PerlIO * (*開く)(...);

"Open()" メソッドは、perl の関数を組み合わせているため、多くの引数があります。
「open」、「PerlIO_open」、perl の「sysopen」、「PerlIO_fdopen」、および「PerlIO_reopen」。 の
完全なプロトタイプは次のとおりです。

PerlIO * (*開く)(pTHX_ PerlIO_funcs *tab,
PerlIO_list_t *レイヤー、IV n、
const char *モード、
int fd、int imode、int perm、
PerlIO *古い、
int narg、SV **args);

Open は (おそらく間接的に) "PerlIO_allocate()" を呼び出して、
テーブルを呼び出して、開いているファイルのレイヤー情報に関連付けます。
「PerlIO_push」。 の 「PerlIO *」に向けられたすべてのレイヤーの配列です。
それらに渡された引数、 n レイヤーのその配列へのインデックスです
呼ばれた。 マクロ "PerlIOArg" は、引数に対して (おそらく "NULL") SV * を返します。
レイヤーに渡されます。

この モード string は、正規表現に一致する ""fopen()" のような" 文字列です。
"/^[I#]?[rwa]\+?[bt]?$/".

「I」プレフィックスは、特別な方法で「stdin」..「stderr」を作成するときに使用されます
"PerlIO_fdopen" 呼び出し; 「#」プレフィックスは、これが「sysopen」であることを意味し、 iモード および
パーマ "PerlLIO_open3" に渡す必要があります。 「r」の意味 read、「w」は意味します w儀式と「a」
手段 a追加します。 「+」サフィックスは、読み取りと書き込み/追加の両方が行われることを意味します。
許可されました。 接尾辞「b」はファイルがバイナリであることを意味し、「t」はテキストであることを意味します。
(ほとんどすべてのレイヤーは、バイナリ モードで IO を実行し、b/t ビットを無視する必要があります。
":crlf" レイヤーをプッシュして区別を処理する必要があります。)

If 古い が「NULL」でない場合、これは「PerlIO_reopen」です。 Perl 自体はこれを使用しません。
(まだ?)セマンティクスは少しあいまいです。

If fd 負でない場合は、数値のファイル記述子です fdで開かれます
提供されたモード文字列と互換性のある方法で、呼び出しは次と同等です
「PerlIO_fdopen」。 この場合 ナルグス ゼロになります。

If ナルグス ゼロより大きい場合、「open」に渡される引数の数を示します。
それ以外の場合、たとえば "PerlIO_open" が呼び出された場合は 1 になります。 単純な場合
SvPV_nolen(*args) は開くパス名です。

レイヤーが「Open()」を提供する場合、通常は次のレイヤーの「Open()」メソッドを呼び出す必要があります
ダウン (もしあれば) し、それが成功した場合は自分自身を上にプッシュします。 「PerlIOBase_open」は
正確にそれを行うために提供されているため、ほとんどの場合、独自に記述する必要はありません
「Open()」メソッド。 このメソッドが定義されていない場合、他のレイヤーで問題が発生する可能性があります
開いている間に自分自身をその上に押し込みます。

"PerlIO_push" が実行され、open が失敗した場合は、"PerlIO_pop" 自体を実行する必要があります。
そうでない場合、レイヤーは削除されず、問題が発生する可能性があります。

失敗した場合は「NULL」を返します。

ビンモード
IV (*Binmode)(pTHX_ PerlIO *f);

オプション。 ":raw" レイヤーがプッシュされたときに使用されます (明示的に、または binmode(FH) の結果として)。
存在しない場合、レイヤーがポップされます。 存在する場合は、レイヤーをバイナリとして構成する必要があります (または
エラー "binmode" で -0 が返された場合、レイヤーで失敗します。
まだスタックにあります。

ゲタルグ
SV * (*Getarg)(pTHX_PerlIO *f,
CLONE_PARAMS *param、int フラグ);

オプション。 存在する場合は、渡された文字列引数を表す SV * を返す必要があります
プッシュされたときのレイヤー。 例: ":encoding(ascii)" は、値を持つ SvPV を返します。
「アスキー」。 (パラメータ および フラグ ほとんどの場合、引数は無視できます)

「Dup」は「Getarg」を使用して、「Pushed」に最初に渡された引数を取得するため、
レイヤーに「Pushed」への追加の引数があり、
「Dup」されることはありません。

フィレノ
IV (*ファイル番号)(pTHX_ PerlIO *f);

ハンドルの Unix/Posix 数値ファイル記述子を返します。 通常は
"PerlIOBase_fileno()" (次のレイヤーを下に要求するだけ) で十分です。

エラーの場合は -1 を返します。これには、レイヤーが実行できない場合も含まれると見なされます。
そのようなファイル記述子を提供します。

DUP
PerlIO * (*Dup)(pTHX_ PerlIO *f, PerlIO *o,
CLONE_PARAMS *param、int フラグ);

XXX: さらにドキュメントが必要です。

スレッドが生成されるときに「クローン」プロセスの一部として使用されます (この場合、param は
非 NULL である必要があります)、および「open」で「&」を介してストリームが複製されている場合。

"Open" と同様に、成功すると PerlIO* を返し、失敗すると "NULL" を返します。

読む
SSize_t (*Read)(pTHX_ PerlIO *f, void *vbuf, Size_t カウント);

基本的な読み取り操作。

通常、「Fill」を呼び出してポインターを操作します (おそらく API を介して)。
「PerlIOBuf_read()」は、「高速取得」を提供する派生クラスに適している場合があります
方法。

実際に読み取ったバイト数を返すか、エラーの場合は -1 を返します。

未読
SSize_t (*未読)(pTHX_ PerlIO *f,
const void *vbuf, Size_t count);

stdio の「ungetc()」のスーパーセット。 バイトを確認するために将来の読み取りを手配する必要があります
「vbuf」。 明らかに優れた実装がない場合は、「PerlIOBase_unread()」
呼び出しレイヤーの上に「偽の」「保留」レイヤーをプッシュすることにより、機能を提供します。

未読文字数を返します。

書きます
SSize_t (*Write)(PerlIO *f, const void *vbuf, Size_t カウント);

基本的な書き込み操作。

書き込まれたバイトを返します。エラーの場合は -1 を返します。

Seek
IV (*Seek)(pTHX_ PerlIO *f, Off_t オフセット, int whence);

ファイル ポインタを配置します。 通常、独自の「フラッシュ」メソッドを呼び出してから、
下の次のレイヤーの「Seek」メソッド。

成功すると 0 を返し、失敗すると -1 を返します。

言う
Off_t (*Tell)(pTHX_ PerlIO *f);

ファイルポインタを返します。 避けるべき位置のレイヤーのキャッシュされた概念に基づく場合があります
オーバーヘッド。

ファイル ポインタの取得に失敗した場合は -1 を返します。

閉じる
IV (*閉じる)(pTHX_ PerlIO *f);

ストリームを閉じます。 通常は "PerlIOBase_close()" を呼び出して自分自身をフラッシュして閉じる必要があります
下のレイヤーを削除し、データ構造 (バッファー、変換テーブル、
...) データ構造に直接保持されません。

成功すると 0 を返し、失敗すると -1 を返します。

フラッシュ
IV (*フラッシュ)(pTHX_ PerlIO *f);

ストリームの状態を下のレイヤーと一致させる必要があります。 つまり、バッファリングされた書き込み
データが書き込まれ、データが読み取られるように下層のファイル位置が調整されます
以下ですが、実際には消費されません。 (おそらく、そのようなデータを下位に「Unread()」する必要があります
層。)

成功すると 0 を返し、失敗すると -1 を返します。

埋める
IV (*Fill)(pTHX_ PerlIO *f);

このレイヤーのバッファーは、下のレイヤーから (読み取り用に) 満たす必要があります。 あなたが
「サブクラス」PerlIOBuf レイヤーで、そのレイヤーを使用したい _read メソッドと独自の供給
PerlIOBuf のバッファを埋める fill メソッド。

成功すると 0 を返し、失敗すると -1 を返します。

イオフ
IV (*Eof)(pTHX_ PerlIO *f);

ファイル終了インジケータを返します。 通常は "PerlIOBase_eof()" で十分です。

ファイルの終わりの場合は 0、ファイルの終わりでない場合は 1、エラーの場合は -1 を返します。

エラー
IV (*エラー)(pTHX_ PerlIO *f);

エラーインジケータを返します。 通常は "PerlIOBase_error()" で十分です。

エラーがある場合 (通常は "PERLIO_F_ERROR" が設定されている場合) は 1 を返し、それ以外の場合は 0 を返します。

クリアラー
void (*Clearerr)(pTHX_PerlIO *f);

ファイルの終わりとエラー インジケーターをクリアします。 を設定するには "PerlIOBase_clearerr()" を呼び出す必要があります。
「PERLIO_F_XXXXX」フラグで十分です。

セットラインブフ
void (*Setlinebuf)(pTHX_PerlIO *f);

ストリームを行バッファーとしてマークします。 "PerlIOBase_setlinebuf()" は PERLIO_F_LINEBUF を設定します
フラグであり、通常は十分です。

Get_base
STDCHAR * (*Get_base)(pTHX_ PerlIO *f);

このレイヤーに読み取りバッファーを割り当て (まだ割り当てていない場合)、ポインターを返します。
それ。 失敗した場合は NULL を返します。

Get_bufsiz
Size_t (*Get_bufsiz)(pTHX_ PerlIO *f);

最後の "Fill()" がバッファーに入れられたバイト数を返します。

Get_ptr
STDCHAR * (*Get_ptr)(pTHX_ PerlIO *f);

このレイヤーのバッファーに相対的な現在の読み取りポインターを返します。

Get_cnt
SSize_t (*Get_cnt)(pTHX_ PerlIO *f);

現在のバッファでまだ読み取られていないバイト数を返します。

Set_ptrcnt
void (*Set_ptrcnt)(pTHX_PerlIO *f,
STDCHAR *ptr、SSize_t cnt);

「ptr」および/または「cnt」に一致するように、読み取りポインターとバイト数を調整します。 の
アプリケーション (または上のレイヤー) は、それらが一貫していることを確認する必要があります。 (チェックは許可されています
パラノイア。)

ユーティリティ
次のレイヤーを要求するには、PerlIONext(PerlIO *f) を使用します。

PerlIO* が有効であることを確認するには、PerlIOValid(PerlIO *f) を使用します。 (これが行うことはすべて、実際には
ポインターが非 NULL であり、その後ろのポインターが非 NULL であることを確認するだけです。)

PerlIOBase(PerlIO *f) は「ベース」ポインタ、つまり「PerlIOl*」を返します。
ポインター。

PerlIOSelf(PerlIO* f, type) は、型にキャストされた PerlIOBase を返します。

Perl_PerlIO_or_Base(PerlIO* f, callback, base, failure, args) は、 折り返し電話
レイヤーの機能から f (「読み取り」などのIO関数の名前のみ)
  引数、またはそのようなコールバックがない場合は、 ベース を使用したコールバックのバージョン
同じ引数、または f が無効な場合は、errno を EBADF に設定して戻ります 失敗.

Perl_PerlIO_or_fail(PerlIO* f, callback, failure, args) は、 折り返し電話
層の機能 f 引数、またはそのようなコールバックがない場合は、errno をに設定します。
EINVAL。 または、f が無効な場合は、errno を EBADF に設定して戻ります 失敗.

Perl_PerlIO_or_Base_void(PerlIO* f, callback, base, args) は、 折り返し電話
層の機能 f 引数、またはそのようなコールバックがない場合は、 ベース
同じ引数を持つコールバックのバージョン、または f が無効な場合は、errno を EBADF に設定します。

Perl_PerlIO_or_fail_void(PerlIO* f, callback, args) は、 折り返し電話
層の機能 f 引数、またはそのようなコールバックがない場合は、errno をに設定します。
EINVAL。 または、f が無効な場合は、errno を EBADF に設定します。

実装 PerlIO
実装ドキュメントが不明確または不十分であると思われる場合は、既存のドキュメントを参照してください。
以下を含む PerlIO 層の実装:

· C 実装

この ペルリオ.c および ペルリオール.h Perl コアでは、「unix」、「perlio」、「stdio」、
「crlf」、「utf8」、「byte」、「raw」、「pending」レイヤー、および「mmap」と「win32」
該当する場合はレイヤー。 (「win32」は現在未完成で未使用です。
Win32 で代わりに使用されます。PerlIO の「ファイルハンドルのレイヤーのクエリ」を参照してください。)

Perl コアの PerlIO::encoding、PerlIO::scalar、PerlIO::via。

CPAN 上の PerlIO::gzip および APR::PerlIO (mod_perl 2.0)。

· Perl の実装

Perl コアの PerlIO::via::QuotedPrint と CPAN の PerlIO::via::*。

PerlIO レイヤーを作成している場合は、怠惰になりたい場合があります。つまり、次のように実装します。
興味のある方法のみ。 他の方法は、
「空白」メソッド

PerlIOBase_noop_ok
PerlIOBase_noop_fail

(何もせず、それぞれゼロと -1 を返します) または特定のメソッドについては、
NULL メソッドを使用してデフォルトの動作を仮定します。 Open メソッドは、
「親」レイヤー。 次の表は、動作をまとめたものです。

NULL でのメソッドの動作

クリアエラー PerlIOBase_clearerr
PerlIOBase_close を閉じる
PerlIOBase_dup の複製
Eof PerlIOBase_eof
エラー PerlIOBase_error
ファイル番号 PerlIOBase_fileno
失敗を埋める
フラッシュ成功
Getarg成功
Get_base の失敗
Get_bufsiz の失敗
Get_cnt の失敗
Get_ptr の失敗
継承を開く
ポップ成功
プッシュ成功
PerlIOBase_read を読む
失敗を求める
Set_cnt の失敗
Set_ptrcnt の失敗
Setlinebuf PerlIOBase_setlinebuf
失敗を知らせる
未読 PerlIOBase_unread
書き込み失敗

FAILURE errno を (Unixish では EINVAL に、VMS では LIB$_INVARG に) 設定し、
return -1 (数値の戻り値の場合) または NULL (ポインターの場合)
INHERITED 下層から継承
SUCCESS 戻り値 0 (数値の戻り値の場合) またはポインター

基本
ファイル「perlio.c」は、次のレイヤーを提供します。

「ユニックス」
Unix/POSIX "read()"、"write()"、"lseek()"、
"近い()"。 バッファリングなし。 O_TEXT と O_TEXT を区別するプラットフォームでも
O_BINARY このレイヤーは常に O_BINARY です。

「ペルリオ」
PerlIO API 全体を提供する非常に完全な汎用バッファリング レイヤー。 それは
また、他のレイヤーの「基本クラス」として使用することも意図しています。 (たとえば、その「Read()」
メソッドは、"Get_cnt()"/"Get_ptr()"/"Set_ptrcnt()" メソッドの観点から実装されています)。

"unix" 上の "perlio" は、PerlIO API で見られる stdio の完全な置き換えを提供します。
これは、システムの標準入出力が perl の「高速」を許可しない場合の USE_PERLIO のデフォルトです。
gets」アクセスであり、「O_TEXT」と「O_BINARY」を区別しません。

「標準」
レイヤー スキームを介して PerlIO API を提供するレイヤーですが、
システムの stdio を呼び出します。 システムの stdio が提供する場合、これは (現在) デフォルトです。
perl の「高速取得」アクセスを許可するのに十分なアクセス権と、それらを区別しないアクセス権
「O_TEXT」と「O_BINARY」の間。

"crlf"
「perlio」を基底クラスとして派生させたレイヤー。 CR、LFにWin32ライクな「\n」を提供
翻訳。 「perlio」の上に適用するか、バッファ層自体として機能させることができます。
システムが「O_TEXT」と「O_TEXT」を区別する場合、「unix」ではなく「crlf」がデフォルトです。
「O_BINARY」が開きます。 (ある時点で、「unix」は「ネイティブ」Win32 IO レイヤーに置き換えられます。
そのプラットフォームでは、Win32 の読み取り/書き込みレイヤーにはさまざまな欠点があるためです。)「crlf」レイヤー
何らかの方法でデータを変換するレイヤーの合理的なモデルです。

"mmap"
Configure が "mmap()" 関数を検出した場合、このレイヤーが提供されます ("perlio" を
「ベース」) によって「読み取り」操作を行います mmap()ファイルを実行します。 パフォーマンス向上は
最新のシステムでは限界に達しているため、主に概念実証として存在します。 それは可能性があります
ある時点でコアから切り離されます。 「mmap」レイヤーは合理的なモデルです
ミニマリストの「派生」レイヤー用。

"保留中"
提供するために使用できる「perlio」の「内部」派生物 未読() function
バッファがない、または気にならないレイヤーの場合。 (基本的にこのレイヤーの
「Fill()」は自身をスタックからポップするため、下のレイヤーから読み取りを再開します。)

"生"
レイヤー スタック上に決して存在しないダミー レイヤー。 代わりに、実際に「プッシュ」したとき
スタックをポップして自分自身を削除し、すべてのオブジェクトで Binmode 関数テーブル エントリを呼び出します。
スタック内のレイヤー - 通常、これは (PerlIOBase_binmode 経由で) レイヤーを削除します。
「PERLIO_K_RAW」ビットが設定されていません。 レイヤーは、それらを定義することでその動作を変更できます
独自の Binmode エントリ。

「utf8」
別のダミーレイヤー。 プッシュされると、それ自体がポップされ、「PERLIO_F_UTF8」フラグが設定されます
スタックの一番上にあった (そして今はもう一度) レイヤー。

加えて ペルリオ.c また、いくつかの "PerlIOBase_xxxx()" 関数を提供します。
特別なことをする必要のないクラスのテーブルスロットで使用することを意図しています
特定の方法のために。

拡張
レイヤは、拡張モジュールによって利用可能になります。 未知の層に遭遇したとき
PerlIO コードは以下と同等の処理を行います:

PerlIO '層' を使用します。

場所 未知のレイヤーです。 PerlIO.pm 次に、次のことを試みます。

PerlIO::レイヤーが必要です。

そのプロセスの後、レイヤーがまだ定義されていない場合、「開く」は失敗します。

次の拡張レイヤーが perl にバンドルされています。

":エンコーディング"
エンコーディングを使用します。

このレイヤーを使用可能にしますが、 PerlIO.pm それを見つける場所を「知っている」。 それは
このように呼び出される引数を取るレイヤーの例:

open( $fh, "<:encoding(iso-8859-7)", $pathname );

":スカラー"
スカラーからのデータの読み取りとスカラーへのデータの書き込みをサポートします。

open( $fh, "+<:scalar", \$scalar );

ハンドルが開かれると、次の文字列値から get バイトを読み取ります。 $スカラー,
値を変更します。 どちらの場合も、 $スカラー ゼロから開始しますが、可能です
「シーク」によって変更され、「テル」によって決定されます。

このレイヤーは、呼び出し時に暗示されることに注意してください 開いた() したがって:

open( $fh, "+<", \$scalar );

":経由"
レイヤーを Perl コードとして実装できるようにするために提供されます。 例えば:

PerlIO::via::StripHTML を使用します。
open( my $fh, "<:via(StripHTML)", "index.html" );

詳細については、PerlIO::via を参照してください。

すべて


このドキュメントを改善するために必要なこと。

・通らずに有効なfhの作り方を解説 開いた()(つまり、レイヤーを適用します)。 為に
たとえば、ファイルが perl で開かれていないが、そのような fh を取得したい場合
Perlによって開かれました。

PerlIO_apply_layera がどのように適合するか、そのドキュメントは公開されましたか?

現在、例は次のようになります。

PerlIO *foo_to_PerlIO(pTHX_ char *mode, ...)
{
char *モード; /* "w"、"r" など */
const char *layers = ":APR"; /* レイヤー名 */
PerlIO *f = PerlIO_allocate(aTHX);
もし (!f) {
NULLを返します。
}

PerlIO_apply_layers(aTHX_ f, モード, レイヤー);

もし (f) {
PerlIOAPR *st = PerlIOSelf(f, PerlIOAPR);
/* _open() のように st 構造体を埋めます */
st->file = ファイル;
PerlIOBase(f)->フラグ |= PERLIO_F_OPEN;

f を返します。
}
NULLを返します。
}

· XXX でマークされた場所のドキュメントを修正/追加します。

・レイヤーによるエラー処理は規定しない。 たとえば、$! 設定する必要があります
明示的に、エラー処理を最上位レイヤーに委譲する必要がある場合。

使い方のヒントになるかも セテルノ() またはそれらが見つかる場所へのポインタ。

・分かりやすいように具体例を挙げていただけると助かります。
API。 もちろん、API が簡潔でなければならないことに同意しますが、
ガイドのような XNUMX 番目のドキュメントは、より簡単に開始できると思います
APIであるドキュメントを使用しますが、物事が行われている場所に例があります
PerlIO の第一人者ではない (まだ) 人にとっては不明です。

onworks.net サービスを使用してオンラインで perliol を使用する


無料のサーバーとワークステーション

Windows と Linux のアプリをダウンロード

Linuxコマンド

Ad