Este es el comando perliol que se puede ejecutar en el proveedor de alojamiento gratuito de OnWorks utilizando una de nuestras múltiples estaciones de trabajo en línea gratuitas, como Ubuntu Online, Fedora Online, emulador en línea de Windows o emulador en línea de MAC OS.
PROGRAMA:
NOMBRE
perliol: API de C para la implementación de IO en capas de Perl.
SINOPSIS
/ * Definiendo una capa ... * /
#incluir
DESCRIPCIÓN
Este documento describe el comportamiento y la implementación de la abstracción PerlIO
descrito en perlapio cuando se define "USE_PERLIO".
Historia y las Fondo
La abstracción de PerlIO se introdujo en perl5.003_02 pero languideció como solo una
abstracción hasta perl5.7.0. Sin embargo, durante ese tiempo, varias extensiones de Perl cambiaron
para usarlo, por lo que la API se corrige principalmente para mantener la compatibilidad (fuente).
El objetivo de la implementación es proporcionar la API de PerlIO en una plataforma flexible
manera neutral. También es una prueba de un enfoque "C orientado a objetos, con vtables" que
se puede aplicar a Perl 6.
Básico Estructura
PerlIO es una pila de capas.
Los niveles bajos de la pila funcionan con las llamadas del sistema operativo de bajo nivel (archivo
descriptores en C) entrando y saliendo bytes, las capas superiores del búfer de pila, filtro,
y manipular de otro modo las E / S y devolver caracteres (o bytes) a Perl. Condiciones above
y las a continuación se utilizan para hacer referencia al posicionamiento relativo de las capas de la pila.
Una capa contiene una "vtable", la tabla de operaciones de E / S (en el nivel C, una tabla de funciones
punteros) y banderas de estado. Las funciones en vtable implementan operaciones como
"abrir", "leer" y "escribir".
Cuando se solicita E / S, por ejemplo, "leer", la solicitud va de Perl primero a la
pila usando las funciones de "lectura" de cada capa, luego, en la parte inferior, se solicita la entrada de
los servicios del sistema operativo, luego el resultado se devuelve a la pila, finalmente
interpretado como datos de Perl.
Las solicitudes no necesariamente van siempre hasta el sistema operativo: eso es
donde entra en juego el almacenamiento en búfer de PerlIO.
Cuando haces un open() y especifique capas de PerlIO adicionales para implementar, las capas que
especificar se "empujan" en la parte superior de la pila predeterminada ya existente. Una forma de verlo es
que "el sistema operativo está a la izquierda" y "Perl está a la derecha".
Las capas exactas que se encuentran en esta pila predeterminada dependen de muchas cosas: su
sistema, versión de Perl, configuración del tiempo de compilación de Perl y configuración del tiempo de ejecución de Perl.
Consulte PerlIO, "PERLIO" en perlrun y abra para obtener más información.
binmode () opera de manera similar a open(): de forma predeterminada, las capas especificadas se colocan en la parte superior
de la pila existente.
Sin embargo, tenga en cuenta que incluso cuando las capas especificadas se "colocan en la parte superior" para open() y las
binmode (), esto no significa que los efectos se limiten a la "parte superior": las capas PerlIO pueden
Sea muy "activo" e inspeccione y afecte las capas también más profundas en la pila. Como ejemplo
hay una capa llamada "cruda" que repetidamente "hace estallar" capas hasta que alcanza la primera
capa que se ha declarado capaz de manejar datos binarios. Las capas "empujadas" son
procesado en orden de izquierda a derecha.
sysopen () opera (como era de esperar) en un nivel más bajo en la pila que open(). For
ejemplo en Unix o sistemas similares a Unix sysopen () opera directamente a nivel de archivo
descriptores: en términos de capas de PerlIO, utiliza solo la capa "unix", que es una
envoltorio bastante delgado en la parte superior de los descriptores de archivos de Unix.
capas vs Disciplinas
La discusión inicial sobre la capacidad de modificar el comportamiento de los flujos de E / S utilizó el término
"disciplina" para las entidades que fueron agregadas. Esto vino (creo) del uso de la
término en "sfio", que a su vez lo tomó prestado de "disciplinas de línea" en terminales Unix.
Sin embargo, este documento (y el código C) utiliza el término "capa".
Este es, espero, un término natural dada la implementación, y debería evitar connotaciones
que son inherentes a los usos anteriores de "disciplina" para cosas que son bastante diferentes.
Fecha Estructuras
La estructura de datos básica es un PerlIOl:
estructura typedef _PerlIO PerlIOl;
typedef estructura _PerlIO_funcs PerlIO_funcs;
typedef PerlIOl * PerlIO;
estructura _PerlIO
{
PerlIOl * siguiente; / * Capa inferior * /
Pestaña PerlIO_funcs *; / * Funciones para esta capa * /
Banderas U32; / * Varias banderas para el estado * /
};
Un "PerlIOl *" es un puntero a la estructura, y el Postulación el nivel "PerlIO *" es un
puntero a un "PerlIOl *" - es decir, un puntero a un puntero a la estructura. Esto permite
nivel de aplicación "PerlIO *" para permanecer constante mientras que el "PerlIOl *" real debajo
cambios. (Compare "SV *" de perl que permanece constante mientras que su campo "sv_any" cambia como
el tipo del escalar cambia.) Un flujo de E / S se representa en general como un puntero a
esta lista enlazada de "capas".
Cabe señalar que debido a la doble indirección en un "PerlIO *", un
"& (perlio-> next)" "es" un "PerlIO *", por lo que, hasta cierto punto, al menos una capa puede usar el
API "estándar" en la siguiente capa.
Una "capa" se compone de dos partes:
1. Las funciones y atributos de la "clase de capa".
2. Los datos por instancia para un identificador particular.
Funciones y las Atributos
Se accede a las funciones y atributos a través de la "pestaña" (para tabla) miembro de "PerlIOl".
Las funciones (métodos de la capa "clase") son fijas y están definidas por el
Tipo "PerlIO_funcs". Son básicamente las mismas que las funciones públicas de "PerlIO_":
estructura _PerlIO_funcs
{
Tamaño_t ftamaño;
nombre del personaje;
Size_t tamaño;
Tipo IV;
IV (* Pulsado) (pTHX_ PerlIO * f, modo const char *, SV * arg, pestaña PerlIO_funcs *);
IV (* Popped) (pTHX_ PerlIO * f);
PerlIO * (* Abrir) (pestaña pTHX_ PerlIO_funcs *,
PerlIO_list_t * capas, IV n,
modo const char *,
int fd, int modo, int permanente,
PerlIO * viejo,
int narg, SV ** args);
IV (* Binmode) (pTHX_ PerlIO * f);
SV * (* Getarg) (pTHX_ PerlIO * f, CLONE_PARAMS * param, int banderas)
IV (* Fileno) (pTHX_ PerlIO * f);
PerlIO * (* Dup) (pTHX_ PerlIO * f, PerlIO * o, CLONE_PARAMS * param, int banderas)
/ * Funciones similares a Unix - cf disciplinas de línea sfio * /
SSize_t (* Leer) (pTHX_ PerlIO * f, void * vbuf, Size_t count);
SSize_t (* No leído) (pTHX_ PerlIO * f, const void * vbuf, Size_t count);
SSize_t (* Escritura) (pTHX_ PerlIO * f, const void * vbuf, Size_t count);
IV (* Seek) (pTHX_ PerlIO * f, Off_t offset, int de dónde);
Off_t (* Tell) (pTHX_ PerlIO * f);
IV (* Cerrar) (pTHX_ PerlIO * f);
/ * Funciones IO con búfer tipo Stdio * /
IV (* Flush) (pTHX_ PerlIO * f);
IV (* Relleno) (pTHX_ PerlIO * f);
IV (* Eof) (pTHX_ PerlIO * f);
IV (* Error) (pTHX_ PerlIO * f);
void (* Clearerr) (pTHX_ PerlIO * f);
void (* Setlinebuf) (pTHX_ PerlIO * f);
/ * Funciones de espionaje de Perl * /
STDCHAR * (* Get_base) (pTHX_ PerlIO * f);
Tamaño_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);
};
Los primeros miembros de la estructura dan un tamaño de tabla de funciones para verificar la compatibilidad
"nombre" para la capa, el tamaño a "malloc" para los datos por instancia y algunas marcas
que son atributos de la clase en su conjunto (como si es una capa de almacenamiento en búfer),
seguir las funciones que se dividen en cuatro grupos básicos:
1. Funciones de apertura y configuración
2. Operaciones básicas de IO
3. Opciones de almacenamiento en búfer de la clase Stdio.
4. Funciones para admitir el acceso "rápido" tradicional de Perl al búfer.
Una capa no tiene que implementar todas las funciones, pero toda la tabla tiene que ser
regalo. Las ranuras no implementadas pueden ser NULL (lo que resultará en un error cuando se llamen) o
se puede completar con stubs para "heredar" el comportamiento de una "clase base". Esta "herencia"
se fija para todas las instancias de la capa, pero a medida que la capa elige qué stubs rellenar
la tabla, es posible la "herencia múltiple" limitada.
Por instancia Fecha
Los datos por instancia se mantienen en la memoria más allá de la estructura básica de PerlIOl, haciendo un
PerlIOl el primer miembro de la estructura de la capa así:
estructura typedef
{
struct _PerlIO base; / * Información de la "clase" base * /
STDCHAR * buf; / * Inicio del búfer * /
STDCHAR * end; / * Fin de la parte válida del búfer * /
STDCHAR * ptr; / * Posición actual en el búfer * /
Off_t posn; / * Desplazamiento de buf en el archivo * /
Size_t bufsiz; / * Tamaño real del búfer * /
IV una palabra; / * Tampón de emergencia * /
} PerlIOBuf;
De esta manera (como para los escalares de perl) un puntero a un PerlIOBuf puede tratarse como un puntero
a un PerlIOl.
capas in acción.
mesa perlio unix
| |
+ ----------- + + ---------- + + -------- +
PerlIO -> | | ---> | siguiente | ---> | NULL |
+ ----------- + + ---------- + + -------- +
| | | tampón | | fd |
+ ----------- + | | + -------- +
| | + ---------- +
Lo anterior intenta mostrar cómo funciona el esquema de capas en un caso simple. Las aplicaciones
"PerlIO *" apunta a una entrada en la (s) tabla (s) que representan identificadores abiertos (asignados). Para
ejemplo, las tres primeras ranuras de la tabla corresponden a "stdin", "stdout" y "stderr".
La mesa, a su vez, apunta a la capa "superior" actual para el mango, en este caso un
instancia de la capa de almacenamiento en búfer genérico "perlio". Esa capa a su vez apunta a la siguiente
capa hacia abajo - en este caso la capa "unix" de bajo nivel.
Lo anterior es aproximadamente equivalente a una transmisión en búfer "stdio", pero con mucho más
flexibilidad:
· Si el nivel de Unix "leer" / "escribir" / "lseek" no es apropiado para (digamos) sockets, entonces el
La capa "unix" se puede reemplazar (en tiempo abierto o incluso dinámicamente) con una capa "socket".
· Diferentes manejadores pueden tener diferentes esquemas de almacenamiento en búfer. La capa "superior" podría ser la
Capa "mmap" si la lectura de archivos de disco fue más rápida usando "mmap" que "read". Un
El flujo "sin búfer" se puede implementar simplemente al no tener una capa de búfer.
· Se pueden insertar capas adicionales para procesar los datos a medida que fluyen. Este fue el
impulsando la necesidad de incluir el esquema en perl 5.7.0+ - necesitábamos un mecanismo para permitir
datos a traducir entre la codificación interna de perl (conceptualmente al menos Unicode
como UTF-8) y el formato "nativo" utilizado por el sistema. Esto es proporcionado por el
": capa de codificación (xxxx)" que normalmente se encuentra por encima de la capa de almacenamiento en búfer.
· Se puede agregar una capa que haga "\ n" en la traducción CRLF. Esta capa se puede utilizar en cualquier
plataforma, no solo aquellos que normalmente hacen tales cosas.
Por instancia bandera los bits
Los bits de banderas genéricos son un híbrido de banderas de estilo "O_XXXXX" deducidas de la cadena de modo
pasados a "PerlIO_open ()", y bits de estado para capas de búfer típicas.
PERLIO_F_EOF
Fin del documento.
PERLIO_F_CANWRITE
Se permiten escrituras, es decir, abiertas como "w" o "r +" o "a", etc.
PERLIO_F_CANREAD
Se permiten lecturas, es decir, abiertas "r" o "w +" (o incluso "a +" - ick).
PERLIO_F_ERROR
Ha ocurrido un error (para "PerlIO_error ()").
PERLIO_F_TRUNCATE
Truncar archivo sugerido por el modo abierto.
PERLIO_F_APPEND
Todas las escrituras deben adjuntarse.
PERLIO_F_CRLF
La capa tiene un rendimiento similar a Win32 "\ n" asignado a CR, LF para salida y CR, LF asignado a
"\ n" para la entrada. Normalmente, la capa "crlf" proporcionada es la única capa que necesita molestarse
sobre esto. "PerlIO_binmode ()" interferirá con esta bandera en lugar de agregar / eliminar capas
si el bit "PERLIO_K_CANCRLF" está configurado para la clase de capas.
PERLIO_F_UTF8
Los datos escritos en esta capa deben estar codificados en UTF-8; Los datos proporcionados por esta capa deben
se considerará codificado en UTF-8. Se puede configurar en cualquier capa mediante la capa ficticia ": utf8". También establece
en la capa ": codificación".
PERLIO_F_UNBUF
La capa no tiene búfer, es decir, la escritura en la siguiente capa debe ocurrir para cada escritura en
esta capa.
PERLIO_F_WRBUF
El búfer de esta capa contiene datos escritos en él pero no enviados a la siguiente.
capa.
PERLIO_F_RDBUF
El búfer de esta capa contiene actualmente datos no consumidos leídos de la capa inferior.
PERLIO_F_LINEBUF
La capa tiene búfer de línea. Los datos de escritura deben pasarse a la siguiente capa cada vez que un "\ n"
es visto. A continuación, se deben procesar todos los datos más allá de "\ n".
PERLIO_F_TEMP
El archivo ha sido "desvinculado ()" editado, o debería ser eliminado en "cerrar ()".
PERLIO_F_OPEN
La manija está abierta.
PERLIO_F_FASTGETS
Esta instancia de esta capa admite la interfaz "Fast" gets "". Normalmente establecido basado
sobre "PERLIO_K_FASTGETS" para la clase y por la existencia de la (s) función (es) en el
mesa. Sin embargo, una clase que normalmente proporciona esa interfaz puede necesitar evitarla en un
instancia particular. La capa "pendiente" debe hacer esto cuando se coloca por encima de un
capa que no es compatible con la interfaz. ("Sv_gets ()" de Perl no espera el
transmite rápidamente el comportamiento de "get" para cambiar durante un "get").
Métodos in Detail
ftamaño
Tamaño_t ftamaño;
Tamaño de la tabla de funciones. Esto se compara con el valor que el código PerlIO "conoce" como
una verificación de compatibilidad. Versiones futuras pueden ser capaz de tolerar capas compiladas contra
una versión antigua de los encabezados.
nombre
nombre del personaje;
El nombre de la capa cuya open() método que Perl debería invocar en open(). Por ejemplo
si la capa se llama APR, llamará:
abrir $ fh, ">: APR", ...
y Perl sabe que tiene que invocar el PerlIOAPR_open () método implementado por el
Capa APR.
tamaño
Size_t tamaño;
El tamaño de la estructura de datos por instancia, por ejemplo:
tamaño de (PerlIOAPR)
Si este campo es cero, entonces "PerlIO_pushed" no mallociza nada y asume
La función Pushed de la capa hará cualquier manipulación requerida de la pila de capas, que se usa para evitar
malloc / free overhead para capas ficticias. Si el campo es distinto de cero, debe ser al menos
el tamaño de "PerlIOl", "PerlIO_pushed" asignará memoria para los datos de la capa
estructuras y vincular la nueva capa a la pila de la secuencia. (Si el método Pushed de la capa
devuelve una indicación de error de que la capa ha vuelto a aparecer).
tipo
Tipo IV;
· PERLIO_K_BUFFERED
La capa está almacenada en búfer.
· PERLIO_K_RAW
Es aceptable tener la capa en una pila binmode (FH), es decir, no lo hace (o lo hará)
configurarse para no transformar los bytes que lo atraviesan.
· PERLIO_K_CANCRLF
La capa se puede traducir entre los extremos de línea "\ n" y CRLF.
· PERLIO_K_FASTGETS
La capa permite la búsqueda de búfer.
· PERLIO_K_MULTIARG
Se usa cuando la capa open() acepta más argumentos de lo habitual. El extra
los argumentos no deben ir antes del argumento "MODE". Cuando se usa esta bandera es
hasta la capa para validar los argumentos.
Empujado
IV (* Pulsado) (pTHX_ PerlIO * f, modo const char *, SV * arg);
El único método absolutamente obligatorio. Se llama cuando la capa se inserta en la pila.
El argumento "modo" puede ser NULL si esto ocurre después de la apertura. El "arg" no será "NULL"
si se pasó una cadena de argumentos. En la mayoría de los casos, esto debería llamar a "PerlIOBase_pushed ()"
para convertir el "modo" en los indicadores correspondientes "PERLIO_F_XXXXX" además de cualquier
acciones que realiza la propia capa. Si una capa no espera un argumento, necesita
ni guardar el que se le pasó, ni proporcionar "Getarg ()" (tal vez podría
"Perl_warn" que el argumento no fue esperado).
Devuelve 0 en caso de éxito. En caso de falla, devuelve -1 y debe establecer errno.
Reventado
IV (* Popped) (pTHX_ PerlIO * f);
Se llama cuando la capa se extrae de la pila. Normalmente, se abrirá una capa después
Se llama a "Close ()". Pero una capa puede abrirse sin cerrarse si el programa está
administrar capas dinámicamente en la secuencia. En tales casos, "Popped ()" debería liberar cualquier
recursos (búferes, tablas de traducción, ...) que no se encuentran directamente en la estructura de la capa.
También debería "No leer ()" cualquier dato no consumido que haya sido leído y almacenado en el búfer de la
capa de abajo de nuevo a esa capa, de modo que se pueda volver a proporcionar a lo que es ahora
anterior.
Devuelve 0 en caso de éxito y fracaso. Si devuelve "Popped ()" su verdadero y luego perlio.c asume
que la capa ha aparecido sola, o la capa es super especial y necesita ser
retenido por otras razones. En la mayoría de los casos debería volver false.
Abierto
PerlIO * (* Abierto) (...);
El método "Open ()" tiene muchos argumentos porque combina las funciones de perl
"open", "PerlIO_open", "sysopen" de perl, "PerlIO_fdopen" y "PerlIO_reopen". El
el prototipo completo es el siguiente:
PerlIO * (* Abrir) (pestaña pTHX_ PerlIO_funcs *,
PerlIO_list_t * capas, IV n,
modo const char *,
int fd, int modo, int permanente,
PerlIO * viejo,
int narg, SV ** args);
Open debería (quizás indirectamente) llamar a "PerlIO_allocate ()" para asignar una ranura en el
table y asócielo con la información de capas para el archivo abierto, llamando
"PerlIO_push". El ponedoras es una matriz de todas las capas destinadas al "PerlIO *",
y cualquier argumento que se les haya pasado, n es el índice en esa matriz de la capa que se
llamado. La macro "PerlIOArg" devolverá un SV * (posiblemente "NULL") para el argumento
pasado a la capa.
El elemento modo cadena es una cadena "" fopen () "- como" que coincidiría con la expresión regular
"/ ^ [I #]? [Rwa] \ +? [Bt]? $ /".
El prefijo 'I' se utiliza durante la creación de "stdin" .. "stderr" a través de especial
Llamadas "PerlIO_fdopen"; el prefijo '#' significa que es "sysopen" y que modo y las
permanente debe pasarse a "PerlLIO_open3"; 'r' significa read, 'w' significa writo y 'a'
significa append. El sufijo '+' significa que tanto la lectura como la escritura / adición son
permitido. El sufijo 'b' significa que el archivo debe ser binario y 't' significa que es texto.
(Casi todas las capas deben realizar la E / S en modo binario e ignorar los bits b / t.
La capa ": crlf" debe presionarse para manejar la distinción).
If los ancianos no es "NULL", entonces este es un "PerlIO_reopen". Perl en sí no usa esto
(¿todavía?) y la semántica es un poco vaga.
If fd no es negativo, entonces es el descriptor de archivo numérico fd, que estará abierto en un
de manera compatible con la cadena de modo suministrada, la llamada es, por lo tanto, equivalente a
"PerlIO_fdopen". En este caso Nargs será cero.
If Nargs es mayor que cero, entonces da el número de argumentos pasados a "abrir",
de lo contrario, será 1 si, por ejemplo, se llamó a "PerlIO_open". En casos sencillos
SvPV_nolen (* args) es el nombre de la ruta para abrir.
Si una capa proporciona "Open ()", normalmente debería llamar al método "Open ()" de la siguiente capa.
hacia abajo (si lo hay) y luego empujarse hacia arriba si tiene éxito. "PerlIOBase_open" es
proporcionado para hacer exactamente eso, por lo que en la mayoría de los casos no tiene que escribir su propio
Método "Open ()". Si este método no está definido, otras capas pueden tener dificultades.
empujándose sobre él durante la apertura.
Si se realizó "PerlIO_push" y la apertura ha fallado, debe hacerlo "PerlIO_pop", ya que
si no es así, la capa no se eliminará y puede causar graves problemas.
Devuelve "NULL" en caso de error.
modo bin
IV (* Binmode) (pTHX_ PerlIO * f);
Opcional. Se usa cuando se empuja la capa ": raw" (explícitamente o como resultado de binmode (FH)).
Si no está presente, se abrirá una capa. Si está presente, debe configurar la capa como binaria (o
pop en sí mismo) y devuelve 0. Si devuelve -1 para el error "binmode" fallará con la capa
todavía en la pila.
Getarg
SV * (* Getarg) (pTHX_ PerlIO * f,
CLONE_PARAMS * param, int banderas);
Opcional. Si está presente, debe devolver un SV * que representa el argumento de cadena pasado a
la capa cuando fue empujada. por ejemplo, ": codificación (ascii)" devolvería un SvPV con valor
"ascii". (detener y las banderas los argumentos se pueden ignorar en la mayoría de los casos)
"Dup" usa "Getarg" para recuperar el argumento originalmente pasado a "Pushed", por lo que
debe implementar esta función si su capa tiene un argumento adicional para "Pushed" y
alguna vez ser "Dup" ed.
fileño
IV (* Fileno) (pTHX_ PerlIO * f);
Devuelve el descriptor de archivo numérico Unix / Posix para el identificador. Normalmente
"PerlIOBase_fileno ()" (que solo pide la siguiente capa hacia abajo) será suficiente para esto.
Devuelve -1 en caso de error, que se considera que incluye el caso en el que la capa no puede
proporcione dicho descriptor de archivo.
Dup
PerlIO * (* Dup) (pTHX_ PerlIO * f, PerlIO * o,
CLONE_PARAMS * param, int banderas);
XXX: necesita más documentos.
Se utiliza como parte del proceso de "clonación" cuando se genera un hilo (en cuyo caso, param
ser no NULL) y cuando se está duplicando una secuencia a través de '&' en "abrir".
Similar a "Abrir", devuelve PerlIO * en caso de éxito, "NULL" en caso de error.
Leer
SSize_t (* Leer) (pTHX_ PerlIO * f, void * vbuf, Size_t count);
Operación de lectura básica.
Normalmente llamará a "Rellenar" y manipulará punteros (posiblemente a través de la API).
"PerlIOBuf_read ()" puede ser adecuado para clases derivadas que proporcionan "obtención rápida"
métodos.
Devuelve los bytes reales leídos, o -1 en caso de error.
No leídos
SSize_t (* No leído) (pTHX_ PerlIO * f,
const void * vbuf, Size_t count);
Un superconjunto de "ungetc ()" de stdio. Debería hacer arreglos para futuras lecturas para ver los bytes en
"vbuf". Si no hay una implementación obviamente mejor, entonces "PerlIOBase_unread ()"
proporciona la función presionando una capa "falsa" "pendiente" sobre la capa de llamada.
Devuelve el número de caracteres no leídos.
Escribe.
SSize_t (* Write) (PerlIO * f, const void * vbuf, Size_t count);
Operación de escritura básica.
Devuelve bytes escritos o -1 en caso de error.
EL EQUIPO
IV (* Seek) (pTHX_ PerlIO * f, Off_t offset, int de dónde);
Coloque el puntero del archivo. Normalmente debería llamar a su propio método "Flush" y luego el
Método de "búsqueda" de la siguiente capa hacia abajo.
Devuelve 0 en caso de éxito, -1 en caso de error.
Tell
Off_t (* Tell) (pTHX_ PerlIO * f);
Devuelve el puntero del archivo. Puede basarse en el concepto de posición en caché de capas para evitar
gastos generales.
Devuelve -1 si no se obtiene el puntero del archivo.
Cerrado
IV (* Cerrar) (pTHX_ PerlIO * f);
Cierra la corriente. Normalmente debería llamar a "PerlIOBase_close ()" para vaciarse y cerrar
capas de abajo, y luego desasignar cualquier estructura de datos (búferes, tablas de traducción,
...) no se mantiene directamente en la estructura de datos.
Devuelve 0 en caso de éxito, -1 en caso de error.
Flush
IV (* Flush) (pTHX_ PerlIO * f);
Debe hacer que el estado de la secuencia sea coherente con las capas siguientes. Es decir, cualquier escritura almacenada en búfer
Los datos deben escribirse y la posición del archivo de las capas inferiores debe ajustarse para los datos leídos desde
a continuación, pero no consumido realmente. (Quizás "No leídos ()" tales datos a la parte inferior
capa.)
Devuelve 0 en caso de éxito, -1 en caso de error.
Llene
IV (* Relleno) (pTHX_ PerlIO * f);
El búfer para esta capa debe llenarse (para leer) desde la capa inferior. Cuando usted
capa PerlIOBuf "subclase", desea utilizar su _read método y para suministrar su propio
método de relleno, que llena el búfer de PerlIOBuf.
Devuelve 0 en caso de éxito, -1 en caso de error.
Eof
IV (* Eof) (pTHX_ PerlIO * f);
Devolver indicador de fin de archivo. Normalmente, "PerlIOBase_eof ()" es suficiente.
Devuelve 0 al final del archivo, 1 si no es el final del archivo, -1 en caso de error.
Error
IV (* Error) (pTHX_ PerlIO * f);
Indicador de error de retorno. Normalmente, "PerlIOBase_error ()" es suficiente.
Devuelve 1 si hay un error (generalmente cuando se establece "PERLIO_F_ERROR"), 0 en caso contrario.
Más claro
void (* Clearerr) (pTHX_ PerlIO * f);
Indicadores claros de fin de archivo y error. Debería llamar a "PerlIOBase_clearerr ()" para configurar el
Banderas "PERLIO_F_XXXXX", que pueden ser suficientes.
setlinebuf
void (* Setlinebuf) (pTHX_ PerlIO * f);
Marque la secuencia como línea almacenada en búfer. "PerlIOBase_setlinebuf ()" establece el PERLIO_F_LINEBUF
bandera y normalmente es suficiente.
Obtener_base
STDCHAR * (* Get_base) (pTHX_ PerlIO * f);
Asigne (si aún no lo ha hecho) el búfer de lectura para esta capa y devuelva el puntero a
eso. Devuelve NULL en caso de falla.
get_bufsiz
Tamaño_t (* Get_bufsiz) (pTHX_ PerlIO * f);
Devuelve el número de bytes que el último "Fill ()" puso en el búfer.
Obtener_ptr
STDCHAR * (* Get_ptr) (pTHX_ PerlIO * f);
Devuelve el puntero de lectura actual relativo al búfer de esta capa.
Obtener_cnt
SSize_t (* Get_cnt) (pTHX_ PerlIO * f);
Devuelve el número de bytes que quedan por leer en el búfer actual.
conjunto_ptrcnt
void (* Set_ptrcnt) (pTHX_ PerlIO * f,
STDCHAR * ptr, SSize_t cnt);
Ajuste el puntero de lectura y el recuento de bytes para que coincida con "ptr" y / o "cnt". El
La aplicación (o capa superior) debe garantizar que sean consistentes. (La verificación está permitida por
el paranoico.)
Utilidades
Para solicitar la siguiente capa, use PerlIONext (PerlIO * f).
Para comprobar que un PerlIO * es válido, utilice PerlIOValid (PerlIO * f). (Todo lo que esto hace es realmente
solo para verificar que el puntero no sea NULL y que el puntero detrás de eso no sea NULL).
PerlIOBase (PerlIO * f) devuelve el puntero "Base", o en otras palabras, el "PerlIOl *"
puntero.
PerlIOSelf (PerlIO * f, type) devuelve la conversión de PerlIOBase a un tipo.
Perl_PerlIO_or_Base (PerlIO * f, callback, base, failure, args) o llama al llamar de vuelta
de las funciones de la capa f (solo por el nombre de la función IO, como "Leer") con
la args, o si no hay tal devolución de llamada, llama al bases versión de la devolución de llamada con el
mismos argumentos, o si la f no es válida, establezca errno en EBADF y regrese el fracaso.
Perl_PerlIO_or_fail (PerlIO * f, callback, failure, args) o llama al llamar de vuelta del
funciones de la capa f con el args, o si no hay tal devolución de llamada, establezca errno en
EINVAL. O si la f no es válida, establezca errno en EBADF y regrese el fracaso.
Perl_PerlIO_or_Base_void (PerlIO * f, callback, base, args) o llama al llamar de vuelta del
funciones de la capa f con el args, o si no hay tal devolución de llamada, llama al bases
versión de la devolución de llamada con los mismos argumentos, o si la f no es válida, establezca errno en EBADF.
Perl_PerlIO_or_fail_void (PerlIO * f, callback, args) o llama al llamar de vuelta del
funciones de la capa f con el args, o si no hay tal devolución de llamada, establezca errno en
EINVAL. O si la f no es válida, establezca errno en EBADF.
Poner en marcha Perlio capas
Si encuentra que el documento de implementación no es claro o no es suficiente, consulte el
Implementaciones de capa PerlIO, que incluyen:
· Implementaciones C
El elemento perlio.c y las perliol.h en el núcleo de Perl implemente el "unix", "perlio", "stdio",
"crlf", "utf8", "byte", "raw", capas "pendientes", y también las capas "mmap" y "win32"
capas si corresponde. (El "win32" está sin terminar y sin usar actualmente, para ver qué es
utilizado en su lugar en Win32, consulte "Consulta de las capas de identificadores de archivos" en PerlIO).
PerlIO :: encoding, PerlIO :: scalar, PerlIO :: via en el núcleo de Perl.
PerlIO :: gzip y APR :: PerlIO (mod_perl 2.0) en CPAN.
· Implementaciones de Perl
PerlIO :: via :: QuotedPrint en el núcleo de Perl y PerlIO :: via :: * en CPAN.
Si está creando una capa PerlIO, es posible que desee ser vago, en otras palabras, implementar
solo los métodos que le interesan. Los otros métodos que puede reemplazar con el
métodos "en blanco"
PerlIOBase_noop_ok
PerlIOBase_noop_fail
(que no hacen nada y devuelven cero y -1, respectivamente) o para ciertos métodos puede
asumir un comportamiento predeterminado mediante el uso de un método NULL. El método Open busca ayuda en el
capa 'padre'. La siguiente tabla resume el comportamiento:
comportamiento del método con NULL
Clearerr PerlIOBase_clearerr
Cerrar PerlIOBase_close
Duplicar PerlIOBase_dup
Eof PerlIOBase_eof
Error PerlIOBase_error
Archivo PerlIOBase_fileno
Llenar FALLO
ÉXITO de descarga
ÉXITO DE Getarg
ERROR en get_base
Get_bufsiz FALLO
Get_cnt FALLA
Get_ptr FALLO
Abierto HEREDADO
ÉXITO reventado
ÉXITO empujado
Leer PerlIOBase_read
Buscar FRACASO
Set_cnt FALLO
FALLO de set_ptrcnt
SetlinebufPerlIOBase_setlinebuf
Dile FALLO
PerlIOBase_unread no leído
Escribir FALLO
FALLO Establezca errno (a EINVAL en Unixish, a LIB $ _INVARG en VMS) y
return -1 (para valores de retorno numéricos) o NULL (para punteros)
HEREDADO Heredado de la capa de abajo
ÉXITO Devuelve 0 (para valores devueltos numéricos) o un puntero
Nuestras capas
El archivo "perlio.c" proporciona las siguientes capas:
"unix"
Una capa básica sin búfer que llama a Unix / POSIX "read ()", "write ()", "lseek ()",
"cerca()". Sin búfer. Incluso en plataformas que distinguen entre O_TEXT y
O_BINARY esta capa es siempre O_BINARY.
"perlio"
Una capa de almacenamiento en búfer genérica muy completa que proporciona toda la API de PerlIO. Está
también destinado a ser utilizado como una "clase base" para otras capas. (Por ejemplo, su "Leer ()"
se implementa en términos de los métodos "Get_cnt ()" / "Get_ptr ()" / "Set_ptrcnt ()").
"perlio" sobre "unix" proporciona un reemplazo completo para stdio como se ve a través de la API de PerlIO.
Este es el valor predeterminado para USE_PERLIO cuando el stdio del sistema no permite el "fast
obtiene "acceso, y que no distinguen entre" O_TEXT "y" O_BINARY ".
"stdio"
Una capa que proporciona la API de PerlIO a través del esquema de capas, pero la implementa mediante
stdio del sistema de llamada. Este es (actualmente) el valor predeterminado si el stdio del sistema proporciona
acceso suficiente para permitir el acceso de "accesos rápidos" de Perl y que no distinguen
entre "O_TEXT" y "O_BINARY".
"crlf"
Una capa derivada usando "perlio" como clase base. Proporciona "\ n" similar a Win32 a CR, LF
traducción. Puede aplicarse encima de "perlio" o servir como capa de amortiguación.
"crlf" sobre "unix" es el valor predeterminado si el sistema distingue entre "O_TEXT" y
Se abre "O_BINARY". (En algún momento, "unix" será reemplazado por una capa de E / S Win32 "nativa"
en esa plataforma, ya que la capa de lectura / escritura de Win32 tiene varios inconvenientes). La capa "crlf"
es un modelo razonable para una capa que transforma datos de alguna manera.
"mmap"
Si Configure detecta funciones "mmap ()", se proporciona esta capa (con "perlio" como
"base") que "lee" operaciones por mmap ()ing el archivo. La mejora del rendimiento es
marginal en los sistemas modernos, por lo que está principalmente allí como prueba de concepto. Es probable
ser desagregado del núcleo en algún momento. La capa "mmap" es un modelo razonable
para una capa "derivada" minimalista.
"pendiente"
Un derivado "interno" de "perlio" que se puede utilizar para proporcionar No leído() función
para capas que no tienen búfer o que no se pueden molestar. (Básicamente, esta capa
"Fill ()" sale de la pila y, por lo tanto, reanuda la lectura desde la capa inferior).
"crudo"
Una capa ficticia que nunca existe en la pila de capas. En cambio, cuando se "empuja", en realidad
hace estallar la pila eliminándose a sí misma, luego llama a la entrada de la tabla de funciones Binmode en todos los
capas en la pila - normalmente esto (a través de PerlIOBase_binmode) elimina cualquier capa que
no tienen establecido el bit "PERLIO_K_RAW". Las capas pueden modificar ese comportamiento definiendo su
propia entrada Binmode.
"utf8"
Otra capa ficticia. Cuando se presiona, aparece y activa la bandera "PERLIO_F_UTF8"
la capa que era (y ahora es una vez más) la parte superior de la pila.
Además de reunir registros perlio.c también proporciona una serie de funciones "PerlIOBase_xxxx ()" que son
destinado a ser utilizado en los espacios de tabla de clases que no necesitan hacer nada especial
para un método en particular.
Extension capas
Las capas pueden estar disponibles mediante módulos de extensión. Cuando se encuentra una capa desconocida
el código PerlIO realizará el equivalente de:
use PerlIO 'capa';
¿Dónde? . es la capa desconocida. PerlIO.pm luego intentará:
requiere PerlIO :: layer;
Si después de ese proceso la capa aún no está definida, la "apertura" fallará.
Las siguientes capas de extensión se incluyen con perl:
": codificación"
utilizar codificación;
hace que esta capa esté disponible, aunque PerlIO.pm "sabe" dónde encontrarlo. Es un
ejemplo de una capa que toma un argumento como se llama así:
open ($ fh, "<: codificación (iso-8859-7)", $ ruta);
":escalar"
Brinda soporte para leer y escribir datos en un escalar.
abierto ($ fh, "+ <: escalar", \ $ escalar);
Cuando un identificador está tan abierto, lee get bytes del valor de cadena de $ escalar y
escribe cambiar el valor. En ambos casos la posición en $ escalar comienza como cero pero puede
modificarse mediante "buscar" y determinarse mediante "indicar".
Tenga en cuenta que esta capa está implícita al llamar open() así:
abierto ($ fh, "+ <", \ $ escalar);
":vía"
Se proporciona para permitir que las capas se implementen como código Perl. Por ejemplo:
use PerlIO :: via :: StripHTML;
open (my $ fh, "<: via (StripHTML)", "index.html");
Consulte PerlIO :: via para obtener más detalles.
TODO
Cosas que deben hacerse para mejorar este documento.
· Explica cómo hacer una fh válida sin pasar por open()(es decir, aplicar una capa). Para
ejemplo, si el archivo no se abre a través de perl, pero queremos recuperar un fh, como este
fue abierto por Perl.
¿Cómo encaja PerlIO_apply_layera, dónde se hicieron públicos sus documentos?
Actualmente, el ejemplo podría ser algo como esto:
PerlIO * foo_to_PerlIO (modo pTHX_ char *, ...)
{
modo char *; / * "w", "r", etc * /
const char * capas = ": APR"; / * el nombre de la capa * /
PerlIO * f = PerlIO_allocate (aTHX);
si (! f) {
devuelve NULL;
}
PerlIO_apply_layers (aTHX_ f, modo, capas);
si (f) {
PerlIOAPR * st = PerlIOSelf (f, PerlIOAPR);
/ * completa la estructura st, como en _open () * /
st-> archivo = archivo;
PerlIOBase (f) -> banderas | = PERLIO_F_OPEN;
devolver f;
}
devuelve NULL;
}
· Arreglar / agregar la documentación en los lugares marcados como XXX.
· No se especifica el manejo de errores por capa. por ejemplo, cuando $! debe ser configurado
explícitamente, cuando el manejo de errores debe delegarse simplemente a la capa superior.
Probablemente dé algunas pistas sobre el uso SETERRNO () o indicadores de dónde se pueden encontrar.
· Creo que ayudaría dar algunos ejemplos concretos para que sea más fácil de entender
la API. Por supuesto, estoy de acuerdo en que la API tiene que ser concisa, pero como no hay
segundo documento que es más una guía, creo que facilitaría comenzar
con el documento, que es una API, pero tiene ejemplos en lugares donde las cosas están
poco claro, para una persona que no es un gurú de PerlIO (todavía).
Use perliol en línea usando los servicios de onworks.net