英语法语西班牙文

OnWorks 网站图标

perliol - 云端在线

通过 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器在 OnWorks 免费托管服务提供商中运行 perliol

这是可以在 OnWorks 免费托管服务提供商中使用我们的多个免费在线工作站之一运行的命令 perliol,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器

程序:

您的姓名


perliol - Perl 在层中实现 IO 的 C API。

概要


/* 定义一个层... */
#包括

商品描述


本文档描述了 PerlIO 抽象的行为和实现
当定义“USE_PERLIO”时,在 perlapio 中描述。

发展历程 背景
PerlIO 抽象是在 perl5.003_02 中引入的,但仅仅作为一个
抽象直到 perl5.7.0。 然而,在那段时间里,许多 perl 扩展切换了
使用它,因此 API 主要是固定的以保持(源)兼容性。

实现的目的是在一个灵活的平台上提供 PerlIO API
中立的方式。 这也是对“面向对象的 C,带有 vtables”方法的尝试
可以应用于 Perl 6。

基本版 结构
PerlIO 是一堆层。

堆栈的低级别与低级别操作系统调用(文件
C中的描述符)进出字节,堆栈缓冲区的较高层,过滤器,
并以其他方式操作 I/O,并将字符(或字节)返回给 Perl。 条款 以上
如下。 用于指代堆叠层的相对定位。

一层包含一个“vtable”,即I/O操作表(在C级是一个函数表
指针)和状态标志。 vtable 中的函数实现了如下操作
“打开”、“读取”和“写入”。

当请求 I/O(例如“读取”)时,请求首先从 Perl
堆栈使用每一层的“读取”函数,然后在底部请求输入
操作系统服务,然后结果向上返回堆栈,最后被
解释为 Perl 数据。

请求不一定总是一直到操作系统:那就是
PerlIO 缓冲发挥作用的地方。

当你做一个 打开() 并指定要部署的额外 PerlIO 层
指定被“推送”在已经存在的默认堆栈的顶部。 一种查看方式是
“操作系统在左边”和“Perl在右边”。

这个默认堆栈中的确切层取决于很多事情:您的操作
系统、Perl 版本、Perl 编译时配置和 Perl 运行时配置。
请参阅 PerlIO,perlrun 中的“PERLIO”,并打开以获取更多信息。

二进制模式() 操作类似于 打开(): 默认情况下,指定的层被推到顶部
现有堆栈。

但是,请注意,即使指定的图层被“推到顶部” 打开()
二进制模式(),这并不意味着效果仅限于“顶部”:PerlIO 层可以
非常“活跃”并检查和影响堆栈中更深的层。 举个例子
有一个叫做“raw”的层,它反复“弹出”层直到它到达第一个
已声明自己能够处理二进制数据的层。 “推”层是
按从左到右的顺序处理。

系统打开() 操作(不出所料)在堆栈中比 打开()。 对于
Unix 或类 Unix 系统中的示例 系统打开() 直接在文件级别操作
描述符:就 PerlIO 层而言,它仅使用“unix”层,这是一个
在 Unix 文件描述符之上的相当薄的包装器。

vs 学科
修改 IO 流行为的能力的初步讨论使用了术语
添加的实体的“纪律”。 这来自(我相信)使用
“sfio”中的术语,后者又从 Unix 终端上的“线路规则”中借用了它。
但是,本文档(和 C 代码)使用术语“层”。

我希望这是一个考虑到实现的自然术语,应该避免内涵
这是早期使用“纪律”对相当不同的事物所固有的。

时间 结构
基本数据结构是一个 PerlIOl:

typedef struct _PerlIO PerlIOl;
typedef struct _PerlIO_funcs PerlIO_funcs;
类型定义 PerlIOl *PerlIO;

结构体_PerlIO
{
PerlIOl * 下一个; /* 下层 */
PerlIO_funcs * tab; /* 该层的函数 */
U32 标志; /* 各种状态标志 */
};

“PerlIOl *”是指向结构的指针,并且 应用的区域 “PerlIO *”级别是一个
指向“PerlIOl *”的指针——即指向结构指针的指针。 这允许
应用程序级别“PerlIO *”保持不变,而实际的“PerlIOl *”在下面
变化。 (比较 perl 的“SV *”,当它的“sv_any”字段更改为
标量的类型发生变化。)然后通常将 IO 流表示为指向
这个“层”的链表。

