Spec-Zone.ru › Tcl/Tk

refchan

НАЗВАНИЕ
refchan — обработчик команд API отражённых каналов
СИНТАКСИС
ОПИСАНИЕ
ОБЯЗАТЕЛЬНЫЕ ПОДКОМАНДЫ
cmdPrefix инициализировать channelId режим
cmdPrefix завершить channelId
cmdPrefix наблюдать channelId событие
НЕОБЯЗАТЕЛЬНЫЕ ПОДКОМАНДЫ
cmdPrefix читать channelId количество
cmdPrefix записать channelId данные
cmdPrefix переместиться channelId смещение база
начало
текущее
конец
cmdPrefix настроить channelId параметр значение
cmdPrefix получить channelId параметр
cmdPrefix получить все channelId
cmdPrefix блокирующий channelId режим
ПРИМЕЧАНИЯ
ПРИМЕР
СМОТРИ ТАКЖЕ
КЛЮЧЕВЫЕ СЛОВА

Имя

refchan — обработчик команд API отражённых каналов

Синтаксис

cmdPrefix параметр ?аргумент аргумент ...?

Описание

Обработчик на уровне Tcl для отражённого канала должен быть командой с подкомандами (называемой ансамблем, так как это команда, такая как созданная командой namespace ensembleсоздать, хотя реализация обработчиков отражённых каналов не связана с namespace ensemble никоим образом; см. ПРИМЕР ниже, как создать oo::class, который поддерживает API). Обратите внимание, что cmdPrefix — это то, что было указано в вызове chan create и может состоять из нескольких аргументов; это будет расширено до нескольких слов вместо префикса.

Из всех возможных подкоманд, обработчик должен поддерживать инициализировать, завершить и наблюдать. Поддержка других подкоманд является необязательной.

Обязательные подкоманды

cmdPrefix инициализировать channelId режим
Вызов этой подкоманды будет первым вызовом cmdPrefix для указанного нового channelId. Ответственность этой подкоманды — настроить любые внутренние структуры данных, необходимые для отслеживания канала и его состояния.

Значение возвращаемое методом должно быть списком, содержащим имена всех подкоманд, поддерживаемых cmdPrefix. Это также сообщает ядру Tcl, какая версия API для отражённых каналов используется этим обработчиком команд.

Любая ошибка, сгенерированная методом, прервёт создание канала, и канал не будет создан. Выброшенная ошибка будет отображаться как ошибка, выброшенная командой chan create. Любая исключительная ситуация, кроме error (например, break и т.д.) рассматривается как (и преобразуется в) ошибку.

Примечание: Если создание канала было прервано из-за ошибок здесь, то подкоманда завершить не будет вызвана.

Аргумент режим сообщает обработчику, был ли канал открыт для чтения, записи или обоих. Он представляет собой список, содержащий любые из строк read или write. Список всегда будет содержать по крайней мере один элемент.

Подкоманда должна выбросить ошибку, если выбранный режим не поддерживается cmdPrefix.

cmdPrefix завершить channelId
Вызов этой подкоманды будет последним вызовом cmdPrefix для указанного channelId. Он будет сгенерирован непосредственно перед уничтожением структур данных канала, удерживаемых ядром Tcl. Обработчик команд не должен больше никак обращаться к channelId. После вызова этой подкоманды все внутренние ресурсы, выделенные для этого канала, должны быть очищены.

Возвращаемое значение этой подкоманды игнорируется.

Если подкоманда выбросит ошибку, команда, которая вызвала её выполнение (обычно chan close), будет отображать эту ошибку. Любые исключительные ситуации, помимо error (например, break и т.д.) рассматриваются как (и преобразуются в) ошибки.

Эта подкоманда не вызывается, если создание канала было прервано во время инициализировать (см. выше).

cmdPrefix наблюдать channelId событие
Эта подкоманда уведомляет cmdPrefix, что указанный channelId заинтересован в событиях, перечисленных в eventspec. Этот аргумент — список, содержащий любое из read и write. Список может быть пустым, что сигнализирует о том, что канал не хочет быть уведомлён о каких-либо событиях. В этом случае обработчик должен полностью отключить генерацию событий.

Предупреждение: Любое возвращаемое значение подкоманды игнорируется. Это включает все ошибки, выброшенные подкомандой, break, continue и пользовательские коды возврата.

Эта подкоманда взаимодействует с chan postevent. Попытка отправить событие, которое не было указано в последнем вызове наблюдать, приведёт к тому, что chan postevent выбросит ошибку.

