Skip to content

Commit

Permalink
GH-233 partially working recursive document write, plus or minus a fe…
Browse files Browse the repository at this point in the history
…w objects.
  • Loading branch information
Patrick Corless committed Jun 1, 2023
1 parent a5f7a13 commit 57098fa
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ public int getInt(Name key) {
return library.getInt(entries, key);
}

public Reference getReference(Name key) {
Object o = entries.get(key);
if (o instanceof Reference) {
return (Reference) o;
}
return null;
}

public List getList(Name key) {
Object o = getObject(key);
if (o instanceof List) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ private void setInputStream(ByteBuffer input)
input = header.parseHeader(input);

library.setDocumentByteBuffer(input);
library.setFileVersion(header.getVersion());
library.setFileHeader(header);

// create instance of CrossReferenceRoot as we may need it the trailer can't be correctly decoded.
crossReferenceRoot = new CrossReferenceRoot(library);
Expand All @@ -366,13 +366,13 @@ private void setInputStream(ByteBuffer input)
crossReferenceRoot.initialize(input);
library.setCrossReferenceRoot(crossReferenceRoot);
} catch (Exception e) {
crossReferenceRoot.setLazyInitializationFailed(true);
crossReferenceRoot.setInitializationFailed(true);
logger.log(Level.WARNING, "Cross reference loading failed, reindexing file.", e);
}
}

// linear traversal of file.
if (trailer.isLazyInitializationFailed() || crossReferenceRoot.isLazyInitializationFailed()) {
if (trailer.isLazyInitializationFailed() || crossReferenceRoot.isInitializationFailed()) {
crossReferenceRoot = library.rebuildCrossReferenceTable();
library.setCrossReferenceRoot(crossReferenceRoot);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ public Change getChange(Reference reference) {
if (change != null) {
return change;
} else {
logger.warning("No change object was found for " + reference);
return null;
}
}
Expand Down Expand Up @@ -233,7 +232,7 @@ else if (aron > bron)
}
}