需要注意的是,由于“PerlIO *”中的双重间接性,一个
"&(perlio->next)" "是"一个"PerlIO *",所以在某种程度上至少有一层可以使用
下一层的“标准”API。

一个“层”由两部分组成:

1.“图层类”的功能和属性。

2. 特定句柄的每个实例数据。

功能 Attributes
函数和属性通过“PerlIOl”的“tab”(表)成员访问。
功能(层“类”的方法)是固定的,并由
“PerlIO_funcs”类型。 它们与公共的“PerlIO_”函数大致相同:

结构体_PerlIO_funcs
{
size_t fsize;
字符 * 名称;
size_t 大小;
四类;
IV (*Pushed)(pTHX_PerlIO *f,const char *mode,SV *arg, PerlIO_funcs *tab);
IV (*Popped)(pTHX_PerlIO *f);
PerlIO * (*打开)(pTHX_ PerlIO_funcs *选项卡,
PerlIO_list_t *层,IV n,
常量字符*模式,
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 flags)
IV (*Fileno)(pTHX_PerlIO *f);
PerlIO * (*Dup)(pTHX_ PerlIO *f、PerlIO *o、CLONE_PARAMS *param、int 标志)
/* 类 Unix 函数 - cf sfio 行规范 */
SSize_t (*Read)(pTHX_PerlIO *f, void *vbuf, Size_t count);
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 offset, int wherece);
Off_t (*Tell)(pTHX_PerlIO *f);
IV (*关闭)(pTHX_ PerlIO *f);
/* 类似 Stdio 的缓冲 IO 函数 */
IV (*Flush)(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);
};

struct 的前几个成员给出了一个函数表大小,用于兼容性检查
层的“名称”,每个实例数据的“malloc”大小,以及一些标志
哪些是类整体的属性(比如是否是缓冲层),然后
遵循分为四个基本组的功能:

1. 打开和设置功能

2. 基本IO操作

3. Stdio 类缓冲选项。

4. 支持 Perl 对缓冲区的传统“快速”访问的函数。

一个层不一定要实现所有的功能,但整个表必须
展示。 未实现的插槽可以为 NULL(调用时会导致错误)或
可以用存根填充以从“基类”“继承”行为。 这份“传承”
对于图层的所有实例都是固定的,但是随着图层选择要填充的存根
表中,有限的“多重继承”是可能的。

每个实例 时间
每个实例的数据都保存在基本 PerlIOl 结构之外的内存中,通过创建一个
PerlIOl 是层结构的第一个成员,因此:

