private void FlushOrRelease(PdfObject obj)
 {
     if (release)
     {
         if (!obj.IsReleaseForbidden())
         {
             obj.Release();
         }
     }
     else
     {
         MakeIndirectIfNeeded(obj);
         if (!pdfDoc.IsAppendMode() || obj.IsModified())
         {
             obj.Flush();
         }
         else
         {
             if (!obj.IsReleaseForbidden())
             {
                 obj.Release();
             }
         }
     }
 }
Esempio n. 2
0
        /// <summary>Flushes all modified objects which have not been flushed yet.</summary>
        /// <remarks>Flushes all modified objects which have not been flushed yet. Used in case incremental updates.</remarks>
        /// <param name="forbiddenToFlush">
        /// a
        /// <see cref="Java.Util.Set{E}"/>
        /// of
        /// <see cref="PdfIndirectReference">references</see>
        /// that are forbidden to be flushed automatically.
        /// </param>
        protected internal virtual void FlushModifiedWaitingObjects(ICollection <PdfIndirectReference> forbiddenToFlush
                                                                    )
        {
            PdfXrefTable xref = document.GetXref();

            for (int i = 1; i < xref.Size(); i++)
            {
                PdfIndirectReference indirectReference = xref.Get(i);
                if (null != indirectReference && !indirectReference.IsFree() && !forbiddenToFlush.Contains(indirectReference
                                                                                                           ))
                {
                    bool isModified = indirectReference.CheckState(PdfObject.MODIFIED);
                    if (isModified)
                    {
                        PdfObject obj = indirectReference.GetRefersTo(false);
                        if (obj != null)
                        {
                            if (!obj.Equals(objectStream))
                            {
                                obj.Flush();
                            }
                        }
                    }
                }
            }
            if (objectStream != null && objectStream.GetSize() > 0)
            {
                objectStream.Flush();
                objectStream = null;
            }
        }
Esempio n. 3
0
        /// <summary>Flushes all objects which have not been flushed yet.</summary>
        /// <param name="forbiddenToFlush">
        /// a
        /// <see cref="Java.Util.Set{E}"/>
        /// of
        /// <see cref="PdfIndirectReference">references</see>
        /// that are forbidden to be flushed automatically.
        /// </param>
        protected internal virtual void FlushWaitingObjects(ICollection <PdfIndirectReference> forbiddenToFlush)
        {
            PdfXrefTable xref      = document.GetXref();
            bool         needFlush = true;

            while (needFlush)
            {
                needFlush = false;
                for (int i = 1; i < xref.Size(); i++)
                {
                    PdfIndirectReference indirectReference = xref.Get(i);
                    if (indirectReference != null && !indirectReference.IsFree() && indirectReference.CheckState(PdfObject.MUST_BE_FLUSHED
                                                                                                                 ) && !forbiddenToFlush.Contains(indirectReference))
                    {
                        PdfObject obj = indirectReference.GetRefersTo(false);
                        if (obj != null)
                        {
                            obj.Flush();
                            needFlush = true;
                        }
                    }
                }
            }
            if (objectStream != null && objectStream.GetSize() > 0)
            {
                objectStream.Flush();
                objectStream = null;
            }
        }
        public virtual void IndirectFilterFlushedBeforeStreamTest()
        {
            // TODO DEVSIX-1193 remove junitExpectedException after fix
            String      inFile = sourceFolder + "indFilterInCatalog.pdf";
            String      @out   = destinationFolder + "indirectFilterFlushedBeforeStreamTest.pdf";
            PdfDocument pdfDoc = new PdfDocument(new PdfReader(inFile), new PdfWriter(@out));
            // Simulate the case in which filter is somehow already flushed before stream.
            // Either directly by user or because of any other reason.
            PdfObject filterObject = pdfDoc.GetPdfObject(6);

            filterObject.Flush();
            NUnit.Framework.Assert.That(() => {
                pdfDoc.Close();
            }
                                        , NUnit.Framework.Throws.InstanceOf <NullReferenceException>())
            ;
        }
