public CosBase Parse(ParsingArguments arguments, CosObject obj, bool requiresExistingObject) { return(Parse(arguments.Reader, obj, arguments.CachingProviders.ObjectPool, arguments.CrossReferenceTable, arguments.CachingProviders.BruteForceSearcher, arguments.IsLenientParsing, requiresExistingObject)); }
private static CosBase ParseTrailer(IRandomAccessRead reader, CrossReferenceTable crossReferenceTable, DynamicParser dynamicParser, BruteForceSearcher bruteForceSearcher, CosObjectPool pool, bool isLenientParsing) { foreach (var value in crossReferenceTable.Dictionary.Values) { if (value is CosObject temporaryObject) { // Loads these objects into the object pool for access later. dynamicParser.Parse(reader, temporaryObject, pool, crossReferenceTable, bruteForceSearcher, isLenientParsing, false); } } CosObject root = (CosObject)crossReferenceTable.Dictionary.GetItemOrDefault(CosName.ROOT); if (root == null) { throw new InvalidOperationException("Missing root object specification in trailer."); } var rootObject = dynamicParser.Parse(reader, root, pool, crossReferenceTable, bruteForceSearcher, isLenientParsing, false); return(rootObject); }
public IReadOnlyList <CosObject> Parse(PdfRawStream stream, CosObjectPool pool) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } //need to first parse the header. var numberOfObjects = stream.Dictionary.GetIntOrDefault(CosName.N); var objectNumbers = new List <long>(numberOfObjects); var streamObjects = new List <CosObject>(numberOfObjects); var bytes = stream.Decode(filterProvider); var reader = new RandomAccessBuffer(bytes); for (int i = 0; i < numberOfObjects; i++) { long objectNumber = ObjectHelper.ReadObjectNumber(reader); // skip offset ReadHelper.ReadLong(reader); objectNumbers.Add(objectNumber); } CosObject obj; CosBase cosObject; int objectCounter = 0; while ((cosObject = baseParser.Parse(reader, pool)) != null) { obj = new CosObject(cosObject); obj.SetGenerationNumber(0); if (objectCounter >= objectNumbers.Count) { log.Error("/ObjStm (object stream) has more objects than /N " + numberOfObjects); break; } obj.SetObjectNumber(objectNumbers[objectCounter]); streamObjects.Add(obj); // According to the spec objects within an object stream shall not be enclosed // by obj/endobj tags, but there are some pdfs in the wild using those tags // skip endobject marker if present if (!reader.IsEof() && reader.Peek() == 'e') { ReadHelper.ReadLine(reader); } objectCounter++; } return(streamObjects); }
public CosBase Parse(IRandomAccessRead reader, CosObject obj, CosObjectPool pool, CrossReferenceTable crossReferenceTable, BruteForceSearcher bruteForceSearcher, bool isLenient, bool requireExistingObject) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } return(Parse(reader, obj.GetObjectNumber(), obj.GetGenerationNumber(), pool, crossReferenceTable, bruteForceSearcher, isLenient, requireExistingObject)); }
public static CosBase Find <T>(CosObject baseObject, IPdfObjectParser parser, IRandomAccessRead reader, bool isLenientParsing) where T : CosBase { var result = parser.Parse(baseObject.ToIndirectReference(), reader, isLenientParsing); if (result is T resultT) { return(resultT); } if (result is CosObject obj) { return(Find <T>(obj, parser, reader, isLenientParsing)); } if (result is COSArray arr && arr.Count == 1 && arr.get(0) is CosObject arrayObject) { return(Find <T>(arrayObject, parser, reader, isLenientParsing)); } throw new InvalidOperationException($"Could not find the object {baseObject.ToIndirectReference()} with type {typeof(T).Name}."); }
private static bool TryGetFirstDescendant(PdfDictionary dictionary, out CosObject descendant) { descendant = null; if (!dictionary.TryGetValue(CosName.DESCENDANT_FONTS, out var value)) { return(false); } if (value is CosObject obj) { descendant = obj; return(true); } if (value is COSArray array && array.Count > 0 && array.get(0) is CosObject objArr) { descendant = objArr; return(true); } return(false); }
public CosBase Parse(IRandomAccessRead reader, CosObjectPool pool) { CosBase retval = null; ReadHelper.SkipSpaces(reader); int nextByte = reader.Peek(); if (nextByte == -1) { return(null); } char c = (char)nextByte; switch (c) { case '<': { // pull off first left bracket int leftBracket = reader.Read(); // check for second left bracket c = (char)reader.Peek(); reader.Unread(leftBracket); if (c == '<') { retval = dictionaryParser.Parse(reader, this, pool); ReadHelper.SkipSpaces(reader); } else { retval = stringParser.Parse(reader); } break; } case '[': { // array retval = arrayParser.Parse(reader, this, pool); break; } case '(': retval = stringParser.Parse(reader); break; case '/': // name retval = nameParser.Parse(reader); break; case 'n': { // null ReadHelper.ReadExpectedString(reader, "null"); retval = CosNull.Null; break; } case 't': { string truestring = OtherEncodings.BytesAsLatin1String(reader.ReadFully(4)); if (truestring.Equals("true")) { retval = PdfBoolean.True; } else { throw new IOException("expected true actual='" + truestring + "' " + reader + "' at offset " + reader.GetPosition()); } break; } case 'f': { string falsestring = OtherEncodings.BytesAsLatin1String(reader.ReadFully(5)); if (falsestring.Equals("false")) { retval = PdfBoolean.False; } else { throw new IOException("expected false actual='" + falsestring + "' " + reader + "' at offset " + reader.GetPosition()); } break; } case 'R': reader.Read(); retval = new CosObject(null); break; default: if (char.IsDigit(c) || c == '-' || c == '+' || c == '.') { StringBuilder buf = new StringBuilder(); int ic = reader.Read(); c = (char)ic; while (char.IsDigit(c) || c == '-' || c == '+' || c == '.' || c == 'E' || c == 'e') { buf.Append(c); ic = reader.Read(); c = (char)ic; } if (ic != -1) { reader.Unread(ic); } retval = CosNumberFactory.get(buf.ToString()) as CosBase; } else { //This is not suppose to happen, but we will allow for it //so we are more compatible with POS writers that don't //follow the spec string badstring = ReadHelper.ReadString(reader); if (badstring == string.Empty) { int peek = reader.Peek(); // we can end up in an infinite loop otherwise throw new IOException("Unknown dir object c='" + c + "' cInt=" + (int)c + " peek='" + (char)peek + "' peekInt=" + peek + " at offset " + reader.GetPosition()); } // if it's an endstream/endobj, we want to put it back so the caller will see it if (string.Equals("endobj", badstring) || string.Equals("endstream", badstring)) { reader.Unread(OtherEncodings.StringAsLatin1Bytes(badstring)); } } break; } return(retval); }