protected enum Type {
public enum Type {
SYNTHETIC,
CHANGE,
DELETE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.icepdf.core.util.parser.object.ObjectLoader;

import java.io.IOException;
import java.util.HashMap;

public interface CrossReference {

Expand All @@ -18,6 +19,8 @@ PObject loadObject(ObjectLoader objectLoader, Reference reference, Name hint)
CrossReferenceEntry getEntry(Reference reference)
throws ObjectStateException, CrossReferenceStateException, IOException;

HashMap<Reference, CrossReferenceEntry> getEntries();

int getXrefStartPos();

DictionaryEntries getDictionaryEntries();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.icepdf.core.util.parser.object.Parser;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

/**
Expand All @@ -19,7 +20,7 @@ public abstract class CrossReferenceBase<T extends Dictionary> implements CrossR
public final T crossReference;

protected final ConcurrentHashMap<Reference, CrossReferenceEntry> indirectObjectReferences;
protected CrossReference prefCrossReference;
protected CrossReference prevCrossReference;

protected int xrefStartPos;

Expand All @@ -42,24 +43,34 @@ public CrossReferenceEntry getEntry(Reference reference) throws ObjectStateExcep
DictionaryEntries entries = crossReference.getEntries();
Library library = crossReference.getLibrary();
if (crossReferenceEntry == null && entries.get(PTrailer.PREV_KEY) != null) {
if (prefCrossReference != null) {
return prefCrossReference.getEntry(reference);
if (prevCrossReference != null) {
return prevCrossReference.getEntry(reference);
} else {
// try finding the entry in the previous table
Parser parser = new Parser(library);
synchronized (library.getMappedFileByteBufferLock()) {
CrossReference crossReference = parser.getCrossReference(
library.getMappedFileByteBuffer(), this.crossReference.getInt(PTrailer.PREV_KEY));
if (crossReference != null) {
prefCrossReference = crossReference;
return prefCrossReference.getEntry(reference);
prevCrossReference = crossReference;
return prevCrossReference.getEntry(reference);
}
}
}
}
return crossReferenceEntry;
}

public HashMap<Reference, CrossReferenceEntry> getEntries() {
HashMap<Reference, CrossReferenceEntry> completeIndirectReferences = new HashMap<>(indirectObjectReferences.size());
if (prevCrossReference != null) {
completeIndirectReferences.putAll(prevCrossReference.getEntries());
}
// current after previous so we get the most recent object
completeIndirectReferences.putAll(indirectObjectReferences);
return completeIndirectReferences;
}

public CrossReferenceEntry getEntryNoDescendents(Reference reference) {
return indirectObjectReferences.get(reference);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class CrossReferenceRoot {

private final ArrayList<CrossReference> crossReferences;

private boolean lazyInitializationFailed;
private boolean initializationFailed;

public CrossReferenceRoot(Library library) {
this.library = library;
Expand Down Expand Up @@ -115,12 +115,12 @@ public PObject loadObject(ObjectLoader objectLoader, Reference reference, Name h
return null;
}

public void setLazyInitializationFailed(boolean failed) {
lazyInitializationFailed = failed;
public void setInitializationFailed(boolean failed) {
initializationFailed = failed;
}

public boolean isLazyInitializationFailed() {
return lazyInitializationFailed;
public boolean isInitializationFailed() {
return initializationFailed;
}

public void addCrossReference(CrossReference crossReferenceTable) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package org.icepdf.core.pobjects.structure;

import org.icepdf.core.pobjects.*;
import org.icepdf.core.pobjects.structure.exceptions.CrossReferenceStateException;
import org.icepdf.core.pobjects.structure.exceptions.ObjectStateException;
import org.icepdf.core.pobjects.Dictionary;
import org.icepdf.core.pobjects.DictionaryEntries;
import org.icepdf.core.pobjects.Reference;
import org.icepdf.core.util.Library;
import org.icepdf.core.util.parser.object.ObjectLoader;

import java.io.IOException;

/**
*
Expand All @@ -17,15 +14,6 @@ public CrossReferenceTable(Library library, DictionaryEntries dictionaryEntries,
super(new Dictionary(library, dictionaryEntries), xrefStartPos);
}

@Override
public PObject loadObject(ObjectLoader objectLoader, Reference reference, Name hint)
throws ObjectStateException, CrossReferenceStateException, IOException {
if (reference != null) {
return objectLoader.loadObject(this, reference, hint);
}
return null;
}

public void addEntry(CrossReferenceEntry crossReferenceEntry) {
int generation;
if (crossReferenceEntry instanceof CrossReferenceUsedEntry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ByteBuffer parseHeader(ByteBuffer byteBuffer) {
if (matchPosition == matchLength) {
version = parseVersion(headerBuffer);
} else {
version = 0;
version = 1.0;
}

// check for some bad bytes
Expand Down Expand Up @@ -69,7 +69,7 @@ private static double parseVersion(ByteBuffer buffer) {
} catch (NumberFormatException e) {
// quite for now.
}
return 0;
return 1.0;
}

}
23 changes: 12 additions & 11 deletions core/core-awt/src/main/java/org/icepdf/core/util/Library.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.icepdf.core.pobjects.graphics.images.references.ImagePool;
import org.icepdf.core.pobjects.security.SecurityManager;
import org.icepdf.core.pobjects.structure.CrossReferenceRoot;
import org.icepdf.core.pobjects.structure.Header;
import org.icepdf.core.pobjects.structure.Indexer;
import org.icepdf.core.pobjects.structure.exceptions.CrossReferenceStateException;
import org.icepdf.core.pobjects.structure.exceptions.ObjectStateException;
Expand Down Expand Up @@ -57,8 +58,7 @@
*/
public class Library {

private static final Logger logger =
Logger.getLogger(Library.class.toString());
private static final Logger logger = Logger.getLogger(Library.class.toString());

protected static ThreadPoolExecutor commonThreadPool;
protected static ThreadPoolExecutor imageThreadPool;
Expand Down Expand Up @@ -95,7 +95,7 @@ public class Library {
private final ConcurrentHashMap<Reference, WeakReference<ICCBased>> lookupReference2ICCBased =
new ConcurrentHashMap<>(256);

private double fileVersion = 1.0;
private Header fileHeader;
private String fileOrigin;

private ByteBuffer mappedFileByteBuffer;
Expand Down Expand Up @@ -194,15 +194,15 @@ private Object getObject(Reference reference, Name hint) {
return ((PObject) obj).getObject();
} else if (obj instanceof Reference) {
Reference secondReference = (Reference) obj;
logger.log(Level.WARNING, () -> "Found a reference to a reference: " + secondReference);
logger.log(Level.WARNING, () -> "Found a reference to a reference: " + secondReference);
return getObject(secondReference);
}
return obj;
}

private boolean isSoftReferenceAble(Object object) {
if (object instanceof Dictionary) {
DictionaryEntries entries = ((Dictionary)object).getEntries();
DictionaryEntries entries = ((Dictionary) object).getEntries();
Name type = getName(entries, Dictionary.TYPE_KEY);
if (type != null) {
return type.equals(Font.TYPE) ||
Expand Down Expand Up @@ -359,12 +359,12 @@ public Object getMappedFileByteBufferLock() {
return mappedFileByteBufferLock;
}

public double getFileVersion() {
return fileVersion;
public Header getFileHeader() {
return fileHeader;
}

public void setFileVersion(double fileVersion) {
this.fileVersion = fileVersion;
public void setFileHeader(Header header) {
this.fileHeader = header;
}

/**
Expand Down Expand Up @@ -692,6 +692,7 @@ public Rectangle2D.Float getRectangle(DictionaryEntries dictionaryEntries, Name

/**
* Checks the given values for floats and resolves and References.
*
* @param values list of floats
* @return list of floats
*/
Expand All @@ -711,8 +712,8 @@ public List<Float> getFloatList(List<Object> values) {
private Float getFloatNumber(Object object) {
if (object instanceof Number) {
return ((Number) object).floatValue();
} else if (object instanceof Reference) {
return ((Number)getObject((Reference) object)).floatValue();
} else if (object instanceof Reference) {
return ((Number) getObject((Reference) object)).floatValue();
} else {
return null;
}
Expand Down
Loading

0 comments on commit 57098fa

Please sign in to comment.