Skip to content

Commit

Permalink
Read previous Xrefs of linearized or incremental updated document
Browse files Browse the repository at this point in the history
  • Loading branch information
J-F-Liu committed Feb 16, 2017
1 parent fff5f50 commit b2985d6
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "lopdf"
version = "0.5.0"
version = "0.6.0"
authors = ["Junfeng Liu <[email protected]>"]
homepage = "https://github.com/J-F-Liu/lopdf"
documentation = "https://docs.rs/crate/lopdf/"
Expand All @@ -10,7 +10,7 @@ readme = "README.md"
description = "A Rust library for PDF document manipulation."

[dependencies]
pom = "0.9.0"
pom = "1.0.0"
flate2 = "0.2.14"
linked-hash-map = "0.3.0"

Expand Down
12 changes: 12 additions & 0 deletions src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ impl Object {
_ => None
}
}

pub fn type_name(&self) -> Option<&str> {
match *self {
Object::Dictionary(ref dict) => dict.type_name(),
Object::Stream(ref stream) => stream.dict.type_name(),
_ => None
}
}
}

impl Dictionary {
Expand Down Expand Up @@ -176,6 +184,10 @@ impl Dictionary {
self.0.remove(&key.into())
}

pub fn type_name(&self) -> Option<&str> {
self.0.get("Type").and_then(|obj|obj.as_name()).or(self.0.get("Linearized").and(Some("Linearized")))
}

pub fn type_is(&self, type_name: &str) -> bool {
self.0.get("Type").and_then(|obj|obj.as_name()) == Some(type_name)
}
Expand Down
12 changes: 11 additions & 1 deletion src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,19 @@ impl Reader {
let xref_start = Self::get_xref_start(&self.buffer, &mut input)?;
input.jump_to(xref_start);

let (xref, trailer) = parser::xref_and_trailer(&self).parse(&mut input)
let (mut xref, mut trailer) = parser::xref_and_trailer(&self).parse(&mut input)
.map_err(|_|Error::new(ErrorKind::InvalidData, "Not a valid PDF file (xref_and_trailer)."))?;

// Read previous Xrefs of linearized or incremental updated document.
let mut prev_xref_start = trailer.remove("Prev");
while let Some(prev) = prev_xref_start.and_then(|offset|offset.as_i64()) {
input.jump_to(prev as usize);
let (prev_xref, mut prev_trailer) = parser::xref_and_trailer(&self).parse(&mut input)
.map_err(|_|Error::new(ErrorKind::InvalidData, "Not a valid PDF file (prev xref_and_trailer)."))?;
xref.extend(prev_xref);
prev_xref_start = prev_trailer.remove("Prev");
}

self.document.version = version;
self.document.max_id = xref.size - 1;
self.document.trailer = trailer;
Expand Down
2 changes: 1 addition & 1 deletion src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl Document {
file.write_all(format!("%PDF-{}\n", self.version).as_bytes())?;

for (&(id, generation), object) in &self.objects {
if object.as_dict().map(|dict| dict.type_is("ObjStm")) != Some(true) {
if object.type_name().map(|name| ["ObjStm", "XRef", "Linearized"].contains(&name)) != Some(true) {
Writer::write_indirect_object(&mut file, id, generation, object, &mut xref)?;
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/xref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ impl Xref {
self.entries.insert(id, entry);
}

pub fn extend(&mut self, xref: Xref) {
self.entries.extend(xref.entries);
}

pub fn clear(&mut self) {
self.entries.clear()
}
Expand Down Expand Up @@ -106,6 +110,8 @@ pub fn decode_xref_stream(mut stream: Stream) -> (Xref, Dictionary) {
}
}
dict.remove("Length");
dict.remove("W");
dict.remove("Index");
(xref, dict)
}

Expand Down

0 comments on commit b2985d6

Please sign in to comment.