четверг, 7 апреля 2016 г.

Cache': перехват текущего устройства

Эта заметка описывает программный перехват ввода-вывода текущего устройства в Cache'. Неудобство стандартных устройств mumps, а точнее определенного их поведения состоит в том, что если выполняется программный код, осуществляющий ввод-вывод через него, то этот процесс сторонним кодом не управляем иначе как установкой возможных опций устройству. В то время как в некоторых случаях очень нужно иметь возможность выполнить так называемый унаследованный (legacy) код, который оперирует текущим устройством, но при этом в самих операциях ввода-вывода произвести дополнительные действия.


Ситуация примерно аналогична вводу-выводу в сишном стиле и в стиле C++, когда в первом случае мы можем открыть файл и передать его коду, а во втором случае мы можем создать объект ввода-вывода и переопределить для него операции чтения - записи.
Для перехвата операций ввода-вывода текущего устройства нужно
  1. Сделать отдельную рутину, в которой прописать функции, вызываемые при операциях ввода-вывода.
  2. Указать текущему устройству эту рутину как мнемоническую в команде use
  3. Включить перенаправление для текущего устройства
  4. В функциях переопределяющих операции ввода-вывода можно использовать штатное поведение текущего устройства если отключить перенаправление и при выходе из обработчика снова его включить.
Рутина-перехватчик должна реализовать на свое усмотрение метки

rstr(len,to)Чтение с опциональным указанием заданной длины и таймаута
rchr(to)Чтение номера символа
wstr(expr)Запись строки W expr
wchr(expr)Запись символа W *expr
wtab(expr)Запись пропуска W ?expr
wnlПеревод строки W !
wffОчистка экрана W #

Шаблон рутины примерно такой:

rstr(len,to)
 D $ZU(82,12,0)
 if $D(len)&&$D(to) d
 . ; перехват
 . R data#len:to
 e  i $D(len) d
 . ; перехват
 . R data#len
 e  i $D(to) d
 . ; перехват
 . R data:to
 e  d
 . ; перехват
 . R data 
 D $ZU(82,12,1)
 ; перехват
 Q $G(data)
rchr(to)
 D $ZU(82,12,0)
 i $d(to)
 . ; перехват
 . R *data:to
 . ; перехват
 e  d
 . ; перехват
 . R *data
 . ; перехват
 D $ZU(82,12,1)
 ; перехват
 Q data
 // W expr
wstr(expr) 
 D $ZU(82,12,0)
 ; перехват
 W expr
 D $ZU(82,12,1)
 Q
 // W *expr      
wchr(expr) 
 D $ZU(82,12,0)
 ; перехват
 W *expr
 D $ZU(82,12,1)
 Q
 // W ?expr
wtab(expr)
 D $ZU(82,12,0)
 ; перехват
 W ?expr
 D $ZU(82,12,1)
 Q
 // W !
wnl
 D $ZU(82,12,0)
 ; перехват
 W ! 
 D $ZU(82,12,1)
 Q
 // W #
wff
 D $ZU(82,12,0)
 ; перехват
 W # 
 D $ZU(82,12,1)
 Q  

После чего можно пользоваться, указывая перехватчик:

 u dev::"^ИМЯРУТИНЫ" ; указываем какую мнемонику использовать
 D $ZU(82,12,1)      ; реально включаем флаг использования
 d normal()          ; что будет писать в текущий девайс
 D $ZU(82,12,0)      ; перед закрытием девайса возвращаем флажок
 c dev

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

Комментариев нет:

Отправить комментарий