public ParseIndirectObject ParseIndirectObject() { Tokenizer.IgnoreComments = true; TokenObject t = Tokenizer.GetToken(); ThrowOnEmptyOrError(t); // Indirect object starts with an integer, the object identifier if (!(t is TokenInteger)) { Tokenizer.PushToken(t); return(null); } // Second is another integer, the generation number TokenObject u = Tokenizer.GetToken(); ThrowOnEmptyOrError(u); if (!(u is TokenInteger)) { Tokenizer.PushToken(t); Tokenizer.PushToken(u); return(null); } // This is the keyword 'obj' TokenObject v = Tokenizer.GetToken(); ThrowOnEmptyOrError(v); if (!(v is TokenKeyword) || ((v as TokenKeyword).Value != ParseKeyword.Obj)) { Tokenizer.PushToken(t); Tokenizer.PushToken(u); Tokenizer.PushToken(v); return(null); } // Get actual object that is the content ParseObjectBase obj = ParseObject(); if (obj == null) { throw new ApplicationException($"Indirect object has missing content."); } // Must be followed by either 'endobj' or 'stream' v = Tokenizer.GetToken(); ThrowOnEmptyOrError(v); TokenKeyword keyword = v as TokenKeyword; if (keyword == null) { // PH: FIXME: //throw new ApplicationException($"Indirect object has missing 'endobj or 'stream'."); return(new ParseIndirectObject(t as TokenInteger, u as TokenInteger, new ParseInteger(0))); } if (keyword.Value == ParseKeyword.EndObj) { return(new ParseIndirectObject(t as TokenInteger, u as TokenInteger, obj)); } else if (keyword.Value == ParseKeyword.Stream) { ParseDictionary dictionary = obj as ParseDictionary; if (dictionary == null) { throw new ApplicationException($"Stream must be preceded by a dictionary."); } if (!dictionary.ContainsName("Length")) { throw new ApplicationException($"Stream dictionary must contain a 'Length' entry."); } ParseObjectBase lengthObj = dictionary["Length"]; // Resolve any object reference ParseObjectReference reference = lengthObj as ParseObjectReference; if (reference != null) { lengthObj = OnResolveReference(reference); } ParseInteger length = lengthObj as ParseInteger; if (length == null) { throw new ApplicationException($"Stream dictionary has a 'Length' entry that is not an integer entry."); } if (length.Value < 0) { throw new ApplicationException($"Stream dictionary has a 'Length' less than 0."); } byte[] bytes = Tokenizer.GetBytes(length.Value); if (bytes == null) { throw new ApplicationException($"Cannot read in expected {length.Value} bytes from stream."); } // Stream contents must be followed by 'endstream' v = Tokenizer.GetToken(); ThrowOnEmptyOrError(v); keyword = v as TokenKeyword; if (keyword == null) { throw new ApplicationException($"Stream has missing 'endstream' after content."); } if (keyword.Value != ParseKeyword.EndStream) { throw new ApplicationException($"Stream has unexpected keyword {keyword.Value} instead of 'endstream'."); } // Stream contents must be followed by 'endobj' v = Tokenizer.GetToken(); ThrowOnEmptyOrError(v); keyword = v as TokenKeyword; if (keyword == null) { throw new ApplicationException($"Indirect object has missing 'endobj'."); } if (keyword.Value != ParseKeyword.EndObj) { throw new ApplicationException($"Indirect object has unexpected keyword {keyword.Value} instead of 'endobj'."); } return(new ParseIndirectObject(t as TokenInteger, u as TokenInteger, new ParseStream(dictionary, bytes))); } else { throw new ApplicationException($"Indirect object has unexpected keyword {keyword.Value}."); } }
public PdfInteger(PdfObject parent, ParseInteger integer) : base(parent, integer) { }