=encoding UTF-8 =head1 НАИМЕНОВАНИЕ BH_IO - Подсистема ввода-вывода =head1 СИНТАКСИС #include BH_IO *io = BH_FileNew("input.txt", BH_FILE_WRITE | BH_FILE_TRUNCATE, NULL); BH_IOWrite(io, "Hello, world!", 13, NULL); BH_IOFree(io); cc prog.c -o prog -lbh =head1 ОПИСАНИЕ BH_IO предоставляет подсистему, позволяющей работать с различными объектами (файлы, сокеты, память) через единый интерфейс ввода-вывода. Это позволяет писать код, непривязанный к конкретной системе ввода-вывода. Гарантируется, что любой объект BH_IO поддерживает следующие операции: L, L, L и L. В зависимости от реализации того или иного объекта BH_IO, могут быть доступны дополнительные операции: L, L, L, L, L, L, L и другие. По-умолчанию подсистема ввода-вывода позволяет работать с файлами (L) или оперативной памятью (L), а также буферизировать ввод-вывод (L). =head1 РАСШИРЕНИЕ BH_IO предоставляет разработчику возможность создавать собственные реализации устройств ввода-вывода. Пример: typedef struct BH_MyIO { BH_IO parent; int flags; }; static int ioDestroy(BH_MyIO *io) { /* Ommitted for the example */ } static int ioRead(BH_MyIO *io, BH_IOReadInfo *info) { /* Ommitted for the example */ } static int ioWrite(BH_MyIO *io, BH_IOWriteInfo *info) { /* Ommited for the example */ } static int ioFlags(BH_MyIO *io, int *flags) { *flags = io->flags; return BH_OK; } static int ioCap(BH_MyIO *io, int *op) { BH_UNUSED(io); switch (*op) { case BH_IO_CTL_FLAGS: return BH_OK; default: return BH_NOIMPL; } } static int ioCtl(BH_MyIO *io, BH_IOCtlInfo *info) { switch (info->op) { case BH_IO_CTL_FLAGS: return ioFlags(io, (int *)info->arg); default: return BH_NOIMPL; } } static int ioCallback(BH_MyIO *io, int type, void *arg) { switch (type) { case BH_IO_OP_DESTROY: return ioDestroy(io); case BH_IO_OP_READ: return ioRead(io, (BH_IOReadInfo *)arg); case BH_IO_OP_WRITE: return ioWrite(io, (BH_IOWriteInfo *)arg); case BH_IO_OP_CTL: return ioCtl(io, (BH_IOCtlInfo *)arg); case BH_IO_OP_CAP: return ioCap(io, (int*)arg); default: return BH_NOIMPL; } } BH_IO *BH_MyIONew(int *result) { BH_MyIO *io; int code; code = BH_OOM; if ((io = malloc(sizeof(*io)))) { io->parent.callback = (BH_IOCallback)ioCallback; io->flags = 0; } if (result) *result = code; return (BH_IO*)io; } =head1 API ВЫЗОВЫ =head2 BH_FileNew BH_IO *BH_FileNew(const char *path, int mode, int *result); Создает устройство ввода-вывода для работы с файлом по пути I. Параметр I может принимать комбинацию из следующих значений: =over =item B Открывает файл на чтение =item B Открывает файл на запись =item B Открывает файл в режиме добавление в конец =item B Усекает файл =item B Файл должен быть создан =item B Файл должен существовать =back Опциональный параметр I возвращает 0 или код ошибки. Данная функция возвращает указатель на новый BH_IO объект или NULL. =head2 BH_IOIsFile int BH_IOIsFile(BH_IO *device); Проверяет, является ли устройство ввода-вывода файлом. =head2 BH_BufferNew BH_IO *BH_BufferNew(BH_IO *device, size_t size, int *result); Создает устройство ввода-вывода для буферизации данных к другому устройству I. Параметр I отвечает за размер буферов чтения и записи. Опциональный параметр I возвращает 0 или код ошибки. В случае успеха, данная функция возвращает указатель на новый BH_IO объект или NULL в случае ошибки. =head2 BH_IOIsBuffer int BH_IOIsBuffer(BH_IO *device); Проверяет, является ли устройство ввода-вывода буфером. =head2 BH_BytesNew BH_IO *BH_BytesNew(char *data, size_t size, int *result); Создает устройство ввода-вывода для региона памяти I с размером I. Опциональный параметр I возвращает код ошибки. В случае успеха, данная функция возвращает указатель на новый BH_IO объект или NULL в случае ошибки. =head2 BH_IOIsBytes int BH_IOIsBytes(BH_IO *device); Проверяет, является ли устройство ввода-вывода регионом памяти. =head2 BH_IOFree void BH_IOFree(BH_IO *device); Уничтожает устройство ввода-вывода. =head2 BH_IORead int BH_IORead(BH_IO *device, char *buffer, size_t size, size_t *actual); Читает до I байт из устройства ввода-вывода и записывает данные в I. Опциональный параметр I возвращает число байт, которое было фактически прочитано. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOWrite int BH_IOWrite(BH_IO *io, const char *buffer, size_t size, size_t *actual); Записывает до I байт в устройство ввода-вывода из I. Опциональный параметр I возвращает число байт, которое было записано. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOCtl int BH_IOCtl(BH_IO *device, int op, void *arg); Манипулирует параметрами устройства ввода-вывода с помощью команды I и параметра I. Возможные значения I: =over =item B Аргумент: int * Вернуть флаги устройства ввода-вывода. =item B Сбросить ошибки устройства ввода-вывода. =item B Аргумент: L Читает без извлечения данные из устройства ввода-вывода. =item B Записать буферизированные данные в устройство ввода-вывода. =item B Аргумент: int64_t * Получить размер устройства ввода-вывода. =item B Аргумент: int64_t * Читает текущее смещение указателя чтения устройства ввода-вывода. =item B Аргумент: L Изменяет текущее положение указателя чтения устройства ввода-вывода. =item B Аргумент: L|void * Получает объект устройства, используемый в реализации. =item B Аргумент: L|void * Устанавливает объект устройства, который будет использоваться в реализации. =back В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOCap int BH_IOCap(BH_IO *device, int op); Проверяет возможность выполнения команды I на устройстве ввода-вывода. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOFlags int BH_IOFlags(BH_IO *device, int *flags); Возвращает текущие флаги I устройства ввода-вывода. Возможные флаги (и их комбинации): =over =item B В процессе выполнения возникла ошибка. =item B Устройство достигло конца файла. =back В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOClear int BH_IOClear(BH_IO *device); Очищает устройство ввода-вывода от ошибок. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOPeek int BH_IOPeek(BH_IO *device, char *buffer, size_t size, size_t *actual); Читает без извлечения до I байт из устройства ввода-вывода и записывает данные в I. Опциональный параметр I возвращает число байт, которое было фактически прочитано. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOFlush int BH_IOFlush(BH_IO *device); Записывает буферизированные значения в устройство ввода-вывода. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOSize int BH_IOSize(BH_IO *device, int64_t *size); Читает текущий размер устройства ввода-вывода в байтах и записывает значение в I. Для различных типов устройств ввода-вывода данное значение может означать разные вещи (к примеру: текущий размер файла, размер выделенной для ввода-вывода памяти и т.д.). В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOTell int BH_IOTell(BH_IO *device, int64_t *offset); Читает текущее смещение указателя чтения устройства ввода-вывода относительно начала и записывает значение в I. В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOSeek int BH_IOSeek(BH_IO *device, int64_t offset, int whence); Изменяет текущее положение указателя чтения устройства ввода-вывода с учетом смещения I и начальной позиции I. Возможные значения начальной позиции I: =over =item B Смещение относительно начала устройства. =item B Смещение относительно текущей позиции устройства. =item B Смещение относительно конца устройства. =back В случае успеха, данная функция возвращает 0 или код ошибки. =head2 BH_IOError int BH_IOError(BH_IO *device); Проверяет, находится ли устройство ввода-вывода в состоянии ошибки. Данная функция эквивалентна следующему коду: (BH_IOFlags(device) & BH_IO_FLAG_ERROR) =head2 BH_IOEndOfFile int BH_IOEndOfFile(BH_IO *device); Проверяет, достигло ли устройство ввода-вывода конца. Данная функция эквивалентна следующему коду: (BH_IOFlags(device) & BH_IO_FLAG_EOF) =head2 BH_IOReadLine char *BH_IOReadLine(BH_IO *device, char *str, size_t size); Читает строку размером до I байт из устройства ввода-вывода и записывает данные в I. Результирующая строка нуль-терминированная. Останавливается на символе I<\n> или конце потока (EOF). Если строка длиннее буфера, её остаток остаётся в устройстве ввода-вывода для последующего чтения. Данная функция возвращает указатель на новый I или NULL. =head2 BH_IOReadLineFull char *BH_IOReadLineFull(BH_IO *device, char *str, size_t size); Читает строку размером до I байт из устройства ввода-вывода и записывает данные в I. Результирующая строка нуль-терминированная. Останавливается на символе I<\n> или конце потока (EOF). Полностью читает строку из устройства ввода-вывода, отбрасывая избыточные данные. Данная функция возвращает указатель на новый I или NULL. =head1 СТРУКТУРЫ ДАННЫХ =head2 BH_IO typedef struct BH_IO { BH_IOCallback callback; } BH_IO; =head2 BH_IOReadInfo typedef struct BH_IOReadInfo { char *data; size_t size; size_t *actual; } BH_IOReadInfo; =head2 BH_IOWriteInfo typedef struct BH_IOWriteInfo { const char *data; size_t size; size_t *actual; } BH_IOWriteInfo; =head2 BH_IOCtlInfo typedef struct BH_IOCtlInfo { int op; void *arg; } BH_IOCtlInfo; =head2 BH_IOSeekInfo typedef struct BH_IOSeekInfo { int64_t offset; int whence; } BH_IOSeekInfo; =head1 СМ. ТАКЖЕ L