public virtual void PdfIndirectReferenceFlags() { PdfIndirectReference reference = new PdfIndirectReference(null, 1); reference.SetState(PdfObject.FREE); reference.SetState(PdfObject.READING); reference.SetState(PdfObject.MODIFIED); NUnit.Framework.Assert.AreEqual(true, reference.CheckState(PdfObject.FREE), "Free"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState(PdfObject.READING), "Reading"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState(PdfObject.MODIFIED), "Modified"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState((byte)(PdfObject.FREE | PdfObject.MODIFIED | PdfObject .READING)), "Free|Reading|Modified"); reference.ClearState(PdfObject.FREE); NUnit.Framework.Assert.AreEqual(false, reference.CheckState(PdfObject.FREE), "Free"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState(PdfObject.READING), "Reading"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState(PdfObject.MODIFIED), "Modified"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState((byte)(PdfObject.READING | PdfObject.MODIFIED)) , "Reading|Modified"); NUnit.Framework.Assert.AreEqual(false, reference.CheckState((byte)(PdfObject.FREE | PdfObject.READING | PdfObject .MODIFIED)), "Free|Reading|Modified"); reference.ClearState(PdfObject.READING); NUnit.Framework.Assert.AreEqual(false, reference.CheckState(PdfObject.FREE), "Free"); NUnit.Framework.Assert.AreEqual(false, reference.CheckState(PdfObject.READING), "Reading"); NUnit.Framework.Assert.AreEqual(true, reference.CheckState(PdfObject.MODIFIED), "Modified"); NUnit.Framework.Assert.AreEqual(false, reference.CheckState((byte)(PdfObject.FREE | PdfObject.READING)), "Free|Reading" ); reference.ClearState(PdfObject.MODIFIED); NUnit.Framework.Assert.AreEqual(false, reference.CheckState(PdfObject.FREE), "Free"); NUnit.Framework.Assert.AreEqual(false, reference.CheckState(PdfObject.READING), "Reading"); NUnit.Framework.Assert.AreEqual(false, reference.CheckState(PdfObject.MODIFIED), "Modified"); NUnit.Framework.Assert.AreEqual(true, !reference.IsFree(), "Is InUse"); reference.SetState(PdfObject.FREE); NUnit.Framework.Assert.AreEqual(false, !reference.IsFree(), "Not IsInUse"); }
/// <summary>Marks object to be saved as indirect.</summary> /// <param name="document">a document the indirect reference will belong to.</param> /// <returns>object itself.</returns> public virtual PdfObject MakeIndirect(PdfDocument document, PdfIndirectReference reference) { if (document == null || indirectReference != null) { return(this); } if (document.GetWriter() == null) { throw new PdfException(PdfException.ThereIsNoAssociatePdfWriterForMakingIndirects); } if (reference == null) { indirectReference = document.CreateNextIndirectReference(); indirectReference.SetRefersTo(this); } else { reference.SetState(MODIFIED); indirectReference = reference; indirectReference.SetRefersTo(this); } SetState(FORBID_RELEASE); ClearState(MUST_BE_INDIRECT); return(this); }
protected internal virtual void FreeReference(PdfIndirectReference reference) { if (reference.IsFree()) { return; } if (reference.CheckState(PdfObject.MUST_BE_FLUSHED)) { ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.PdfXrefTable)); logger.Error(iText.IO.LogMessageConstant.INDIRECT_REFERENCE_USED_IN_FLUSHED_OBJECT_MADE_FREE); return; } if (reference.CheckState(PdfObject.FLUSHED)) { ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.PdfXrefTable)); logger.Error(iText.IO.LogMessageConstant.ALREADY_FLUSHED_INDIRECT_OBJECT_MADE_FREE); return; } reference.SetState(PdfObject.FREE).SetState(PdfObject.MODIFIED); AppendNewRefToFreeList(reference); if (reference.GetGenNumber() < MAX_GENERATION) { reference.genNr++; } }
/// <summary>Creates next available indirect reference.</summary> /// <returns>created indirect reference.</returns> protected internal virtual PdfIndirectReference CreateNextIndirectReference(PdfDocument document) { PdfIndirectReference reference = new PdfIndirectReference(document, ++count); Add(reference); return((PdfIndirectReference)reference.SetState(PdfObject.MODIFIED)); }
/// <summary>Sets the 'modified' flag to the indirect object, the flag denotes that the object was modified since the document opening. /// </summary> /// <remarks> /// Sets the 'modified' flag to the indirect object, the flag denotes that the object was modified since the document opening. /// <para /> /// This flag is meaningful only if the /// <see cref="PdfDocument"/> /// is opened in append mode /// (see /// <see cref="StampingProperties.UseAppendMode()"/> /// ). /// <para /> /// In append mode the whole document is preserved as is, and only changes to the document are /// appended to the end of the document file. Because of this, only modified objects need to be flushed and are /// allowed to be flushed (i.e. to be written). /// </remarks> /// <returns> /// this /// <see cref="PdfObject"/> /// instance. /// </returns> public virtual PdfObject SetModified() { if (indirectReference != null) { indirectReference.SetState(MODIFIED); SetState(FORBID_RELEASE); } return(this); }
private void AppendNewRefToFreeList(PdfIndirectReference reference) { reference.SetOffset(0); if (freeReferencesLinkedList.IsEmpty <int, PdfIndirectReference>()) { System.Diagnostics.Debug.Assert(false); // free references list is not initialized yet return; } PdfIndirectReference lastFreeRef = freeReferencesLinkedList.Get(0); ((PdfIndirectReference)lastFreeRef.SetState(PdfObject.MODIFIED)).SetOffset(reference.GetObjNumber()); freeReferencesLinkedList.Put(reference.GetObjNumber(), lastFreeRef); freeReferencesLinkedList.Put(0, reference); }
/// <summary>Flushes the object.</summary> /// <remarks>Flushes the object. Override this method if you want to define custom behaviour for object flushing. /// </remarks> /// <param name="pdfObject">object to flush.</param> /// <param name="canBeInObjStm">indicates whether object can be placed into object stream.</param> /// <exception cref="System.IO.IOException">on error.</exception> protected internal virtual void FlushObject(PdfObject pdfObject, bool canBeInObjStm) { PdfIndirectReference indirectReference = pdfObject.GetIndirectReference(); if (IsFullCompression() && canBeInObjStm) { PdfObjectStream objectStream = GetObjectStream(); objectStream.AddObject(pdfObject); } else { indirectReference.SetOffset(GetCurrentPos()); WriteToBody(pdfObject); } ((PdfIndirectReference)indirectReference.SetState(PdfObject.FLUSHED)).ClearState(PdfObject.MUST_BE_FLUSHED ); switch (pdfObject.GetObjectType()) { case PdfObject.BOOLEAN: case PdfObject.NAME: case PdfObject.NULL: case PdfObject.NUMBER: case PdfObject.STRING: { ((PdfPrimitiveObject)pdfObject).content = null; break; } case PdfObject.ARRAY: { PdfArray array = ((PdfArray)pdfObject); MarkArrayContentToFlush(array); array.ReleaseContent(); break; } case PdfObject.STREAM: case PdfObject.DICTIONARY: { PdfDictionary dictionary = ((PdfDictionary)pdfObject); MarkDictionaryContentToFlush(dictionary); dictionary.ReleaseContent(); break; } case PdfObject.INDIRECT_REFERENCE: { MarkObjectToFlush(((PdfIndirectReference)pdfObject).GetRefersTo(false)); break; } } }
/// <summary>Removes indirect reference from free references linked list.</summary> /// <remarks> /// Removes indirect reference from free references linked list. /// It does not removes it from xref table and affects only the linked list formed by offset values of free references. /// </remarks> /// <param name="freeRefObjNr"> /// object number of the reference to be removed. /// Removes the free reference with the least object number if this parameter is less than zero: /// this could be used for finding the next free reference for reusing. /// </param> /// <returns> /// /// <see cref="PdfIndirectReference"/> /// instance of the removed free reference corresponding to the object number /// passed as parameter. /// <see langword="null"/> /// - if given object number doesn't correspond to free reference or equals to zero. /// </returns> private PdfIndirectReference RemoveFreeRefFromList(int freeRefObjNr) { if (freeReferencesLinkedList.IsEmpty <int, PdfIndirectReference>()) { System.Diagnostics.Debug.Assert(false); // free references list is not initialized yet return(null); } if (freeRefObjNr == 0) { return(null); } if (freeRefObjNr < 0) { int?leastFreeRefObjNum = null; foreach (KeyValuePair <int, PdfIndirectReference> entry in freeReferencesLinkedList) { if (entry.Key <= 0 || xref[entry.Key].GetGenNumber() >= MAX_GENERATION) { continue; } leastFreeRefObjNum = entry.Key; break; } if (leastFreeRefObjNum == null) { return(null); } freeRefObjNr = (int)leastFreeRefObjNum; } PdfIndirectReference freeRef = xref[freeRefObjNr]; if (!freeRef.IsFree()) { return(null); } PdfIndirectReference prevFreeRef = freeReferencesLinkedList.JRemove(freeRef.GetObjNumber()); if (prevFreeRef != null) { freeReferencesLinkedList.Put((int)freeRef.GetOffset(), prevFreeRef); ((PdfIndirectReference)prevFreeRef.SetState(PdfObject.MODIFIED)).SetOffset(freeRef.GetOffset()); } return(freeRef); }
protected internal virtual void FreeReference(PdfIndirectReference reference) { reference.SetOffset(0); reference.SetState(PdfObject.FREE); if (!reference.CheckState(PdfObject.FLUSHED)) { if (reference.refersTo != null) { reference.refersTo.SetIndirectReference(null).SetState(PdfObject.MUST_BE_INDIRECT); reference.refersTo = null; } if (reference.GetGenNumber() < MAX_GENERATION) { freeReferences.Add(reference.GetObjNumber()); xref[reference.GetObjNumber()] = null; } } }
private void MarkObjectToFlush(PdfObject pdfObject) { if (pdfObject != null) { PdfIndirectReference indirectReference = pdfObject.GetIndirectReference(); if (indirectReference != null) { if (!indirectReference.CheckState(PdfObject.FLUSHED)) { indirectReference.SetState(PdfObject.MUST_BE_FLUSHED); } } else { if (pdfObject.GetObjectType() == PdfObject.INDIRECT_REFERENCE) { if (!pdfObject.CheckState(PdfObject.FLUSHED)) { pdfObject.SetState(PdfObject.MUST_BE_FLUSHED); } } else { if (pdfObject.GetObjectType() == PdfObject.ARRAY) { MarkArrayContentToFlush((PdfArray)pdfObject); } else { if (pdfObject.GetObjectType() == PdfObject.DICTIONARY) { MarkDictionaryContentToFlush((PdfDictionary)pdfObject); } } } } } }
internal virtual void InitFreeReferencesList(PdfDocument pdfDocument) { freeReferencesLinkedList.Clear(); // ensure zero object is free xref[0].SetState(PdfObject.FREE); SortedSet <int> freeReferences = new SortedSet <int>(); for (int i = 1; i < Size(); ++i) { PdfIndirectReference @ref = xref[i]; if (@ref == null || @ref.IsFree()) { freeReferences.Add(i); } } PdfIndirectReference prevFreeRef = xref[0]; while (!freeReferences.IsEmpty <int>()) { int currFreeRefObjNr = -1; if (prevFreeRef.GetOffset() <= int.MaxValue) { currFreeRefObjNr = (int)prevFreeRef.GetOffset(); } if (!freeReferences.Contains(currFreeRefObjNr) || xref[currFreeRefObjNr] == null) { break; } freeReferencesLinkedList.Put(currFreeRefObjNr, prevFreeRef); prevFreeRef = xref[currFreeRefObjNr]; freeReferences.Remove(currFreeRefObjNr); } while (!freeReferences.IsEmpty <int>()) { int next = freeReferences.PollFirst(); if (xref[next] == null) { if (pdfDocument.properties.appendMode) { continue; } xref[next] = (PdfIndirectReference) new PdfIndirectReference(pdfDocument, next, 0).SetState(PdfObject.FREE) .SetState(PdfObject.MODIFIED); } else { if (xref[next].GetGenNumber() == MAX_GENERATION && xref[next].GetOffset() == 0) { continue; } } if (prevFreeRef.GetOffset() != (long)next) { ((PdfIndirectReference)prevFreeRef.SetState(PdfObject.MODIFIED)).SetOffset(next); } freeReferencesLinkedList.Put(next, prevFreeRef); prevFreeRef = xref[next]; } if (prevFreeRef.GetOffset() != 0) { ((PdfIndirectReference)prevFreeRef.SetState(PdfObject.MODIFIED)).SetOffset(0); } freeReferencesLinkedList.Put(0, prevFreeRef); }