typedef结构
{
struct _PerlIO 基础; /* 基础“类”信息 */
STDCHAR * buf; /* 缓冲区开始 */
STDCHAR * 结束; /* 缓冲区有效部分结束 */
STDCHAR * ptr; /* 当前缓冲区中的位置 */
Off_t posn; /* buf 到文件的偏移量 */
size_t bufsiz; /* 缓冲区的实际大小 */
IV oneword; /* 紧急缓冲 */
PerlIOBuf;

通过这种方式(对于 perl 的标量),指向 PerlIOBuf 的指针可以被视为一个指针
到 PerlIOl。

in 行动。
表 perlio unix
| |
+-----------+ +-----------+ +--------+
PerlIO ->| |--->| 下一个|--->| 空 |
+-----------+ +-----------+ +--------+
| | | 缓冲区 | | FD |
+------------+ | | +--------+
| | +-----------+

以上试图展示层方案如何在一个简单的情况下工作。 该应用程序的
“PerlIO *”指向表中表示打开(已分配)句柄的条目。 为了
例如,表中的前三个插槽对应于“stdin”、“stdout”和“stderr”。
该表又指向手柄的当前“顶层” - 在这种情况下是
通用缓冲层“perlio”的实例。 那一层又指向下一层
向下层 - 在这种情况下是低级“unix”层。

以上大致相当于“stdio”缓冲流,但还有更多
灵活性:

· 如果 Unix 级别的“读”/“写”/“lseek”不适合(比如说)套接字,那么
“unix”层可以用“socket”层替换(在打开时甚至动态)。

· 不同的句柄可以有不同的缓冲方案。 “顶层”可能是
“mmap”层,如果使用“mmap”读取磁盘文件比“read”更快。 一个
“无缓冲”流可以简单地通过没有缓冲层来实现。

· 可以插入额外的层来处理流经的数据。 这是
推动在 perl 5.7.0+ 中包含该方案的需求 - 我们需要一种机制来允许
要在 perl 的内部编码之间转换的数据(概念上至少是 Unicode
作为 UTF-8),以及系统使用的“本机”格式。 这是由
":encoding(xxxx)" 层,通常位于缓冲层之上。

· 可以添加一个对 CRLF 进行“\n”转换的层。 该层可用于任何
平台,而不仅仅是那些通常会做这些事情的平台。

每个实例
通用标志位是从模式字符串推导出的“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
层正在执行类似于 Win32 的“\n”映射到 CR,LF 用于输出和 CR,LF 映射到
"\n" 用于输入。 通常提供的“crlf”层是唯一需要麻烦的层
对这个。 “PerlIO_binmode()”会弄乱这个标志而不是添加/删除层
如果为图层类设置了“PERLIO_K_CANCRLF”位。

PERLIO_F_UTF8
写入该层的数据应为 UTF-8 编码; 该层提供的数据应该
被认为是 UTF-8 编码。 可以通过 ":utf8" 虚拟层在任何层上设置。 还设置
在“:编码”层。

PERLIO_F_UNBUF
层是无缓冲的——即每次写入都应该向下一层写入
这一层。

PERLIO_F_WRBUF
该层的缓冲区当前保存写入它但未发送到下一个的数据
层。

PERLIO_F_RDBUF
该层的缓冲区当前保存从下面的层读取的未消耗数据。

PERLIO_F_LINEBUF
层是行缓冲的。 每当出现“\n”时,写入数据应向下传递到下一层
被看到。 然后应该处理超出“\n”的任何数据。

PERLIO_F_TEMP
文件已被“取消链接()”编辑,或应在“关闭()”时删除。

PERLIO_F_OPEN
把手打开。

PERLIO_F_FASTGETS
该层的这个实例支持“快速“获取”接口。 通常基于设置
在类的“PERLIO_K_FASTGETS”上以及通过函数的存在
桌子。 然而,通常提供该接口的类可能需要在
具体实例。 当“pending”层被推到一个
不支持接口的层。 (Perl 的“sv_gets()”不期望
流式传输快速“获取”行为在一次“获取”期间发生变化。)

方法 in Detail
大小
size_t fsize;

函数表的大小。 这与 PerlIO 代码“知道”的值进行比较
兼容性检查。 未来版本 五月 能够容忍针对其编译的层
旧版本的标题。

姓名
字符 * 名称;

图层名称 打开() Perl 应该调用的方法 打开()。 例如
如果图层称为 APR,您将调用:

打开 $fh, ">:APR", ...

Perl 知道它必须调用 PerlIOAPR_open() 实现的方法
APR 层。

尺寸
size_t 大小;

每个实例数据结构的大小,例如:

大小(PerlIOAPR)

如果此字段为零,则“PerlIO_pushed”不会分配任何内容并假定
layer 的 Pushed 函数将执行任何所需的层堆栈操作 - 用于避免
虚拟层的 malloc/free 开销。 如果该字段非零,则它必须至少为
“PerlIOl”的大小,“PerlIO_pushed”将为层的数据分配内存
结构并将新层链接到流的堆栈上。 (如果图层的 Pushed 方法
返回一个错误指示该层再次弹出。)


四类;

· 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);

唯一绝对强制的方法。 当层被压入堆栈时调用。
如果在打开后发生这种情况,则“mode”参数可能为 NULL。 “arg”将是非“NULL”
如果传递了参数字符串。 在大多数情况下,这应该调用“PerlIOBase_pushed()”
将“模式”转换为适当的“PERLIO_F_XXXXX”标志以及任何
层本身采取的行动。 如果一个层不期待它需要的参数
既不保存传递给它的那个,也不提供“Getarg()”(它也许可以
“Perl_warn”,表明该论点出乎意料)。

成功返回 0。 失败时返回 -1 并应设置 errno。

弹出
IV (*Popped)(pTHX_PerlIO *f);