Необязательные подкоманды

cmdPrefix read channelId count
Этот необязательный подкоманда вызывается, когда пользователь запрашивает данные из канала channelId. count указывает, сколько байтов запрошено. Если подкоманда не поддерживается, то невозможно читать из канала, управляемого командой.

Возвращаемое значение этой подкоманды принимается как запрашиваемые данные байты. Если возвращаемые данные содержат больше байтов, чем запрошено, будет сигнализировано и позже выброшено ошибку командой, выполнившей чтение (обычно gets или read). Однако возвращение меньше байтов, чем запрошено, допустимо.

Обратите внимание, что возвращение ничего (0 байт) является сигналом для верхних уровней о том, что EOF достигнут в канале. Чтобы сигнализировать о том, что канал пуст прямо сейчас, но еще не достиг EOF, необходимо выбросить ошибку "EAGAIN", т.е. либо

return -code error EAGAIN
или
error EAGAIN

Для расширяемости любая ошибка, значение которой является отрицательным целым числом, заставит верхние уровни установить переменную C-уровня "errno" в абсолютное значение этого числа, сигнализируя об ошибке системы. Однако обратите внимание, что точное соответствие между этими номерами ошибок и их значениями зависит от операционной системы.

Например, в Linux оба

return -code error -11
и
error -11

эквивалентны приведенным выше примерам, используя более удобочитаемую строку "EAGAIN", но это неверно для BSD, где эквивалентное число равно -35.

Символьная строка, однако, одинакова во всех системах и внутренне преобразуется в правильное число. Никакое другое значение ошибки не имеет такого соответствия со строкой символа.

Если подкоманда выбросит любую другую ошибку, команда, вызвавшая её выполнение (обычно gets или read), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

cmdPrefix write channelId data
Эта необязательная подкоманда вызывается, когда пользователь записывает данные в канал channelId. Аргумент data содержит байты, а не символы. Любые типы преобразований (EOL, кодирование), настроенные для канала, уже применены на этом этапе. Если эта подкоманда не поддерживается, то запись в канал, управляемый командой, невозможна.

Возвращаемое значение подкоманды принимается как количество записанных байтов каналом. Любое нечисловое значение вызовет ошибку, которая будет сигнализирована и позже выброшена командой, выполнившей запись. Отрицательное значение означает, что запись не удалась. Возвращение значения, большего, чем количество переданных байтов, или нуля, запрещено и приведёт к ошибке ядра Tcl.

Чтобы сигнализировать о том, что канал в данный момент не может принимать данные на запись, необходимо выбросить ошибку "EAGAIN", т.е. либо

return -code error EAGAIN
или
error EAGAIN

Для расширяемости любая ошибка, значение которой является отрицательным целым числом, заставит верхние уровни установить переменную C-уровня "errno" в абсолютное значение этого числа, сигнализируя об ошибке системы. Однако обратите внимание, что точное соответствие между этими номерами ошибок и их значениями зависит от операционной системы.

Например, в Linux оба

return -code error -11
и
error -11

эквивалентны приведенным выше примерам, используя более удобочитаемую строку "EAGAIN", но это неверно для BSD, где эквивалентное число равно -35.

Символьная строка, однако, одинакова во всех системах и внутренне преобразуется в правильное число. Никакое другое значение ошибки не имеет такого соответствия со строкой символа.

Если подкоманда выбросит любую другую ошибку, команда, вызвавшая её выполнение (обычно puts), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

cmdPrefix seek channelId offset base
Эта необязательная подкоманда отвечает за обработку запросов chan seek и chan tell в канале channelId. Если она не поддерживается, поиск по каналу невозможен.

Аргумент base такой же, как и соответствующий аргумент встроенной команды chan seek, а именно:

start
Поиск ведётся относительно начала канала.
current
Поиск ведётся относительно текущей позиции поиска.
end
Поиск ведётся относительно конца канала.

offset — целое число, определяющее количество байтов для поиска вперёд или назад. Положительное число означает поиск вперёд, отрицательное — назад. Каналы могут поддерживать ограниченный поиск. Например, сокеты могут искать вперёд, но не назад.

Возвращаемое значение подкоманды принимается как (новая) позиция канала, отсчитываемая от начала. Это должно быть целое число, большее или равное нулю. Если подкоманда выбросит ошибку, то команда, вызвавшая её выполнение (обычно chan seek или chan tell), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

