///|
fn pdf_tweak_replace_array_entry(
values : ArrayView[@syntax.PdfObject],
index : Int,
value : @syntax.PdfObject,
source : String,
) -> @syntax.PdfObject raise @core.PdfError {
if index < 0 || index >= values.length() {
raise BadPageSpecification(source)
}
PdfArray(
[
for i in 0.. if i == index { value } else { values[i] }
],
)
}
///|
fn pdf_tweak_chain_array_index(name : @core.PdfName) -> Int? {
let bytes = name.bytes()
guard bytes.length() >= 3 &&
bytes[0].to_int() == 47 &&
bytes[1].to_int() == 91 else {
return None
}
guard pdf_tweak_is_digit_byte(bytes[2]) else { return None }
let mut value = 0
let mut index = 2
while index < bytes.length() && pdf_tweak_is_digit_byte(bytes[index]) {
value = value * 10 + bytes[index].to_int() - 48
index += 1
}
Some(value)
}
///|
fn PdfDocument::pdf_tweak_replace_existing_chain(
self : PdfDocument,
object : @syntax.PdfObject,
chain : ArrayView[@core.PdfName],
chain_index : Int,
value : @syntax.PdfObject,
source : String,
) -> @syntax.PdfObject raise @core.PdfError {
let key = chain[chain_index]
let final_key = chain_index + 1 == chain.length()
match object {
PdfDictionary(_) | PdfStreamObject(_) =>
if final_key {
match object.lookup_immediate(key) {
Some(_) => object.replace_dict_entry(key, value)
None => raise BadPageSpecification(source)
}
} else {
match object.lookup_immediate(key) {
Some(PdfIndirect(number)) => {
let updated = self.pdf_tweak_replace_existing_chain(
self.lookup_object_or_null(number),
chain,
chain_index + 1,
value,
source,
)
self.add_object_given_number(number, updated)
object
}
Some(child) => {
let updated = self.pdf_tweak_replace_existing_chain(
child,
chain,
chain_index + 1,
value,
source,
)
object.replace_dict_entry(key, updated)
}
None => raise BadPageSpecification(source)
}
}
PdfArray(values) =>
match pdf_tweak_chain_array_index(key) {
Some(index) =>
if final_key {
pdf_tweak_replace_array_entry(values, index, value, source)
} else {
match values.get(index) {
Some(PdfIndirect(number)) => {
let updated = self.pdf_tweak_replace_existing_chain(
self.lookup_object_or_null(number),
chain,
chain_index + 1,
value,
source,
)
self.add_object_given_number(number, updated)
object
}
Some(child) => {
let updated = self.pdf_tweak_replace_existing_chain(
child,
chain,
chain_index + 1,
value,
source,
)
pdf_tweak_replace_array_entry(values, index, updated, source)
}
None => raise BadPageSpecification(source)
}
}
None => raise BadPageSpecification(source)
}
_ => raise BadPageSpecification(source)
}
}
///|
fn PdfDocument::pdf_tweak_replace_numbered_object(
self : PdfDocument,
number : Int,
chain : ArrayView[@core.PdfName],
value : @syntax.PdfObject,
source : String,
) -> Unit raise @core.PdfError {
if chain.length() == 0 {
if number == 0 {
self.set_trailer_dict(value)
} else {
self.add_object_given_number(number, value)
}
} else {
let object = if number == 0 {
self.trailer_dict()
} else {
self.lookup_object_or_null(number)
}
let updated = self.pdf_tweak_replace_existing_chain(
object, chain, 0, value, source,
)
if number == 0 {
self.set_trailer_dict(updated)
} else {
self.add_object_given_number(number, updated)
}
}
}