当层从堆栈中弹出时调用。 通常会弹出一个图层
“关闭()”被调用。 但是如果程序不关闭可以弹出一个图层
动态管理流上的层。 在这种情况下,“Popped()”应该释放任何
资源(缓冲区、转换表等)不直接保存在层的结构中。
它还应该“Unread()”任何已从
下面的层回到那个层,这样它就可以重新提供给现在的样子
以上。

成功和失败返回 0。 如果“Popped()”返回 true 然后 佩里奥.c 假设
要么图层本身弹出,要么图层非常特殊并且需要
因其他原因保留。 在大多数情况下它应该返回 false.

可选
PerlIO * (*打开)(...);

“Open()”方法有很多参数,因为它结合了 perl 的功能
“open”、“PerlIO_open”、perl 的“sysopen”、“PerlIO_fdopen”和“PerlIO_reopen”。 这
完整原型如下:

PerlIO * (*打开)(pTHX_ PerlIO_funcs *选项卡,
PerlIO_list_t *层,IV n,
常量字符*模式,
int fd、int imode、int perm、
PerlIO *旧,
int narg,SV **args);

Open 应该(也许是间接地)调用“PerlIO_allocate()”来在
表并将其与打开文件的图层信息相关联,通过调用
“PerlIO_push”。 这 是用于“PerlIO *”的所有层的数组,
以及传递给他们的任何参数, n 是该层数组的索引
叫。 宏“PerlIOArg”将为参数返回一个(可能是“NULL”)SV *
传递到图层。

这款 模式 string 是一个 ""fopen()"-like" 字符串,它将匹配正则表达式
“/^[I#]?[rwa]\+?[bt]?$/”。

“I”前缀在通过特殊创建“stdin”..“stderr”期间使用
“PerlIO_fdopen”调用; “#”前缀表示这是“sysopen”,并且 爱莫德
烫发 应该传递给“PerlLIO_open3”; 'r' 的意思 r读,'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”是
提供正是为了做到这一点,所以在大多数情况下,您不必自己编写
“打开()”方法。 如果没有定义这个方法,其他层可能会有困难
在打开时将自己推到它上面。

如果执行了“PerlIO_push”并且打开失败,则它必须“PerlIO_pop”自己,因为
如果不是,该层将不会被移除,并且可能会导致严重的问题。

失败时返回“NULL”。

二进制模式
IV (*Binmode)(pTHX_PerlIO *f);

可选的。 在推送 ":raw" 层时使用(显式或作为 binmode(FH) 的结果)。
如果不存在层将被弹出。 如果存在,应将层配置为二进制(或
pop本身)并返回0。如果它返回-1错误“binmode”将失败与层
仍在堆栈中。

格塔格
SV * (*Getarg)(pTHX_PerlIO *f,
CLONE_PARAMS *参数,int 标志);

可选的。 如果存在应该返回一个 SV * 表示传递给的字符串参数
推入时的图层。 例如 ":encoding(ascii)" 将返回一个带有值的 SvPV
“ascii”。 (停止标志 在大多数情况下可以忽略参数)

“Dup”使用“Getarg”来检索最初传递给“Pushed”的参数,所以你
如果您的层有一个额外的参数“推”,则必须实现此功能,并且将
永远被“欺骗”。

文件编号
IV (*Fileno)(pTHX_PerlIO *f);

返回句柄的 Unix/Posix 数字文件描述符。 一般
“PerlIOBase_fileno()”(它只是询问下一层)就足够了。

错误返回-1,这被认为包括层不能
提供这样的文件描述符。

DUP
PerlIO * (*Dup)(pTHX_ PerlIO *f, PerlIO *o,
CLONE_PARAMS *参数,int 标志);

XXX:需要更多文档。

生成线程时用作“克隆”过程的一部分(在这种情况下,param 将
非 NULL) 以及当流通过“打开”中的“&”复制时。

与“Open”类似,成功时返回 PerlIO*,失败时返回“NULL”。

阅读
SSize_t (*Read)(pTHX_PerlIO *f, void *vbuf, Size_t count);

基本读操作。

通常会调用“Fill”并操作指针(可能通过 API)。
“PerlIOBuf_read()”可能适用于提供“快速获取”的派生类
方法。

返回实际读取的字节数,或在出错时返回 -1。

未读
SSize_t (*未读)(pTHX_ PerlIO *f,
const void *vbuf, Size_t 计数);

stdio 的“ungetc()”的超集。 应该安排将来读取以查看字节
“vbuf”。 如果没有明显更好的实现,那么“PerlIOBase_unread()”
通过在调用层上方推送“假”“待定”层来提供该功能。

返回未读字符的数量。

填写
SSize_t (*Write)(PerlIO *f, const void *vbuf, Size_t count);

基本的写操作。

返回写入的字节数或错误时返回 -1。

寻找
IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int wherece);