Esempio n. 5
0
        /// <summary>Flushes all modified objects which have not been flushed yet.</summary>
        /// <remarks>Flushes all modified objects which have not been flushed yet. Used in case incremental updates.</remarks>
        protected internal virtual void FlushModifiedWaitingObjects()
        {
            PdfXrefTable xref = document.GetXref();

            for (int i = 1; i < xref.Size(); i++)
            {
                PdfIndirectReference indirectReference = xref.Get(i);
                if (null != indirectReference)
                {
                    PdfObject obj = indirectReference.GetRefersTo(false);
                    if (obj != null && !obj.Equals(objectStream) && obj.IsModified())
                    {
                        obj.Flush();
                    }
                }
            }
            if (objectStream != null && objectStream.GetSize() > 0)
            {
                objectStream.Flush();
                objectStream = null;
            }
        }
        /// <summary>
        /// Flushes to the output stream modified objects that can belong only to the given page, which makes this method
        /// "safe" compared to the
        /// <see cref="UnsafeFlushDeep(int)"/>
        /// . Flushed object frees the memory, but it's impossible to
        /// modify such objects or read data from them. This method releases all other page structure objects that are not
        /// modified.
        /// <p>
        /// This method is mainly designed for the append mode. It is similar to the
        /// <see cref="PdfPage.Flush()"/>
        /// , but it
        /// additionally releases all page objects that were not flushed. This method is ideal for small amendments of pages,
        /// but it makes more sense to use
        /// <see cref="PdfPage.Flush()"/>
        /// for newly created or heavily modified pages. <br />
        /// This method will throw an exception for documents opened in reading mode (see
        /// <see cref="PageFlushingHelper"/>
        /// for more details on modes). It is also not advised to be used in stamping mode: even though it will indeed
        /// release the objects and free the memory, the released objects will definitely be re-read again on document
        /// closing, which would affect performance.
        /// </p>
        /// <p>
        /// When using this method in append mode (or in stamping mode), be careful not to try to modify the object instances
        /// obtained before this method call! See
        /// <see cref="PageFlushingHelper"/>
        /// for details on released and flushed objects state.
        /// </p>
        /// <p>
        /// This method shall be used only when it's known that the page and its inner structures processing is finished.
        /// This includes reading data from pages, page modification and page handling via addons/utilities.
        /// </p>
        /// </summary>
        /// <param name="pageNum">the page number which low level objects structure is to be flushed or released from memory.
        ///     </param>
        public virtual void AppendModeFlush(int pageNum)
        {
            if (pdfDoc.GetWriter() == null)
            {
                throw new ArgumentException(PdfException.FlushingHelperFLushingModeIsNotForDocReadingMode);
            }
            PdfPage page = pdfDoc.GetPage(pageNum);

            if (page.IsFlushed())
            {
                return;
            }
            page.GetDocument().DispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.END_PAGE, page));
            bool pageWasModified = page.GetPdfObject().IsModified();

            page.SetModified();
            release         = true;
            pageWasModified = FlushPage(pageNum) || pageWasModified;
            PdfArray annots = page.GetPdfObject().GetAsArray(PdfName.Annots);

            if (annots != null && !annots.IsFlushed())
            {
                ArrayFlushIfModified(annots);
            }
            PdfObject thumb = page.GetPdfObject().Get(PdfName.Thumb, false);

            FlushIfModified(thumb);
            PdfObject contents = page.GetPdfObject().Get(PdfName.Contents, false);

            if (contents is PdfIndirectReference)
            {
                if (contents.CheckState(PdfObject.MODIFIED) && !contents.CheckState(PdfObject.FLUSHED))
                {
                    PdfObject contentsDirectObj = ((PdfIndirectReference)contents).GetRefersTo();
                    if (contentsDirectObj.IsArray())
                    {
                        ArrayFlushIfModified((PdfArray)contentsDirectObj);
                    }
                    else
                    {
                        contentsDirectObj.Flush();
                    }
                }
            }
            else
            {
                // already checked that modified
                if (contents is PdfArray)
                {
                    ArrayFlushIfModified((PdfArray)contents);
                }
                else
                {
                    if (contents is PdfStream)
                    {
                        FlushIfModified(contents);
                    }
                }
            }
            // Page tags flushing is supported only in PdfPage#flush and #unsafeFlushDeep: it makes sense to flush tags
            // completely for heavily modified or new pages. For the slightly modified pages it should be enough to release
            // the tag structure objects via tag structure releasing utility.
            if (!pageWasModified)
            {
                page.GetPdfObject().GetIndirectReference().ClearState(PdfObject.MODIFIED);
                pdfDoc.GetCatalog().GetPageTree().ReleasePage(pageNum);
                page.UnsetForbidRelease();
                page.GetPdfObject().Release();
            }
            else
            {
                // inherited and modified resources are handled in #flushPage call in the beginning of method
                page.ReleaseInstanceFields();
                page.GetPdfObject().Flush();
            }
        }