Це команда perliol, яку можна запустити в постачальнику безкоштовного хостингу OnWorks за допомогою однієї з наших численних безкоштовних робочих станцій, таких як Ubuntu Online, Fedora Online, онлайн-емулятор Windows або онлайн-емулятор MAC OS.
ПРОГРАМА:
ІМ'Я
perliol - C API для реалізації Perl IO в шарах.
СИНТАКСИС
/* Визначення шару ... */
#включати
ОПИС
Цей документ описує поведінку та реалізацію абстракції PerlIO
описано в perlapio, коли визначено "USE_PERLIO".
Історія та фон
Абстракція PerlIO була введена в perl5.003_02, але існувала лише як
абстракція до perl5.7.0. Однак за цей час змінилося ряд розширень perl
для його використання, тому API здебільшого фіксований для підтримки (джерела) сумісності.
Метою реалізації є забезпечення PerlIO API на гнучкому та платформному
нейтральний спосіб. Це також випробування підходу "об'єктно-орієнтованого C з vtables".
може застосовуватися до Perl 6.
Базовий структура
PerlIO – це набір шарів.
Низькі рівні стека працюють із низькорівневими викликами операційної системи (файл
дескриптори в C) отримання та виведення байтів, вищі рівні буфера стека, фільтр,
і іншим чином маніпулювати вводом-виводом і повертати символи (або байти) до Perl. Умови вище
та нижче використовуються для позначення відносного розташування шарів стека.
Рівень містить "vtable", таблицю операцій введення-виводу (на рівні C таблицю функцій
покажчики) та прапорці стану. Функції у vtable реалізують такі операції, як
«відкрити», «читати» та «записати».
Коли запитується введення-виведення, наприклад "читання", запит йде від Perl спочатку вниз
стек, використовуючи функції "читання" кожного шару, потім у нижній частині запитується введення
служб операційної системи, то результат повертається вгору стеку, нарешті
інтерпретується як дані Perl.
Запити не обов'язково завжди йдуть аж до операційної системи: це
де в гру вступає буферизація PerlIO.
Коли ви робите відчинено() і вкажіть додаткові шари PerlIO, які будуть розгорнуті, шари, які ви
вказати "поміщаються" поверх уже існуючого стеку за замовчуванням. Один із способів побачити це
що «операційна система знаходиться зліва» і «Perl знаходиться справа».
Які саме шари в цьому стеку за замовчуванням залежить від багатьох речей: вашої роботи
система, версія Perl, конфігурація часу компіляції Perl та конфігурація середовища виконання Perl.
Перегляньте PerlIO, «PERLIO» у perlrun і відкрийте для отримання додаткової інформації.
binmode() діє аналогічно відчинено(): за замовчуванням вказані шари висуваються зверху
існуючого стека.
Однак зверніть увагу, що навіть якщо вказані шари «висуваються зверху» для відчинено() та
binmode(), це не означає, що ефекти обмежені «верхнім»: шари PerlIO можуть
бути дуже «активним» і перевіряти та впливати на шари також глибше в стеку. Як приклад
є шар, який називається «сирий», який багаторазово «збиває» шари, поки не досягне першого
рівень, який оголосив себе здатним обробляти двійкові дані. «Просунуті» шари є
обробляється в порядку зліва направо.
sysopen() працює (як не дивно) на нижчому рівні в стеку, ніж відчинено(). Форум
наприклад в Unix або Unix-подібних системах sysopen() працює безпосередньо на рівні файлу
дескриптори: з точки зору шарів PerlIO, він використовує тільки рівень "unix", який є
досить тонка обгортка поверх дескрипторів файлів Unix.
Шари vs Дисципліни
Початкове обговорення можливості змінювати поведінку потоків введення-виведення використовувало цей термін
"дисципліна" для доданих об'єктів. Це сталося (я вважаю) від використання
термін у "sfio", який, у свою чергу, запозичив його з "строкових дисциплін" на терміналах Unix.
Однак у цьому документі (і коді C) використовується термін «шаров».
Я сподіваюся, що це природний термін з огляду на реалізацію, і він повинен уникати конотацій
які притаманні раніше використанню «дисципліни» для речей, які досить різні.
дані Структури
Основною структурою даних є PerlIOl:
typedef struct _PerlIO PerlIOl;
typedef struct _PerlIO_funcs PerlIO_funcs;
typedef PerlIOl *PerlIO;
struct _PerlIO
{
PerlIOl * наступний; /* Нижній шар */
PerlIO_funcs * вкладка; /* Функції для цього шару */
прапори U32; /* Різні прапори для стану */
};
"PerlIOl *" - це вказівник на структуру, і додатку рівень "PerlIO *" - це a
покажчик на "PerlIOl *" - тобто вказівник на вказівник на структуру. Це дозволяє
рівень програми "PerlIO *", щоб залишатися незмінним, а фактичний "PerlIOl *" нижче
зміни. (Порівняйте perl "SV *", який залишається незмінним, тоді як його поле "sv_any" змінюється як
змінюється тип скаляра.) Тоді потік введення-виведення, як правило, представляється як вказівник на
цей зв'язаний список "шарів".
Слід зазначити, що через подвійну ненаправленість у "PerlIO *", a
"&(perlio->next)" "є" PerlIO *", і тому до певної міри принаймні один шар може використовувати
"стандартний" API на наступному рівні.
«Шар» складається з двох частин:
1. Функції та атрибути «класу шару».
2. Дані для екземпляра для певного дескриптора.
Функції та Attributes
Доступ до функцій та атрибутів здійснюється через член "tab" (для таблиці) PerlIOl.
Функції (методи шару "клас") фіксовані і визначаються
Тип "PerlIO_funcs". Вони загалом такі ж, як загальнодоступні функції "PerlIO_":
struct _PerlIO_funcs
{
Size_t fsize;
char * ім'я;
Size_t розмір;
IV вид;
IV (*Pushed)(pTHX_ PerlIO *f,const char *mode,SV *arg, PerlIO_funcs *tab);
IV (*Вискочив)(pTHX_ PerlIO *f);
PerlIO * (*Відкрити)(pTHX_ PerlIO_funcs *вкладка,
PerlIO_list_t *шари, IV n,
const char *mode,
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 (*Fileno)(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);
SSize_t (*Write)(pTHX_ PerlIO *f, const void *vbuf, кількість Size_t);
IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int звідки);
Off_t (*Скажіть)(pTHX_ PerlIO *f);
IV (*Закрити)(pTHX_ PerlIO *f);
/* Буферизовані функції IO, подібні до STdio */
IV (*Промивання)(pTHX_ PerlIO *f);
IV (*Заповнення)(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);
};
Перші кілька членів структури дають розмір таблиці функцій для перевірки сумісності
"назва" для шару, розмір до "malloc" для даних для кожного екземпляра та деякі позначки
які є атрибутами класу в цілому (наприклад, чи є він буферним шаром), то
дотримуйтесь функцій, які поділяються на чотири основні групи:
1. Функції відкриття та налаштування
2. Основні операції IO
3. Параметри буферизації класу Stdio.
4. Функції підтримки традиційного «швидкого» доступу Perl до буфера.
Рівень не повинен реалізовувати всі функції, але має бути вся таблиця
присутній. Нереалізовані слоти можуть мати значення NULL (що призведе до помилки під час виклику) або
можна заповнити заглушками, щоб «успадкувати» поведінку від «базового класу». Це "спадок"
фіксується для всіх екземплярів шару, але як шар вибирає, які заглушки заповнити
таблиці, можливе обмежене «множинне успадкування».
На екземпляр дані
Дані для кожного екземпляра зберігаються в пам’яті за межами базової структури PerlIOl, створюючи a
PerlIO Визначте перший член структури шару таким чином:
структура typedef
{
struct _PerlIO база; /* Базова інформація про "клас" */
STDCHAR * buf; /* Початок буфера */
STDCHAR * кінець; /* Кінець дійсної частини буфера */
STDCHAR * ptr; /* Поточна позиція в буфері */
Off_t posn; /* Зміщення buf у файл */
Size_t bufsiz; /* Реальний розмір буфера */
IV одне слово; /* Аварійний буфер */
} PerlIOBuf;
Таким чином (як для скалярів perl) вказівник на PerlIOBuf можна розглядати як вказівник
до PerlIOl.
Шари in дії.
таблиця perlio unix
| |
+----------+ +----------+ +--------+
PerlIO ->| |--->| далі |--->| NULL |
+----------+ +----------+ +--------+
| | | буфер | | fd |
+----------+ | | +-------+
| | +---------+
Наведена вище спроба показати, як працює схема шарів у простому випадку. Додаток
"PerlIO *" вказує на запис у таблиці(ях), що представляє відкриті (розподілені) дескриптори. Для
Наприклад, перші три слоти в таблиці відповідають "stdin", "stdout" і "stderr".
Таблиця, у свою чергу, вказує на поточний "верхній" шар для ручки - в даному випадку an
екземпляр загального буферного шару "perlio". Цей шар, у свою чергу, вказує на наступний
рівень вниз - у цьому випадку низькорівневий шар "unix".
Наведене вище приблизно еквівалентно буферизованому потоку "stdio", але містить набагато більше
гнучкість:
· Якщо рівень Unix "read"/"write"/"lseek" не підходить для (скажімо) сокетів, тоді
"unix" шар може бути замінений (у відкритому часі або навіть динамічно) шаром "сокет".
· Різні дескриптори можуть мати різні схеми буферизації. "Верхнім" шаром може бути
"mmap", якщо читання дискових файлів було швидшим за допомогою "mmap", ніж "читання". An
"небуферизований" потік може бути реалізований, просто не маючи буферного рівня.
· Додаткові шари можуть бути вставлені для обробки даних під час їх проходження. Це було
спричиняє необхідність включення схеми в 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
Рівень виконує "\n", подібний до Win32, зіставлений на 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
Файл було видалено "unlink()" або його слід видалити за допомогою "close()".
PERLIO_F_OPEN
Ручка відкрита.
PERLIO_F_FASTGETS
Цей екземпляр цього шару підтримує інтерфейс «швидке отримання». Зазвичай встановлюється на основі
на "PERLIO_K_FASTGETS" для класу та за існуванням функції (функцій) у
стіл. Однак класу, який зазвичай надає цей інтерфейс, може знадобитися уникнути його на a
конкретний екземпляр. Шар "очікує на розгляд" повинен зробити це, коли він натиснутий вище a
шар, який не підтримує інтерфейс. ("sv_gets()" Perl не очікує
streams швидко "отримує" поведінку, яка змінюється протягом одного "отримання".)
Методи in деталь
fsize
Size_t fsize;
Розмір таблиці функцій. Це порівнюється зі значенням, яке "знає" код PerlIO
перевірка на сумісність. Майбутні версії може бути здатним витримувати шари, скомпільовані
стара версія заголовків.
ім'я
char * ім'я;
Назва шару, чий відчинено() метод Perl має викликати відчинено(). Наприклад
якщо шар називається APR, ви викличете:
відкрити $fh, ">:APR", ...
і Perl знає, що він повинен викликати PerlIOAPR_open() метод, реалізований за
APR шар.
розмір
Size_t розмір;
Розмір структури даних для кожного екземпляра, наприклад:
sizeof(PerlIOAPR)
Якщо це поле дорівнює нулю, то "PerlIO_pushed" нічого не блокує і припускає
Функція 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 (*Pushed)(pTHX_ PerlIO *f,const char *mode, SV *arg);
Єдиний абсолютно обов'язковий метод. Викликається, коли шар поміщається в стек.
Аргумент "mode" може бути NULL, якщо це відбувається після відкриття. "arg" буде не-"NULL"
якщо передано рядок аргументу. У більшості випадків це має викликати "PerlIOBase_pushed()"
щоб перетворити «режим» у відповідні прапори «PERLIO_F_XXXXX» на додаток до будь-яких
дії, які виконує сам шар. Якщо шар не очікує аргументу, він потрібен
ані зберігати переданий до нього, ані надавати "Getarg()" (можливо,
"Perl_warn", що аргумент був неочікуваним).
У разі успіху повертає 0. У разі відмови повертає -1 і має встановити errno.
Вискочив
IV (*Вискочив)(pTHX_ PerlIO *f);
Викликається, коли шар витягується зі стека. Після цього шар зазвичай з’являється
Викликається "Close()". Але шар можна відкрити, не закриваючи, якщо програма є
динамічне керування шарами в потоці. У таких випадках "Popped()" має звільнити будь-який
ресурси (буфери, таблиці перекладу, ...) не містяться безпосередньо в структурі шару.
Він також має "Unread()" будь-які невикористані дані, які були прочитані та буферизовані з
шар нижче назад до цього шару, щоб його можна було повторно надати до того, що коли-небудь є зараз
вище.
Повертає 0 за успіх і невдачу. Якщо повертається "Popped()". правда потім perlio.c передбачає
або шар вискочив сам, або шар є надзвичайно особливим і має бути таким
збережено з інших причин. У більшості випадків він повинен повернутися false.
відкритий
PerlIO * (*Відкрити)(...);
Метод «Open()» має багато аргументів, оскільки він поєднує функції perl
"open", "PerlIO_open", perl "sysopen", "PerlIO_fdopen" і "PerlIO_reopen". The
Повний прототип виглядає наступним чином:
PerlIO * (*Відкрити)(pTHX_ PerlIO_funcs *вкладка,
PerlIO_list_t *шари, IV n,
const char *mode,
int fd, int imode, int perm,
PerlIO *старий,
int narg, SV **args);
Open має (можливо, опосередковано) викликати "PerlIO_allocate()", щоб виділити слот у
таблицю та пов’язати її з інформацією про шари для відкритого файлу, викликавши
"PerlIO_push". The шарів є масивом усіх шарів, призначених для "PerlIO *",
і будь-які аргументи, передані їм, n є індексом цього масиву шару
дзвонив. Макрос "PerlIOArg" поверне (можливо, "NULL") SV * для аргументу
перейшов до шару.
Команда режим string – це рядок, схожий на ""fopen()", який відповідатиме регулярному виразу
"/^[I#]?[rwa]\+?[bt]?$/".
Префікс "I" використовується під час створення "stdin".."stderr" через спец
виклики "PerlIO_fdopen"; префікс '#' означає, що це "sysopen" і те imode та
хімічна завивка слід передати до "PerlLIO_open3"; 'r' означає read, "w" означає wобряд і "а"
засоби append. Суфікс «+» означає, що і читання, і запис/додавання є
дозволено. Суфікс "b" означає, що файл має бути двійковим, а "t" означає, що це текстовий файл.
(Майже всі рівні повинні виконувати введення в двійковий режим і ігнорувати біти b/t.
Шар «:crlf» слід натиснути, щоб обробити відмінність.)
If старий не "NULL", то це "PerlIO_reopen". Сам Perl цього не використовує
(ще?) і семантика трохи розпливчасті.
If fd не негативний, то це числовий дескриптор файлу fd, яка буде відкрита в a
Таким чином, виклик є еквівалентним
"PerlIO_fdopen". В цьому випадку нарги буде нульовим.
If нарги більше нуля, то він дає кількість аргументів, переданих до "open",
інакше це буде 1, якщо, наприклад, було викликано "PerlIO_open". У простих випадках
SvPV_nolen(*args) – це ім’я шляху для відкриття.
Якщо шар забезпечує "Open()", він зазвичай має викликати метод "Open()" наступного шару
вниз (якщо є), а потім штовхнеться зверху, якщо це вдасться. "PerlIOBase_open" є
передбачено, щоб зробити саме це, тому в більшості випадків вам не потрібно писати власний
Метод «Open()». Якщо цей метод не визначено, інші шари можуть мати труднощі
штовхаються на нього під час відкриття.
Якщо "PerlIO_push" було виконано і відкриття не вдалося, він повинен сам "PerlIO_pop", оскільки
якщо це не так, шар не буде видалено і може викликати серйозні проблеми.
Повертає "NULL" у разі відмови.
Binmode
IV (*Binmode)(pTHX_ PerlIO *f);
За бажанням. Використовується, коли шар ":raw" натискається (явно або в результаті binmode(FH)).
Якщо його немає, шар з’явиться. Якщо є, слід налаштувати шар як двійковий (або
pop) і повертає 0. Якщо він повертає -1 для помилки, "binmode" вийде з ладу з шаром
все ще в стопці.
Гетарг
SV * (*Getarg)(pTHX_ PerlIO *f,
CLONE_PARAMS *param, прапори int);
За бажанням. Якщо присутній, має повернути SV *, що представляє передано аргумент рядка
шар, коли він був натиснутий. наприклад, ":encoding(ascii)" поверне SvPV зі значенням
"ascii". (парам та прапори аргументи в більшості випадків можна ігнорувати)
"Dup" використовує "Getarg" для отримання аргументу, спочатку переданого в "Pushed", тому ви
має реалізувати цю функцію, якщо ваш шар має додатковий аргумент для "Pushed" і буде
коли-небудь бути "обдуреним".
Філено
IV (*Fileno)(pTHX_ PerlIO *f);
Повертає числовий дескриптор файлу Unix/Posix для дескриптора. Зазвичай
"PerlIOBase_fileno()" (який просто запитує наступний рівень вниз) буде достатньо для цього.
Повертає -1 у разі помилки, яка, як вважається, включає випадок, коли шар не може
надайте такий дескриптор файлу.
Dup
PerlIO * (*Dup)(pTHX_ PerlIO *f, PerlIO *o,
CLONE_PARAMS *param, прапори int);
XXX: Потрібні додаткові документи.
Використовується як частина процесу "клонування", коли створюється потік (у цьому випадку param
бути не-NULL) і коли потік дублюється за допомогою '&' в розділі "відкрити".
Подібно до "Відкрити", повертає 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, кількість розмірів_t);
Наднабір stdio "ungetc()". Слід організувати майбутні читання, щоб побачити байти
"vbuf". Якщо немає очевидно кращої реалізації, тоді "PerlIOBase_unread()"
забезпечує функцію, натискаючи "підробку" "очікуваного" шару над шаром, що викликає.
Повертає кількість непрочитаних символів.
Запис
SSize_t (*Write)(PerlIO *f, const void *vbuf, кількість Size_t);
Основна операція запису.
Повертає записані байти або -1 у разі помилки.
Шукати
IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int звідки);
Розташуйте вказівник файлу. Зазвичай має викликати власний метод "Flush", а потім
Метод «Шукати» наступного шару вниз.
Повертає 0 при успіху, -1 при невдачі.
Сказати
Off_t (*Скажіть)(pTHX_ PerlIO *f);
Поверніть покажчик файлу. Може ґрунтуватися на кешованій концепції позиції, яку слід уникати
накладні витрати.
Повертає -1 у разі неможливості отримати вказівник файлу.
Закрити
IV (*Закрити)(pTHX_ PerlIO *f);
Закрийте потік. Зазвичай має викликати "PerlIOBase_close()", щоб очистити себе та закрити
шарів нижче, а потім звільнити будь-які структури даних (буфери, таблиці перекладу,
...) не міститься безпосередньо в структурі даних.
Повертає 0 при успіху, -1 при невдачі.
Промивати
IV (*Промивання)(pTHX_ PerlIO *f);
Повинен зробити стан потоку узгодженим із шарами нижче. Тобто будь-який буферизований запис
дані повинні бути записані, а розташування файлів нижніх шарів відкориговано для зчитування даних
нижче, але фактично не споживається. (Можливо, "Unread()" такі дані слід перевести на нижчий
шар.)
Повертає 0 при успіху, -1 при невдачі.
Заповнювати
IV (*Заповнення)(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()" зазвичай достатньо.
Повертає 1, якщо є помилка (зазвичай, коли встановлено "PERLIO_F_ERROR"), 0 в іншому випадку.
Ясніше
void (*Clearerr)(pTHX_ PerlIO *f);
Очистіть індикатори закінчення файлу та помилок. Потрібно викликати "PerlIOBase_clearerr()", щоб встановити
Прапори "PERLIO_F_XXXXX", яких може бути достатньо.
Setlinebuf
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". The
додаток (або шар вище) повинен забезпечити їх узгодженість. (Перевірка дозволена
параноїк.)
Комунальні послуги
Щоб запитати наступний рівень вниз, використовуйте PerlIONext(PerlIO *f).
Щоб перевірити, чи є PerlIO* дійсним, використовуйте PerlIOValid(PerlIO *f). (Все це робить насправді
просто щоб перевірити, що вказівник не має значення NULL і що вказівник за ним не є NULL.)
PerlIObase(PerlIO *f) повертає покажчик "Base", або іншими словами, "PerlIOl*"
вказівник.
PerlIOSelf(PerlIO* f, type) повертає приведення PerlIOSelf до типу.
Perl_PerlIO_or_Base(PerlIO* f, callback, base, failure, args) або викликає Як передзвонити
від функцій шару f (просто за назвою функції IO, як-от "Читання") with
аргументи, або якщо такого зворотного виклику немає, викликає база версія зворотного виклику з
ті самі аргументи, або якщо 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, зворотний виклик, args) або викликає Як передзвонити в
функції шару f з аргументи, або якщо такого зворотного виклику немає, встановіть errno на
EINVAL. Або, якщо f недійсний, установіть для errno значення EBADF.
Реалізація PerlIO Шари
Якщо ви вважаєте, що впроваджувальний документ незрозумілий або недостатній, перегляньте наявний
Реалізації рівня PerlIO, які включають:
· Реалізації C
Команда perlio.c та перліол.ч в ядрі Perl реалізуйте "unix", "perlio", "stdio",
"crlf", "utf8", "byte", "raw", "очікуючі" шари, а також "mmap" і "win32"
шари, якщо є. ("win32" наразі незавершений і не використовується, щоб побачити, що є
замість цього використовується у Win32, див. «Запити до шарів дескрипторів файлів» у PerlIO.)
PerlIO::encoding, PerlIO::scalar, PerlIO::via в ядрі Perl.
PerlIO::gzip і APR::PerlIO (mod_perl 2.0) на CPAN.
· Реалізації Perl
PerlIO::via::QuotedPrint в ядрі Perl і PerlIO::via::* на CPAN.
Якщо ви створюєте шар PerlIO, ви можете бути лінивими, іншими словами, реалізувати
тільки ті методи, які вас цікавлять. Інші методи ви можете замінити на
«пусті» методи
PerlIOBase_noop_ok
PerlIOBase_noop_fail
(які нічого не роблять і повертають нуль і -1 відповідно) або для певних методів ви можете
прийняти поведінку за замовчуванням, використовуючи метод NULL. Метод Open шукає допомогу в
"батьківський" шар. У наступній таблиці підсумовано поведінку:
поведінка методу з NULL
Clearerr PerlIOBase_clearerr
Закрийте PerlIOBase_close
Дублювати PerlIOBase_dup
Eof PerlIOBase_eof
Помилка PerlIOBase_error
Файл PerlIOBase_fileno
Помилка заповнення
Промити УСПІХ
Getarg УСПІХУ
Get_base ПОМИЛКА
Get_bufsiz ПОМИЛКА
Get_cnt ПОМИЛКА
Get_ptr ПОМИЛКА
Відкрити INHERITED
Вискочив УСПІХ
Проштовхнув УСПІХ
Прочитайте PerlIOBase_read
Шукайте НЕУДАЧУ
Set_cnt ПОМИЛКА
Set_ptrcnt ПОМИЛКА
Setlinebuf PerlIOBase_setlinebuf
Скажіть FAILURE
Непрочитане PerlIOBase_unread
Напишіть FAILURE
FAILURE Встановіть errno (в EINVAL в Unixish, у LIB$_INVARG у VMS) і
повернути -1 (для числових значень) або NULL (для покажчиків)
INHERITED Успадковано від шару нижче
УСПІХ Повертає 0 (для числових значень) або покажчик
Core Шари
Файл "perlio.c" містить такі шари:
"unix"
Базовий небуферизований шар, який викликає Unix/POSIX "read()", "write()", "lseek()",
"закрити ()". Без буферизації. Навіть на платформах, які відрізняють O_TEXT і
O_BINARY цей шар завжди O_BINARY.
"перліо"
Дуже повний загальний буферний рівень, який забезпечує весь API PerlIO. це є
також призначений для використання як "базовий клас" для інших шарів. (Наприклад, його "Read()"
метод реалізований у термінах методів "Get_cnt()"/"Get_ptr()"/"Set_ptrcnt()").
"perlio" замість "unix" забезпечує повну заміну stdio, як це видно через API PerlIO.
Це значення за замовчуванням для USE_PERLIO, коли системний stdio не дозволяє perl "швидкий
отримує доступ, і які не відрізняють "O_TEXT" і "O_BINARY".
"stdio"
Рівень, який надає API PerlIO через схему рівня, але реалізує його за допомогою
виклик stdio системи. Це (наразі) за замовчуванням, якщо надає системний stdio
достатній доступ, щоб дозволити Perl "швидкий доступ" і які не розрізняють
між "O_TEXT" і "O_BINARY".
"crlf"
Шар, отриманий з використанням "perlio" як базового класу. Він надає Win32-подібний "\n" для CR,LF
переклад. Може застосовуватися над "perlio" або служити самим буферним шаром.
"crlf" над "unix" є за замовчуванням, якщо система розрізняє "O_TEXT" і
Відкривається "O_BINARY". (У якийсь момент «unix» буде замінено «рідним» рівнем введення в систему Win32
на цій платформі, оскільки рівень читання/запису Win32 має різні недоліки.) Шар «crlf»
є розумною моделлю для шару, який певним чином перетворює дані.
"mmap"
Якщо Configure виявляє функції "mmap()", цей рівень надається (з "perlio" як
"base"), яка виконує операції "читання" за допомогою mmap ()завантаження файлу. Підвищення продуктивності є
маргінальний на сучасних системах, тому він в основному є там як доказ концепції. Це ймовірно
бути відокремленим від ядра в якийсь момент. Рівень "mmap" є розумною моделлю
для мінімалістичного «похідного» шару.
"очікує"
«Внутрішня» похідна від «perlio», яку можна використовувати для надання непрочитаний() функція
для шарів, які не мають буфера або не можуть бути оброблені. (В основному цей шар
"Fill()" виривається зі стека і відновлює читання з нижнього шару.)
"сирий"
Фіктивний шар, який ніколи не існує в стеку шарів. Замість того, коли "штовхнули" це насправді
виводить стек, видаляючи себе, потім викликає запис таблиці функції Binmode для всіх файлів
шари в стеку - зазвичай це (через PerlIOBase_binmode) видаляє всі шари, які
не мають встановленого біта "PERLIO_K_RAW". Шари можуть змінити цю поведінку, визначивши їх
власний запис Binmode.
"utf8"
Ще один фіктивний шар. При натисканні він спливає сам і встановлює прапор "PERLIO_F_UTF8".
шар, який був (і тепер знову є) вершиною стека.
На додаток perlio.c також надає ряд функцій "PerlIOBase_xxxx()", які є
призначений для використання в слотах таблиць класів, які не потребують робити нічого особливого
для конкретного методу.
Розширення Шари
Шари можуть бути доступними за допомогою модулів розширення. Коли зустрічається невідомий шар
код PerlIO буде виконувати еквівалент:
використовувати «шар» PerlIO;
де шар це невідомий шар. PerlIO.pm потім спробує:
вимагає PerlIO::layer;
Якщо після цього процесу шар все ще не визначено, то "відкрити" не вийде.
Наступні шари розширення поєднуються з perl:
": кодування"
використовувати кодування;
робить цей шар доступним, хоча PerlIO.pm «знає», де його знайти. Це є
приклад шару, який приймає аргумент, як його називають таким чином:
open( $fh, "<:кодування(iso-8859-7)", $pathname);
": скаляр"
Забезпечує підтримку читання даних зі скаляра та запису даних до них.
open( $fh, "+<:scalar", \$scalar);
Коли дескриптор відкривається таким чином, читання одержує байти зі значення рядка $скаляр та
записи змінюють значення. В обох випадках положення в $скаляр починається з нуля, але може
змінюватися за допомогою «шукати» та визначати за допомогою «розповісти».
Зверніть увагу, що цей рівень мається на увазі під час дзвінка відчинено() таким чином:
open( $fh, "+<", \$скаляр);
": via"
Надається, щоб дозволити реалізувати шари як код 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, ...)
{
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);
/* заповнюємо структуру st, як у _open() */
st->файл = файл;
PerlIOBase(f)->прапори |= PERLIO_F_OPEN;
повернення f;
}
повернути NULL;
}
· виправити/додати документацію в місцях, позначених як XXX.
· Не вказано обробку помилок шаром. наприклад, коли $! слід встановити
явно, коли обробка помилок має бути просто делегована верхньому шару.
Напевно, дайте кілька підказок щодо використання SETERRNO() або вказівники, де їх можна знайти.
· Я думаю, що було б корисно навести кілька конкретних прикладів, щоб було легше зрозуміти
API. Звичайно, я згоден з тим, що API має бути лаконічним, але оскільки його немає
Другий документ, який більше нагадує керівництво, я думаю, що це полегшить його початок
з документом, який є API, але містить приклади в місцях, де є речі
незрозуміло, для людини, яка (поки що) не є гуру PerlIO.
Використовуйте perliol онлайн за допомогою служб onworks.net