定位文件指针。 通常应该调用它自己的“Flush”方法,然后
下一层的“寻找”方法。

成功时返回 0,失败时返回 -1。

告诉
Off_t (*Tell)(pTHX_PerlIO *f);

返回文件指针。 可能是基于图层缓存位置的概念来避免
高架。

在获取文件指针失败时返回 -1。

关闭
IV (*关闭)(pTHX_ PerlIO *f);

关闭流。 通常应该调用“PerlIOBase_close()”来刷新自身并关闭
层,然后释放任何数据结构(缓冲区、转换表、
...) 不直接保存在数据结构中。

成功时返回 0,失败时返回 -1。

红晕
IV (*Flush)(pTHX_PerlIO *f);

应该使流的状态与下面的层一致。 也就是说,任何缓冲写入
应写入数据,并为从中读取数据调整较低层的文件位置
低于但实际上并未消耗。 (也许应该将“Unread()”这样的数据降到更低
层。)

成功时返回 0,失败时返回 -1。


IV (*Fill)(pTHX_PerlIO *f);

该层的缓冲区应该从下面的层填充(用于读取)。 当你
“子类” PerlIOBuf 层,你想使用它的 _ 方法并提供您自己的
fill 方法,用于填充 PerlIOBuf 的缓冲区。

成功时返回 0,失败时返回 -1。

EOF
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
标志,通常就足够了。

获取_base
STDCHAR * (*Get_base)(pTHX_PerlIO *f);

为该层分配(如果尚未这样做)读取缓冲区并将指针返回到
它。 失败时返回 NULL。

get_bufsiz
size_t (*Get_bufsiz)(pTHX_ PerlIO *f);

返回最后一个“Fill()”放入缓冲区的字节数。

获取_ptr
STDCHAR * (*Get_ptr)(pTHX_PerlIO *f);

返回相对于该层缓冲区的当前读取指针。

获取_cnt
SSize_t (*Get_cnt)(pTHX_PerlIO *f);

返回当前缓冲区中要读取的剩余字节数。

设置_ptrcnt
void (*Set_ptrcnt)(pTHX_PerlIO *f,
STDCHAR *ptr, SSize_t cnt);

调整读取指针和字节数以匹配“ptr”和/或“cnt”。 这
应用程序(或上面的层)必须确保它们是一致的。 (检查被允许
偏执狂。)

Utilities / 公用事业
要请求下一层使用 PerlIONext(PerlIO *f)。

要检查 PerlIO* 是否有效,请使用 PerlIOValid(PerlIO *f)。 (这一切真的是
只是为了检查指针是否为非 NULL 以及其后面的指针是否为非 NULL。)

PerlIOBase(PerlIO *f) 返回“Base”指针,或者换句话说,“PerlIOl*”
指针。

PerlIOSelf(PerlIO* f, type) 将 PerlIOBase 转换为类型。

Perl_PerlIO_or_Base(PerlIO* f, callback, base, failure, args) 要么调用 回电话
从层的功能来看 f (仅通过 IO 函数的名称,如“读取”)与
ARGS,或者如果没有这样的回调,调用 基地 回调的版本
相同的参数,或者如果 f 无效,将 errno 设置为 EBADF 并返回 失败.

Perl_PerlIO_or_fail(PerlIO* f, callback, failure, args) 要么调用 回电话
层的功能 fARGS, 或者如果没有这样的回调, 将 errno 设置为
EINVAL。 或者如果 f 无效,则将 errno 设置为 EBADF 并返回 失败.

Perl_PerlIO_or_Base_void(PerlIO* f, callback, base, args) 要么调用 回电话
层的功能 fARGS,或者如果没有这样的回调,调用 基地
具有相同参数的回调版本,或者如果 f 无效,则将 errno 设置为 EBADF。

