protected override void ReleaseIndirectObject(IIndirectObject obj) { base.ReleaseIndirectObject(obj); if (obj is PDFIndirectObject) { if (this.TraceLog.ShouldLog(PoolTraceLevel)) { this.TraceLog.Add(PoolTraceLevel, PoolTraceCategory, "Writing object data for " + obj.ToString() + " and releasing back onto the pool"); } PDFIndirectObject known = (PDFIndirectObject)obj; if (known.Written == false) { this.WriteAnIndirectObject(known); } PDFStream data = known.ObjectData; PDFStream content = known.HasStream ? known.Stream : null; if (data != null) { this.ReleaseAndRePool(data); } if (content != null) { this.ReleaseAndRePool(content); } known.ReleaseStreams(false); } }
public void Remove_Test() { int generation = 1; PDFXRefTable target = new XRefTableProxy(generation); int count = target.ReferenceCount; PDFIndirectObject obj = new PDFIndirectObject(this); int actual = target.Append(obj); PDFIndirectObject obj2 = new PDFIndirectObject(this); actual = target.Append(obj2); //And check that it is in the list of references Assert.AreEqual(count + 2, target.ReferenceCount); Assert.IsTrue(target.Contains(obj2)); //XRef tables should not actualy remove entries, but replace the cell with an empty/deleted reference. target.Delete(obj2); Assert.AreEqual(count + 2, target.ReferenceCount); Assert.IsTrue(target.Contains(obj2)); IIndirectObject removed = target[count + 1].Reference; Assert.IsNotNull(removed); Assert.IsTrue(removed.Deleted); obj.Dispose(); obj2.Dispose(); }
/// <summary> /// Writes an individual IndirectObject to the base stream /// </summary> /// <param name="pfo"></param> protected virtual void WriteAnIndirectObject(IIndirectObject pfo) { if (pfo.Written == true) { throw new InvalidOperationException(Errors.IndirectObjectHasAlreadyBeenWritten); } try { this.Log("Writing indirect object data " + pfo.Number); this.BaseStream.Flush(); pfo.Offset = this.BaseStream.Position; this.BaseStream.Write(pfo.Number.ToString()); this.BaseStream.Write(" "); this.BaseStream.Write(pfo.Generation.ToString()); this.BaseStream.Write(" "); this.BaseStream.Write(Constants.StartObject); WriteIndirecObjectData(pfo); if (pfo.HasStream) { WriteIndirectStreamData(pfo); } this.BaseStream.Write(Constants.EndObject); this.BaseStream.WriteLine(); pfo.Written = true; } catch (Exception ex) { throw new PDFException("Could not write the indirect object '" + pfo.Number + " " + pfo.Generation + " R' to the underlying base stream: " + ex.Message, ex); } }
/// <summary> /// Overrides the default implementation to encrypt the data, then write it to the underlying stream /// </summary> /// <param name="pfo"></param> protected override void WriteIndirectStreamData(IIndirectObject pfo) { if (this.TraceLog.ShouldLog(TraceLevel.Debug)) { this.TraceLog.Begin(TraceLevel.Debug, "Secure Writer", "Encrypting stream for object '" + pfo.Number + " " + pfo.Generation + "'"); } using (var mon = this._monitor.Record(PerformanceMonitorType.Encrypting_Streams, pfo.ToString())) { byte[] unencrypted = pfo.Stream.GetStreamData(); IStreamFilter enc = CreateEncryptionFilter(pfo.Number, pfo.Generation); byte[] encrypted = enc.FilterStream(unencrypted); if (this.TraceLog.ShouldLog(TraceLevel.Debug)) { this.TraceLog.Add(TraceLevel.Debug, "Encryption", "Encrypted stream from original " + unencrypted.Length + "bytes, now writing " + encrypted.Length + " encypted data bytes"); } this.BaseStream.Write(Constants.StartStream); this.BaseStream.Write(encrypted); this.BaseStream.Write(Constants.EndStream); } if (this.TraceLog.ShouldLog(TraceLevel.Debug)) { this.TraceLog.End(TraceLevel.Debug, "Secure Writer", "Encrypting stream for object '" + pfo.Number + " " + pfo.Generation + "'"); } else if (this.TraceLog.ShouldLog(TraceLevel.Verbose)) { this.TraceLog.Add(TraceLevel.Verbose, "Encryption", "Encrypted the stream data for " + pfo.ToString()); } }
public PDFXRefTableEntry(int index, int generation, bool free, IIndirectObject reference) { this._free = free; this._generation = generation; this._index = index; this._ref = reference; }
public void Add(IIndirectObject obj) { if (obj.ReferencedType is PdfStreamDictionary || obj.ReferencedType is EncryptionDictionary || (obj.GenerationNumber != 0)) { throw new PdfInvalidAssignmentException(obj.ReferencedType); } }
public bool Contains(IIndirectObject obj) { foreach (PDFXRefTableEntry entry in this._entries) { if (entry.Reference == obj) { return(true); } } return(false); }
/// <summary> /// Adds an indirect object, and in turn setting its number and generation /// </summary> /// <param name="obj">The object to add</param> /// <returns>The added objects number</returns> public int Append(IIndirectObject obj) { if (this.ReadOnly) { throw new InvalidOperationException("Read Only XRef Table"); } int index = this._sections.Count - 1; PDFXRefTableSection section = this._sections[index]; return(section.Add(obj)); }
/// <summary> /// Get a reference to an indirect object. If we don't already have /// a reference to the object then this method creates one. /// </summary> internal ObjectReference GetReference(IIndirectObject obj) { ObjectReference oref = null; bool found = _objects.TryGetValue(obj, out oref); if (!found) { oref = new ObjectReference(obj, _nextObjectNumber++); _objects.Add(obj, oref); } return(oref); }
public int Add(IIndirectObject obj) { int index = this._start + _entries.Count; PDFXRefTableEntry entry = new PDFXRefTableEntry(index, obj.Generation, obj.Deleted, obj); this._entries.Add(entry); obj.Number = index; obj.Generation = this.Generation; obj.Offset = -1; return(index); }
/// <summary> /// Removes the current IIndirectObject and fills the space with an empty item /// </summary> /// <param name="obj"></param> public void Delete(IIndirectObject obj) { if (this.ReadOnly) { throw new InvalidOperationException("Read Only XRef Table"); } for (int i = this._sections.Count - 1; i >= 0; i--) { PDFXRefTableSection section = this._sections[i]; if (section.Start < obj.Number) { section.Delete(obj); break; } } }
public ObjectReference(IIndirectObject obj, int number) { _object = obj; _number = number; // We'll fill in the byte offset when we know it ByteOffset = 0; // We don't support updating the document, so all objects // are in-use and are at generation zero. But we implement // the properties anyway for semantic clarity. _generation = 0; InUse = true; _id = $"{_number} {_generation}"; _reference = $"{_number} {_generation} R"; }
public bool Contains(IIndirectObject obj) { for (int i = this._sections.Count - 1; i >= 0; i--) { PDFXRefTableSection section = this._sections[i]; if (section.Start < obj.Number) { return(section.Contains(obj)); } } if (null != this.Previous) { return(this.Previous.Contains(obj)); } else { return(false); } }
public override PDFStream CreateStream(IStreamFilter[] filters, IIndirectObject forobject) { if (this._available.Count > 0 && forobject is PDFIndirectObject) { if (this.TraceLog.ShouldLog(PoolTraceLevel)) { this.TraceLog.Add(PoolTraceLevel, PoolTraceCategory, "Dequeued a previously allocated PDFStream"); } int index = this._available.Count - 1; PDFStream last = this._available[index]; last.Filters = filters; last.IndirectObject = (PDFIndirectObject)forobject; this._available.RemoveAt(index); return(last); } else { return(base.CreateStream(filters, forobject)); } }
/// <summary> /// Overrides the base disposing method to dispose of any indirect object references /// </summary> /// <param name="disposing"></param> protected override void Dispose(bool disposing) { if (disposing) { if (null == this.XRefTable) { Log(TraceLevel.Message, TraceCategory, "No XRefTable to dispose"); } else { Log(TraceLevel.Verbose, TraceCategory, "Disposing PDF writer XRef Table"); try { foreach (PDFXRefTableSection section in this.XRefTable.Sections) { foreach (PDFXRefTableEntry entry in section.Entries) { if (null != entry.Reference) { IIndirectObject pfo = entry.Reference; Log(TraceLevel.Debug, "Disposing indirect object '" + pfo.ToString()); pfo.Dispose(); } } } } catch (Exception ex) { Log(TraceLevel.Error, TraceCategory, "Could not dispose of the PDFWriter14 : " + ex.ToString()); } } } base.Dispose(disposing); }
/// <summary> /// Overrides the default implementation to encrypt the data, then write it to the underlying stream /// </summary> /// <param name="pfo"></param> protected override void WriteIndirectStreamData(IIndirectObject pfo) { if (this.TraceLog.ShouldLog(TraceLevel.Debug)) { this.TraceLog.Begin(TraceLevel.Debug, "Secure Writer", "Encrypting stream for object '" + pfo.Number + " " + pfo.Generation + "'"); } byte[] unencrypted = pfo.Stream.GetStreamData(); IStreamFilter enc = CreateEncryptionFilter(pfo.Number, pfo.Generation); byte[] encrypted = enc.FilterStream(unencrypted); if (this.TraceLog.ShouldLog(TraceLevel.Debug)) { this.TraceLog.Add(TraceLevel.Debug, "Encryption", "Encrypted stream data, now writing"); } this.BaseStream.Write(Constants.StartStream); this.BaseStream.Write(encrypted); this.BaseStream.Write(Constants.EndStream); if (this.TraceLog.ShouldLog(TraceLevel.Debug)) { this.TraceLog.End(TraceLevel.Debug, "Secure Writer", "Encrypting stream for object '" + pfo.Number + " " + pfo.Generation + "'"); } }
public PDFStream CreateStream(IStreamFilter[] filters, IIndirectObject forobject) { PDFIndirectObject indobj = (PDFIndirectObject)forobject; return(new PDFStream(filters, indobj)); }
/// <summary> /// Outputs the IndirectObjects stream data onto the base stream /// </summary> /// <param name="pfo"></param> protected virtual void WriteIndirectStreamData(IIndirectObject pfo) { this.BaseStream.Write(Constants.StartStream); pfo.Stream.WriteTo(this.BaseStream); this.BaseStream.Write(Constants.EndStream); }
/// <summary> /// Outputs the IndirectObjects object data onto the base stream /// </summary> /// <param name="pfo"></param> protected virtual void WriteIndirecObjectData(IIndirectObject pfo) { pfo.ObjectData.WriteTo(this.BaseStream); }
public void Delete(IIndirectObject obj) { int index = obj.Number - this.Start; this._entries[index].Delete(); }
public PDFObjectRef(IIndirectObject reference) { this._ref = reference; }