///|
/// Stream descriptor when bytes are not yet materialized.
pub(all) struct ToGet {
input : @pdfio.Input
position : Int
length : Int
crypt : ToGetCrypt
}
///|
pub fn ToGet::new(
input : @pdfio.Input,
position : Int,
length : Int,
crypt? : ToGetCrypt = ToGetCrypt::NoChange,
) -> ToGet {
{ input, position, length, crypt }
}
///|
pub fn ToGet::length(self : ToGet) -> Int {
self.length
}
///|
/// Stream payload, either in memory or deferred.
pub(all) enum Stream {
Got(@pdfio.MutableBytes)
ToGet(ToGet)
}
///|
/// Get a stream from disk if it hasn't already been got.
fn process_deferred_cryption(
crypt : ToGetCrypt,
data : @pdfio.MutableBytes,
) -> @pdfio.MutableBytes raise {
match crypt {
ToGetCrypt::NoChange => data
ToGetCrypt::ToDecrypt(saved) =>
@pdfcryptprimitives.PdfCryptPrimitives::new().decrypt_stream_data(
saved.crypt_type,
false,
saved.file_encryption_key,
saved.obj,
saved.gen,
saved.key,
saved.keylength,
saved.r,
data,
)
}
}
///|
/// Get a stream from disk if it hasn't already been got.
pub fn PdfObject::getstream(self : PdfObject) -> Unit raise {
match self {
Stream(r) =>
match r.val {
(dict, Stream::ToGet(toget)) => {
let data = try {
let raw = toget.input.bytes_of_input(toget.position, toget.length)
process_deferred_cryption(toget.crypt, raw)
} catch {
_ => raise PdfError::Msg("getstream: can't read stream")
}
let dict_updated = match dict {
Dictionary(_) =>
dict.replace_entry("/Length", Integer(@pdfio.bytes_size(data)))
_ => dict
}
r.val = (dict_updated, Stream::Got(data))
}
_ => ()
}
_ => raise PdfError::Msg("getstream: not a stream")
}
}
///|
/// Find the contents of a stream as bytes.
pub fn PdfObject::bigarray_of_stream(
self : PdfObject,
) -> @pdfio.MutableBytes raise {
self.getstream()
match self {
Stream(r) =>
match r.val {
(_, Stream::Got(bytes)) => bytes
_ => raise PdfError::Msg("couldn't extract raw stream")
}
_ => raise PdfError::Msg("couldn't extract raw stream")
}
}