Perl_PerlIO_or_fail_void(PerlIO* f, callback, args) 要么调用 回电话
层的功能 fARGS, 或者如果没有这样的回调, 将 errno 设置为
EINVAL。 或者如果 f 无效,则将 errno 设置为 EBADF。

实现 佩里奥
如果您发现实施文件不清楚或不充分,请查看现有的
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
PerlIOBase_eof 的 Eof
错误 PerlIOBase_error
文件号 PerlIOBase_fileno
填充失败
冲洗成功
Getarg 成功
Get_base 失败
Get_bufsiz 失败
Get_cnt 失败
Get_ptr 失败
打开继承
突然成功
推动成功
读取 PerlIOBase_read
寻求失败
Set_cnt 失败
Set_ptrcnt 失败
设置行缓冲区 PerlIOBase_setlinebuf
告诉失败
未读 PerlIOBase_unread
写失败

FAILURE 设置 errno(在 Unixish 中为 EINVAL,在 VMS 中为 LIB$_INVARG)和
返回 -1(对于数字返回值)或 NULL(对于指针)
INHERITED 从下层继承
SUCCESS 返回 0(用于数字返回值)或指针

核心
文件“perlio.c”提供以下层:

“Unix”
一个基本的非缓冲层,它调用 Unix/POSIX "read()", "write()", "lseek()",
“关闭()”。 没有缓冲。 即使在区分 O_TEXT 和
O_BINARY 这个层总是 O_BINARY。

“佩利奥”
一个非常完整的通用缓冲层,它提供了整个 PerlIO API。 这是
还打算用作其他层的“基类”。 (例如它的“Read()”
方法是根据“Get_cnt()”/“Get_ptr()”/“Set_ptrcnt()”方法实现的)。

正如通过 PerlIO API 看到的那样,“unix”上的“perlio”完全替代了 stdio。
当系统的 stdio 不允许 perl 的“快速
获取”访问权限,并且不区分“O_TEXT”和“O_BINARY”。

“标准”
通过层方案提供 PerlIO API 的层,但通过
调用系统的 stdio。 如果系统的 stdio 提供,这是(当前)默认值
足够的访问权限以允许 perl 的“快速获取”访问,哪些不区分
“O_TEXT”和“O_BINARY”之间。

“crf”
使用“perlio”作为基类派生的层。 它为 CR,LF 提供类似 Win32 的 "\n"
翻译。 既可以应用在“perlio”之上,也可以作为缓冲层本身。
如果系统区分“O_TEXT”和“unix”,“crlf”是默认的
“O_BINARY”打开。 (在某些时候,“unix”将被“本机”Win32 IO 层取代
在那个平台上,因为 Win32 的读/写层有各种缺点。)“crlf”层
是以某种方式转换数据的层的合理模型。

“地图”
如果 Configure 检测到“mmap()”函数,则提供该层(使用“perlio”作为
“base”) 执行“读取”操作 映射()文件。 性能改进是
在现代系统上处于边缘,因此它主要用作概念证明。 这有可能
在某个时候从核心中分离出来。 “mmap”层是一个合理的模型
对于极简的“派生”层。

“待办的”
“perlio”的“内部”衍生物,可用于提供 未读() 功能
对于没有缓冲区或无法打扰的图层。 (基本上这一层的
“Fill()”将自身从堆栈中弹出,因此从下面的层继续读取。)

“生的”
层堆栈中永远不存在的虚拟层。 相反,当“推”它实际上
弹出堆栈移除自身,然后调用所有的 Binmode 函数表条目
堆栈中的层 - 通常这(通过 PerlIOBase_binmode)删除任何层
没有设置“PERLIO_K_RAW”位。 层可以通过定义它们的
自己的 Binmode 条目。

“utf8”
另一个虚拟层。 按下时它会弹出并设置“PERLIO_F_UTF8”标志
曾经(现在又是)堆栈顶部的层。

另外 佩里奥.c 还提供了许多“PerlIOBase_xxxx()”函数,它们是
旨在用于不需要做任何特殊事情的类的表槽中
对于特定的方法。

延期
可以通过扩展模块使层可用。 当遇到未知层时
PerlIO 代码将执行等效于:

使用 PerlIO '层';

其中 是未知层。 PerlIO.pm 然后将尝试:

需要 PerlIO::layer;

如果在该过程之后层仍未定义,则“打开”将失败。

以下扩展层与 perl 捆绑在一起:

