///|
/// Parsed PDF header version.
///
/// The fields correspond to the digits in a `%PDF-major.minor` header.
pub(all) struct PdfVersion {
major : Int
minor : Int
} derive(Debug, Eq, ToJson)
///|
/// Fallback version used when a PDF header cannot be found.
pub let pdf_default_version : PdfVersion = { major: 2, minor: 0, }
///|
fn pdf_header_at(cursor : @core.ByteCursor, position : Int) -> PdfVersion? {
let header : Result[BytesView, Error] = try
cursor.view_at_absolute(position, 8)
catch {
err => Err(err)
} noraise {
value => Ok(value)
}
match header {
Ok(header) =>
if header[0].to_int() == 37 &&
header[1].to_int() == 80 &&
header[2].to_int() == 68 &&
header[3].to_int() == 70 &&
header[4].to_int() == 45 &&
header[6].to_int() == 46 {
let major = header[5].to_int()
let minor = header[7].to_int()
if @core.pdf_is_digit_byte(major) && @core.pdf_is_digit_byte(minor) {
Some({ major: major - 48, minor: minor - 48, })
} else {
None
}
} else {
None
}
Err(_) => None
}
}
///|
fn pdf_header_probe_length(length : Int) -> Int {
if length < 1024 {
length
} else {
1024
}
}
///|
fn pdf_finish_header_at(
cursor : @core.ByteCursor,
position : Int,
version : PdfVersion,
) -> PdfVersion raise @core.PdfError {
cursor.set_offset(position)
cursor.seek_absolute(position + 8)
version
}
///|
/// Read the PDF header from the current cursor buffer.
///
/// The reader probes the first 1024 bytes for `%PDF-x.y`. When found, the cursor
/// offset is set to the header position and the cursor advances past the header.
/// If no header is found, `pdf_default_version` is returned.
pub fn pdf_read_header_from_cursor(
cursor : @core.ByteCursor,
) -> PdfVersion raise @core.PdfError {
let max_probe = pdf_header_probe_length(cursor.length())
for position in 0..<=max_probe {
match pdf_header_at(cursor, position) {
Some(version) => break pdf_finish_header_at(cursor, position, version)
None => ()
}
} nobreak {
pdf_default_version
}
}
///|
/// Read a PDF header version from a borrowed byte view.
pub fn pdf_read_header_from_view(
data : BytesView,
) -> PdfVersion raise @core.PdfError {
pdf_read_header_from_cursor(@core.byte_cursor_of_view(data))
}
///|
/// Read a PDF header version from owned PDF bytes.
pub fn pdf_read_header_from_bytes(
data : @core.PdfBytes,
) -> PdfVersion raise @core.PdfError {
pdf_read_header_from_view(data)
}