# Класс *io_stream*

Класс, предназначенный для работы с потоками

## Режимы

Поток имеет три различных вида режима:

**general** - Общий режим работы I/O
**binary** - Формат записи и чтения I/O
**flush** - Режим работы flush

### general

Имеет три режима:

**default** - Дефолтный режим работы потока. При read может вернуть только часть от требуемых данных, при write сразу записывает данные в поток.

**yield** - Почти тоже самое, что и **default**, но всегда будет возвращать все требуемые данные. Пока они не будут прочитаны, будет вызывать `coroutine.yield()`. Предназначен для работы в корутинах.

**buffered** - Буферизирует записываемые и читаемые данные.

При вызове `available`/`read` обновляет буфер чтения.

После обновления в `read`, если буфер чтения переполнен, то бросает ошибку `buffer overflow`.

Если требуемого кол-ва байт недостаточно в буфере для чтения, то бросает ошибку `buffer-underflow`. 

При вызове `write` записывает итоговые байты в буфер для записи. Если он переполнен, то бросает ошибку `buffer overflow`.

При вызове `flush` проталкивает данные из буфера для записи в напрямую в поток

### flush

**all** - Сначала проталкивает данные из буфера напрямую в поток (если используется **buffered** режим), а после вызывает `flush` напрямую из библиотеки

**buffer** - Только проталкивает данные из буфера в поток (если используется **buffered** режим)

## Методы

Методы, позволяющие изменить или получить различные режимы поведения потока

```lua
-- Возвращает true, если поток используется в двоичном режиме
io_stream:is_binary_mode() --> bool

-- Включает или выключает двоичный режим
io_stream:set_binary_mode(bool)

-- Возвращает режим работы потока
io_stream:get_mode() --> string

-- Задаёт режим работы потока. Выбрасывает ошибку, если передан неизвестный режим
io_stream:set_mode(string)

-- Возвращает режим работы flush
io_stream:get_flush_mode() --> string

-- Задаёт режим работы flush
io_stream:set_flush_mode(string)
```

I/O методы

```lua

--[[
Читает данные из потока

В двоичном режиме:

Если arg - int, то читает из потока arg байт и возвращает ввиде Bytearray или таблицы, если useTable = true

Если arg - string, то функция интерпретирует arg как шаблон для byteutil. Прочитает кол-во байт, которое определено шаблоном, передаст их в byteutil.unpack и вернёт результат


В текстовом режиме:

Если arg - int, то читает нужное кол-во строк с окончанием CRLF/LF из arg и возвращает ввиде таблицы. Также, если trimEmptyLines = true, то удаляет пустые строки с начала и конца из итоговой таблицы

Если arg не определён, то читает одну строку с окончанием CRLF/LF и возвращает её.
--]]
io_stream:read(
    [опционально] arg: int | string,
    [опционально] useTable | trimEmptyLines: bool
) --> Bytearray | table<int> | string | table<string> | ...

--[[
Записывает данные в поток

В двоичном режиме:

Если arg - string, то функция интерпретирует arg как шаблон для byteutil, передаст его и ... в byteutil.pack и результат запишет в поток

Если arg - Bytearray | table<int>, то записывает байты в поток

В текстовом режиме:

Если arg - string, то записывает строку в поток (вместе с окончанием LF)

Если arg - table<string>, то записывает каждую строку из таблицы отдельно
--]]
io_stream:write(
    arg: Bytearray | table<int> | string | table<string>,
    [опционально] ...
)

-- Читает одну строку с окончанием CRLF/LF из потока вне зависимости от двоичного режима
io_stream:read_line() --> string

-- Записывает одну строку с окончанием LF в поток вне зависимости от двоичного режима
io_stream:write_line(string)

--[[

В двоичном режиме:

Читает все доступные байты из потока и возвращает ввиде Bytearray или table<int>, если useTable = true

В текстовом режиме:

Читает все доступные строки из потока в table<string> если useTable = true, или в одну строку вместе с окончаниями, если нет

--]]
io_stream:read_fully(
    [опционально] useTable: bool
) --> Bytearray | table<int> | table<string> | string
```

Методы, имеющие смысл в использовании только в buffered режиме

```lua
--[[

Если length определён, то возвращает true, если length байт доступно к чтению. Иначе возвращает false

Если не определён, то возвращает количество байт, которое можно прочитать

--]]
io_stream:available(
    [опционально] length: int
) --> int | bool

-- Возвращает максимальный размер буферов
io_stream:get_max_buffer_size() --> int

-- Задаёт новый максимальный размер буферов
io_stream:set_max_buffer_size(max_size: int)
```

Методы, контролирующие состояние потока

```lua

-- Возвращает true, если поток открыт на данный момент
io_stream:is_alive() --> bool

-- Возвращает true, если поток закрыт на данный момент
io_stream:is_closed() --> bool

-- Закрывает поток
io_stream:close()

--[[

Записывает все данные из write-буфера в поток в buffer/all flush-режимах
Вызывает ioLib.flush() в all flush-режиме

--]]
io_stream:flush()
```

Создание нового потока

```lua
--[[

Создаёт новый поток с переданным дескриптором и использующим переданную I/O библиотеку. (Более подробно в core:io_stream.lua)

--]]
io_stream.new(
    descriptor: int,
    binaryMode: bool,
    ioLib: table,
    [опционально] mode: string = "default",
    [опционально] flushMode: string = "all"
) -> io_stream
```