“:编码”
使用编码;

使该层可用,尽管 PerlIO.pm “知道”在哪里可以找到它。 它是一个
一个层的例子,它接受一个参数,因为它被这样调用:

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

“:标量”
提供对从标量读取数据和向标量写入数据的支持。

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

当一个句柄如此打开时,然后从字符串值中读取获取字节 $标量
写入更改值。 在这两种情况下的位置 $标量 从零开始但可以
通过“seek”改变,通过“tell”确定。

请注意,调用时隐含了这一层 打开() 从而:

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

“:通过”
提供以允许将层实现为 Perl 代码。 例如:

使用 PerlIO::via::StripHTML;
open( 我的 $fh, "<:via(StripHTML)", "index.html" );

有关详细信息,请参阅 PerlIO::via。

ALL


需要做的事情来改进这个文档。

· 解释如何在不经过的情况下制作一个有效的 fh 打开()(即应用层)。 为了
例如,如果文件不是通过 perl 打开的,但我们想要取回 fh,就像它
由 Perl 打开。

PerlIO_apply_layera 如何适应,它的文档在哪里公开?

目前的例子可能是这样的:

PerlIO *foo_to_PerlIO(pTHX_ char *mode, ...)
{
字符*模式; /* "w", "r", 等等 */
const char *layers = ":APR"; /* 图层名称 */
PerlIO *f = PerlIO_allocate(aTHX);
如果(!f){
返回空;
}

PerlIO_apply_layers(aTHX_ f, 模式, 层);

如果 (f) {
PerlIOAPR *st = PerlIOSSelf(f, PerlIOAPR);
/* 填充 st 结构体,如 _open() */
st-> 文件 = 文件;
PerlIOBase(f)->flags |= PERLIO_F_OPEN;

返回 f;
}
返回空;
}

· 在标记为 XXX 的地方修复/添加文档。

· 层对错误的处理没有规定。 例如,当 $! 应该设置
明确地,何时应将错误处理委托给顶层。

大概给出一些使用提示 塞特诺() 或指向可以找到它们的位置的指针。

·我觉得可以举一些具体的例子,让大家更容易理解
API。 我当然同意 API 必须简洁,但由于没有
第二个文档更像是一个指南,我认为它会让开始更容易
文档是一个 API,但在某些地方有示例
不清楚,对于还不是 PerlIO 大师的人来说。

使用 onworks.net 服务在线使用 perliol


免费服务器和工作站

下载 Windows 和 Linux 应用程序

  • 1
    QNAP NAS GPL 来源
    QNAP NAS GPL 来源
    QNAP Turbo NAS 的 GPL 源代码。
    受众:开发人员。 用户界面:
    基于网络。 编程语言:C,
    爪哇。 类别:系统, 存储,
    操作系统核心...
    下载 QNAP NAS GPL 源
  • 2
    深层清洁
    深层清洁
    核对所有构建的 Kotlin 脚本
    来自 Gradle/Android 项目的缓存。
    当 Gradle 或 IDE 允许您时很有用
    向下。 该脚本已经过测试
    macOS,但是...
    下载深度清理
  • 3
    Eclipse Checkstyle 插件
    Eclipse Checkstyle 插件
    Eclipse Checkstyle 插件
    集成了 Checkstyle Java 代码
    审计员进入 Eclipse IDE。 这
    插件提供实时反馈
    用户关于viol...
    下载 Eclipse Checkstyle 插件
  • 4
    AstrOrz播放器
    AstrOrz播放器
    AstrOrz Player 是一款免费的媒体播放器
    软件,部分基于 WMP 和 VLC。 这
    播放器采用极简风格,带有
    十多个主题色,还可以
    B ...
    下载 AstrOrzPlayer
  • 5
    电影启动器
    电影启动器
    Kodi Movistar+ TV 是 XBMC/ 的 ADDON
    Kodi 许可分配器
    IPTV服务解码器
    Movistar Integrado en uno de los
    媒体中心马...
    下载 movistartv
  • 6
    代码::块
    代码::块
    Code::Blocks 是一个免费的、开源的、
    跨平台 C、C++ 和 Fortran IDE
    专为满足最苛刻的需求而打造
    它的用户。 它的设计非常
    扩展...
    下载代码::Blocks
  • 更多 ”

Linux 命令

Ad