Реестр пользовательских stream filter

HotPDF умеет декодировать определённые приложением stream filter PDF внутри того же ограниченного конвейера, что и встроенные декодеры Flate, LZW, ASCII85, ASCIIHex и RunLength

Регистрация push- или pull-фильтров

Реализуйте IHPDFCustomStreamFilter, выберите csfmPush или csfmPull и зарегистрируйте интерфейс через THotPDF.RegisterCustomStreamFilter

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

Поиск в реестре берёт снимок интерфейса под короткой критической секцией; callback фильтра и разрушение интерфейса выполняются вне блокировки реестра

Один бюджет на все стадии

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

THPDFCustomStreamFilterRequest.MaxOutputBytes сообщает остаток лимита на цепочку, а ноль означает, что настроенный бюджет цепочки не ограничен

Запрос также несёт декодированное имя PDF-фильтра, стадию с нуля, глубину конвейера, размер ввода, когда он доступен, и cancellation token вызывающего

Отмена и seek-контракты

Перегрузка DecodeLoadedStreamToStream с поддержкой отмены проверяется до и после выполнения пользовательской стадии и во время передачи pull stream

Пользовательские реализации должны проверять Request.CancellationToken внутри длинных push-циклов или блокирующей внешней работы

csscSeekable объявляет, что заёмный ввод, push-приёмник или возвращённый pull stream должны поддерживать seek; нарушение контракта даёт dpsSeekContractViolation

Изоляция сбоев

Каждая пользовательская стадия пишет в ограниченный THPDFAdaptiveTempStream, прежде чем какие-либо байты уйдут на следующую стадию или в назначение вызывающего

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

Успешный pull filter передаёт владение возвращённым stream самому HotPDF; возврат заёмного ввода или nil stream отвергается

Телеметрия

GetCustomStreamFilterStatistics сообщает зарегистрированные имена, попытки push и pull, успехи, отказы, счётчики отмен и нарушений seek, суммарные входные и произведённые байты, а также последнее имя и диагностику

THPDFDecodePipelineInfo.CustomFilterCount и CustomFilterFailureCount описывают текущую цепочку

Пример

Filter := TApplicationFilter.Create;
PDF.RegisterCustomStreamFilter(Filter);
try
  if not PDF.DecodeLoadedStreamToStream(StreamObject, Output,
    CancellationToken, Info) then
    HandleDecodeFailure(Info.Status, Info.Diagnostic);
finally
  PDF.UnregisterCustomStreamFilter(Filter.FilterName);
end;

Связанные API