Сочетание смещения/основания 0/current сигнализирует о запросе chan tell, т.е. не производит поиск относительно текущей позиции, оставляя новую позицию такой же, как текущая, которая и возвращается.

cmdPrefix configure channelId option value
Эта необязательная подкоманда предназначена для установки опций, специфичных для типа канала channelId. Аргумент option указывает опцию для записи, а аргумент value указывает значение, к которому необходимо установить опцию.

Эта подкоманда никогда не будет пытаться обновить более одной опции за раз; это поведение реализовано в ядре канала Tcl.

Возвращаемое значение подкоманды игнорируется.

Если подкоманда выбросит ошибку, то команда, которая выполнила (пере)настройку или запрос (обычно fconfigure или chan configure), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

cmdPrefix cget channelId option
Эта необязательная подкоманда используется при чтении одной опции, специфичной для типа канала channelId. Если эта подкоманда поддерживается, то подкоманда cgetall также должна поддерживаться.

Подкоманда должна вернуть значение указанной опции option.

Если подкоманда выбросит ошибку, команда, которая выполнила (пере)настройку или запрос (обычно fconfigure или chan configure), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

cmdPrefix cgetall channelId
Эта необязательная подкоманда используется для чтения всех опций, специфичных для типа канала channelId. Если эта подкоманда поддерживается, то подкоманда cget также должна поддерживаться.

Подкоманда должна вернуть список всех опций и их значений. Этот список должен иметь чётное количество элементов.

Если подкоманда выбросит ошибку, команда, которая выполнила (пере)настройку или запрос (обычно fconfigure или chan configure), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

cmdPrefix blocking channelId mode
Эта необязательная подкоманда обрабатывает изменения режима блокировки канала channelId. mode — логический флаг. Значение true означает, что канал должен быть установлен в блокирующий режим, а значение false — в режим без блокировки.

Возвращаемое значение подкоманды игнорируется.

Если подкоманда выбросит ошибку, команда, которая вызвала её выполнение (обычно fconfigure или chan configure), будет отображать эту ошибку. Любое исключение, выходящее за рамки error (например, break и т. д.), рассматривается как ошибка и преобразуется в неё.

Примечания

Некоторые функции, поддерживаемые в каналах, определённых в C-интерфейсе Tcl, недоступны каналам, отображённым на уровне Tcl.

Функция Tcl_DriverGetHandleProc не поддерживается; т.е., отображённые каналы не имеют специфичных для ОС дескрипторов.

Функция Tcl_DriverHandlerProc не поддерживается. Эта функция драйвера актуальна только для каналов со стеком, т.е. преобразований. Отображённые каналы всегда являются базовыми каналами, а не преобразованиями.

Функция Tcl_DriverFlushProc не поддерживается. Это связано с тем, что текущий универсальный уровень ввода-вывода Tcl не использует эту функцию. Поэтому поддержка на уровне Tcl также не имеет смысла. Это может быть изменено в будущем (через расширение API, определённого здесь, и изменение его версии), если функция будет использоваться в будущем.

Пример

Здесь показано, как создать канал, который читает данные из строки.
oo::class create stringchan {
    variable data pos
    constructor {string {encoding {}}} {
        if {$encoding eq ""} {set encoding [encoding system]}
        set data [encoding convertto $encoding $string]
        set pos 0
    }

    method initialize {ch mode} {
        return "initialize finalize watch read seek"
    }
    method finalize {ch} {
        my destroy
    }
    method watch {ch events} {
        # Must be present but we ignore it because we do not
        # post any events
    }

    # Must be present on a readable channel
    method read {ch count} {
        set d [string range $data $pos [expr {$pos+$count-1}]]
        incr pos [string length $d]
        return $d
    }

    # This method is optional, but useful for the example below
    method seek {ch offset base} {
        switch $base {
            start {
                set pos $offset
            }
            current {
                incr pos $offset
            }
            end {
                set pos [string length $data]
                incr pos $offset
            }
        }
        if {$pos < 0} {
            set pos 0
        } elseif {$pos > [string length $data]} {
            set pos [string length $data]
        }
        return $pos
    }
}

# Now we create an instance...
set string "The quick brown fox jumps over the lazy dog.\n"
set ch [chan create read [stringchan new $string]]

puts [gets $ch];   # Prints the whole string

seek $ch -5 end;
puts [read $ch];   # Prints just the last word

См. также

chan, transchan

Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/refchan.htm

Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/refchan.htm

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API