THotPDF.DecodeLoadedStreamToStream 方法
通过其完整的过滤链解码一个已加载的 PDF 流,并将最终阶段直接写入由调用方拥有的流
声明
function DecodeLoadedStreamToStream(AStream: THPDFStreamObject; Output: TStream; out Info: THPDFDecodePipelineInfo): boolean;
单元
HPDFDoc
参数
| 名称 | 用途 |
|---|---|
AStream | 已加载的THPDFStreamObject,其 /Filter 条目将被解码 |
Output | 由调用方拥有的目标流,在其当前位置接收解码后的字节 |
CancellationToken | 可与自定义过滤器阶段共享的可选协作式取消令牌 |
Info | 接收输入和输出字节数、过滤器数量、深度、状态、失败的过滤器和诊断 |
返回值
仅当每个请求的阶段都成功时才返回 True,仅当每个请求的阶段都成功
用法说明
- 最终过滤器写入
Output,而不会创建第二个全尺寸的最终内存流 - 中间阶段使用
THPDFAdaptiveTempStream,超过LoadedStreamMemoryThreshold - 每个阶段都受
DecodeBudgetBytes限制,并且每个解码的字节也消耗DocumentDecodeBudgetBytes - ASCII85 要求精确的
~>结束标记,ASCIIHex 要求>;畸形的已加载管线会直接失败,而不是接受被截断的数据 DecodeFilterLimit在阶段分配之前拒绝过大的数组DecodePipelineDepthLimit、循环间接引用检测和同一流递归检测对恶意对象图进行限定- 源流位置在成功或失败之后都会被还原
- 已注册的
IHPDFCustomStreamFilter阶段共享同样的聚合预算和管线深度 - 自定义 push 和 pull 输出会先隔离在自适应临时流中,直到该自定义阶段成功
- 取消重载返回
dpsCancelled,而不是让EHPDFOperationCancelled - 失败的流式目标可能包含失败前已接受的字节;需要原子输出时,请使用临时目标
诊断
THPDFDecodePipelineInfo = record
Status: THPDFDecodePipelineStatus;
InputBytes: Int64;
OutputBytes: Int64;
FilterCount: Integer;
AppliedFilterCount: Integer;
PipelineDepth: Integer;
StopBeforeLast: Boolean;
FailedFilter: AnsiString;
Diagnostic: AnsiString;
end;
Status区分无效流与过滤器、过滤器数量与深度限制、循环引用、递归流、不受支持的过滤器、预算失败、解码器失败、自定义过滤器失败、取消以及 seek 契约违反
示例
Output := TFileStream.Create('payload.bin', fmCreate);
try
if not PDF.DecodeLoadedStreamToStream(StreamObject, Output, Info) then
raise Exception.Create(String(Info.Diagnostic));
finally
Output.Free;
end;