diff --git a/src/UglyToad.PdfPig.sln.DotSettings b/src/UglyToad.PdfPig.sln.DotSettings
new file mode 100644
index 00000000..39e42e16
--- /dev/null
+++ b/src/UglyToad.PdfPig.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ XY
\ No newline at end of file
diff --git a/src/UglyToad.PdfPig/DocumentLayoutAnalysis/XYNode.cs b/src/UglyToad.PdfPig/DocumentLayoutAnalysis/XYNode.cs
index 70620807..db423c55 100644
--- a/src/UglyToad.PdfPig/DocumentLayoutAnalysis/XYNode.cs
+++ b/src/UglyToad.PdfPig/DocumentLayoutAnalysis/XYNode.cs
@@ -25,29 +25,6 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
///
public XYNode[] Children { get; set; }
- ///
- /// Recursively counts the words included in this node.
- ///
- public virtual int CountWords()
- {
- if (Children == null) return 0;
- int count = 0;
- RecursiveCount(Children, ref count);
- return count;
- }
-
- ///
- /// Recursively gets the leafs (last nodes) of this node.
- ///
- public virtual List GetLeafs()
- {
- List leafs = new List();
- if (Children == null || Children.Count() == 0) return leafs;
- int level = 0;
- RecursiveGetLeafs(Children, ref leafs, level);
- return leafs;
- }
-
///
/// Create a new .
///
@@ -79,6 +56,37 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
}
}
+ ///
+ /// Recursively counts the words included in this node.
+ ///
+ public virtual int CountWords()
+ {
+ if (Children == null)
+ {
+ return 0;
+ }
+
+ int count = 0;
+ RecursiveCount(Children, ref count);
+ return count;
+ }
+
+ ///
+ /// Recursively gets the leafs (last nodes) of this node.
+ ///
+ public virtual List GetLeafs()
+ {
+ List leafs = new List();
+ if (Children == null || Children.Length == 0)
+ {
+ return leafs;
+ }
+
+ int level = 0;
+ RecursiveGetLeafs(Children, ref leafs, level);
+ return leafs;
+ }
+
private void RecursiveCount(IEnumerable children, ref int count)
{
if (children.Count() == 0) return;
@@ -122,9 +130,10 @@ namespace UglyToad.PdfPig.DocumentLayoutAnalysis
}
}
+ ///
public override string ToString()
{
- return (IsLeaf ? "Leaf" : "Node");
+ return IsLeaf ? "Leaf" : "Node";
}
}
}
diff --git a/src/UglyToad.PdfPig/Encryption/EncryptionDictionaryFactory.cs b/src/UglyToad.PdfPig/Encryption/EncryptionDictionaryFactory.cs
index 735e1d4f..616545d9 100644
--- a/src/UglyToad.PdfPig/Encryption/EncryptionDictionaryFactory.cs
+++ b/src/UglyToad.PdfPig/Encryption/EncryptionDictionaryFactory.cs
@@ -73,11 +73,8 @@
byte[] userEncryptionBytes = null, ownerEncryptionBytes = null;
if (revision >= 5)
{
- var oe = encryptionDictionary.Get(NameToken.Oe, tokenScanner);
- var ue = encryptionDictionary.Get(NameToken.Ue, tokenScanner);
-
- ownerEncryptionBytes = OtherEncodings.StringAsLatin1Bytes(oe.Data);
- userEncryptionBytes = OtherEncodings.StringAsLatin1Bytes(ue.Data);
+ ownerEncryptionBytes = GetEncryptionBytesOrDefault(encryptionDictionary, tokenScanner, false);
+ userEncryptionBytes = GetEncryptionBytesOrDefault(encryptionDictionary, tokenScanner, true);
}
encryptionDictionary.TryGetOptionalTokenDirect(NameToken.EncryptMetaData, tokenScanner, out BooleanToken encryptMetadata);
@@ -89,5 +86,21 @@
encryptionDictionary,
encryptMetadata?.Data ?? true);
}
+
+ private static byte[] GetEncryptionBytesOrDefault(DictionaryToken encryptionDictionary, IPdfTokenScanner tokenScanner, bool isUser)
+ {
+ var name = isUser ? NameToken.Ue : NameToken.Oe;
+ if (encryptionDictionary.TryGet(name, tokenScanner, out StringToken stringToken))
+ {
+ return OtherEncodings.StringAsLatin1Bytes(stringToken.Data);
+ }
+
+ if (encryptionDictionary.TryGet(name, tokenScanner, out HexToken hexToken))
+ {
+ return hexToken.Bytes.ToArray();
+ }
+
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/src/UglyToad.PdfPig/Tokens/DictionaryToken.cs b/src/UglyToad.PdfPig/Tokens/DictionaryToken.cs
index b8552707..6417e943 100644
--- a/src/UglyToad.PdfPig/Tokens/DictionaryToken.cs
+++ b/src/UglyToad.PdfPig/Tokens/DictionaryToken.cs
@@ -77,6 +77,26 @@
return Data.TryGetValue(name.Data, out token);
}
+ ///
+ /// Try and get the entry with a given name and type or look-up the object if it's an indirect reference.
+ ///
+ internal bool TryGet(NameToken name, IPdfTokenScanner tokenScanner, out T token) where T : IToken
+ {
+ token = default(T);
+ if (!TryGet(name, out var t) || !(t is T typedToken))
+ {
+ if (t is IndirectReferenceToken reference)
+ {
+ return DirectObjectFinder.TryGet(reference, tokenScanner, out token);
+ }
+
+ return false;
+ }
+
+ token = typedToken;
+ return true;
+ }
+
///
/// Try and get the entry with a given name and a specific data type.
///