public PdfDocumentReader(Stream stream, bool leaveOpen) { if (stream is null) { throw new ArgumentNullException(nameof(stream)); } try { if (!stream.CanSeek) { stream = _copyStreamToMemory(stream, leaveOpen); leaveOpen = false; } this._stream = stream; this._leaveOpen = leaveOpen; this._rootReference = null; this._encryptReference = null; this._infoReference = null; _fileVersion = _readHeader(); int pos = _readStartXref(); var reader = new PdfStreamReader(this, stream, pos); try { var token = reader.ReadToken(); switch (token.Type) { case PdfValueType.Xref: _readXrefTable(reader); break; case PdfValueType.Integer: _readXrefObject(pos, reader, token); break; default: throw new PdfExceptionReader("Can't locate table."); } } catch (Exception err) { throw new PdfExceptionReader("Error reading xref table.", err); } } catch (Exception err) { if (!leaveOpen) { stream.Close(); } throw new PdfExceptionReader("Can't open PDF stream.", err); } }
private void _allocateXrefTable(int size) { if (_xrefTable == null || _xrefTable.Length < size) { PdfReferenceReader[] NewTable = new PdfReferenceReader[size]; if (_xrefTable != null) { Array.Copy(_xrefTable, NewTable, _xrefTable.Length); } _xrefTable = NewTable; } }
internal PdfValue pdfReadObj(PdfReferenceReader reference) { try { if (reference.CompressedObj == null) { var reader = new PdfStreamReader(this, _stream, reference.Position); int id = reader.ReadInt(); int revision = reader.ReadInt(); reader.ReadToken(PdfValueType.ObjectBegin); if (id != reference.Id || revision != reference.Revision) { throw new PdfException("Object id d'not match with xreftable."); } var obj = _readObj(reader, false); if (obj is PdfObjectReader && ((PdfObjectReader)obj).NamedType == "ObjStm") { obj = new PdfObjStmReader(this, (PdfObjectReader)obj); } return(obj); } else { if (!(_xrefTable[reference.CompressedObj.Id].Value is PdfObjStmReader objStm)) { throw new PdfException("Obj not ObjStm."); } return(_readObj(new PdfStreamReader(this, objStm.GetStream(reference.Position, reference.Id), 0), true)); } } catch (Exception err) { throw new PdfExceptionReader("Can't read object " + reference.Id.ToString(CultureInfo.InvariantCulture) + "/" + reference.Revision.ToString(CultureInfo.InvariantCulture) + ".", err); } }
internal PdfReferenceReader pdfGetReference(int id, int revision) { if (id < 0 || id > 65000) { throw new PdfExceptionReader("Invalid reference #" + id + " to a unknown object."); } if (id >= _xrefTable.Length) { _allocateXrefTable(id + 1); } if (_xrefTable[id] == null) { return(_xrefTable[id] = new PdfReferenceReader(this, id, revision)); } if (_xrefTable[id].Revision != revision) { throw new PdfExceptionReader("Invalid revesion for object #" + id + "."); } return(_xrefTable[id]); }
public PdfReferenceReader(PdfDocumentReader document, int id, int revision, int position, PdfReferenceReader compressObj) { this.Document = document; this.Id = id; this.Revision = revision; this.Position = position; this.CompressedObj = compressObj; }
internal void setCompressed(int pos, PdfReferenceReader compressedObj) { this.Position = pos; this.CompressedObj = compressedObj; }
private void _readXrefObject(int pos, PdfStreamReader reader, PdfValue firstToken) { int id = ((PdfInteger)firstToken).Value; int revision = reader.ReadInt(); reader.ReadToken(PdfValueType.ObjectBegin); _allocateXrefTable(id + 1); var rr = new PdfReferenceReader(this, id, revision, pos); if (!(_readObj(reader, false) is PdfObjectReader obj)) { throw new PdfExceptionReader("Invalid Xref obj."); } rr.setValue(obj); _xrefTable[id] = rr; var dictionary = obj.Dictionary.Children; PdfValueList w = null; PdfValueList index = null; int size = 0; PdfReferenceReader prev = null; for (int i = 0; i < dictionary.Count; ++i) { var entry = dictionary[i]; if (entry is PdfName) { switch (((PdfName)entry).Value) { case "W": w = ((PdfArray)dictionary[++i]).Children; break; case "Index": index = ((PdfArray)dictionary[++i]).Children; break; case "Size": size = ((PdfInteger)dictionary[++i]).Value; break; case "Prev": prev = (PdfReferenceReader)dictionary[++i]; break; case "Root": _rootReference = (PdfReferenceReader)dictionary[++i]; break; case "Encrypt": _encryptReference = (PdfReferenceReader)dictionary[++i]; break; case "Info": _infoReference = (PdfReferenceReader)dictionary[++i]; break; case "ID": _id = ((PdfArray)dictionary[++i]).Children.ToArray(); break; } } } if (obj.NamedType != "XRef" || w == null || index == null) { throw new PdfExceptionReader("Invalid xref object."); } int s1 = ((PdfInteger)w[0]).Value; int s2 = ((PdfInteger)w[1]).Value; int s3 = ((PdfInteger)w[2]).Value; id = ((PdfInteger)index[0]).Value; _allocateXrefTable(((PdfInteger)index[1]).Value); using (var r = new PdfXrefStreamReader(obj.GetUncompressStream())) { while (!r.EOF) { int t = r.ReadValue(s1); int v2 = r.ReadValue(s2); int v3 = r.ReadValue(s3); switch (t) { case 0: break; case 1: pdfGetReference(id, v3).setPosition(v2); break; case 2: pdfGetReference(id, 0).setCompressed(v3, pdfGetReference(v2, 0)); break; default: throw new PdfExceptionReader("cross-reference stream type #" + t + " unknown."); } ++id; } } }
private void _readXrefTable(PdfStreamReader reader) { PdfValue Token; // Read xref table while ((Token = reader.ReadToken()).Type == PdfValueType.Integer) { int Id = ((PdfInteger)Token).Value; int Count = reader.ReadInt(); _allocateXrefTable(Id + Count); while (Count-- > 0) { int EntryPosition = reader.ReadInt(); int EntryRevision = reader.ReadInt(); bool EntryUsed = (reader.ReadByte() == 'n'); if (EntryPosition >= 10 && EntryUsed) { _xrefTable[Id] = new PdfReferenceReader(this, Id, EntryRevision, EntryPosition); } ++Id; } } // Read trailer if (Token.Type != PdfValueType.Trailer) { throw new PdfExceptionReader("PDF stream corrupt: 'trailer' expected."); } reader.ReadToken(PdfValueType.DictionaryBegin); while ((Token = reader.ReadToken()).Type != PdfValueType.DictionaryEnd) { if (Token.Type == PdfValueType.Name) { switch (((PdfName)Token).Value) { case "Size": if (reader.ReadInt() != _xrefTable.Length) { throw new PdfExceptionReader("PDF stream corrupt: Xref table size d'not match trailer 'Size'."); } break; case "Prev": { var p = reader.ReadInt(); reader.ReadToken(PdfValueType.Xref); _readXrefTable(new PdfStreamReader(this, _stream, p)); } break; case "Root": _rootReference = pdfGetReference(reader.ReadReference()); break; case "Encrypt": _encryptReference = pdfGetReference(reader.ReadReference()); break; case "Info": _infoReference = pdfGetReference(reader.ReadReference()); break; case "ID": { List <PdfValue> ID = new List <PdfValue>(); reader.ReadToken(PdfValueType.ArrayBegin); while ((Token = reader.ReadToken()).Type != PdfValueType.ArrayEnd) { ID.Add(Token); } _id = ID.ToArray(); } break; } } } }