Example #1
0
 internal Reader(IInputStream stream, Files.File file)
 {
     this.parser = new FileParser(stream, file);
 }
Example #2
0
        protected override void WriteIncremental(
            )
        {
            // 1. Original content (head, body and previous trailer).
            FileParser parser = file.Reader.Parser;

            stream.Write(parser.Stream);

            // 2. Body update (modified indirect objects insertion).
            int           xrefSize    = file.IndirectObjects.Count;
            StringBuilder xrefBuilder = new StringBuilder(XRefChunk);
            {
                /*
                 * NOTE: Incremental xref table comprises multiple sections
                 * each one composed by multiple subsections; this update
                 * adds a new section.
                 */
                StringBuilder xrefSubBuilder = new StringBuilder(); // Xref-table subsection builder.
                int           xrefSubCount   = 0;                   // Xref-table subsection counter.
                int           prevKey        = 0;                   // Previous-entry object number.
                foreach (
                    KeyValuePair <int, PdfIndirectObject> indirectObjectEntry
                    in file.IndirectObjects.ModifiedObjects
                    )
                {
                    // Is the object in the current subsection?

                    /*
                     * NOTE: To belong to the current subsection, the object entry MUST be contiguous with the
                     * previous (condition 1) or the iteration has to have been just started (condition 2).
                     */
                    if (indirectObjectEntry.Key - prevKey == 1 ||
                        prevKey == 0)  // Current subsection continues.
                    {
                        xrefSubCount++;
                    }
                    else // Current subsection terminates.
                    {
                        // End current subsection!
                        AppendXRefSubsection(
                            xrefBuilder,
                            prevKey - xrefSubCount + 1,
                            xrefSubCount,
                            xrefSubBuilder
                            );

                        // Begin next subsection!
                        xrefSubBuilder.Length = 0;
                        xrefSubCount          = 1;
                    }

                    prevKey = indirectObjectEntry.Key;

                    // Current entry insertion.
                    if (indirectObjectEntry.Value.IsInUse()) // In-use entry.
                    {
                        // Add in-use entry!
                        AppendXRefEntry(
                            xrefSubBuilder,
                            indirectObjectEntry.Value.Reference,
                            stream.Length
                            );
                        // Add in-use entry content!
                        indirectObjectEntry.Value.WriteTo(stream, file);
                    }
                    else // Free entry.
                    {
                        // Add free entry!

                        /*
                         * NOTE: We purposely neglect the linked list of free entries (see IndirectObjects.remove(int)),
                         * so that this entry links directly back to object number 0, having a generation number of 65535
                         * (not reusable) [PDF:1.6:3.4.3].
                         */
                        AppendXRefEntry(
                            xrefSubBuilder,
                            indirectObjectEntry.Value.Reference,
                            0
                            );
                    }
                }
                // End last subsection!
                AppendXRefSubsection(
                    xrefBuilder,
                    prevKey - xrefSubCount + 1,
                    xrefSubCount,
                    xrefSubBuilder
                    );
            }

            // 3. XRef-table last section.
            long startxref = stream.Length;

            stream.Write(xrefBuilder.ToString());

            // 4. Trailer.
            WriteTrailer(startxref, xrefSize, parser);
        }
Example #3
0
 public ObjectEntry(PdfDataObject dataObject, FileParser parser)
     : this(parser)
 {
     this.dataObject = dataObject;
     this.offset     = -1; // Undefined -- to set on stream serialization.
 }
Example #4
0
 public ObjectEntry(int offset, FileParser parser)
     : this(parser)
 {
     this.dataObject = null;
     this.offset     = offset;
 }
Example #5
0
 private ObjectEntry(FileParser parser)
 {
     this.parser = parser;
 }
Example #6
0
 internal Reader(IInputStream stream, Files.File file, string password = null, System.IO.Stream keyStoreInputStream = null)
 {
     this.parser = new FileParser(stream, file, password, keyStoreInputStream);
 }
        protected override void WriteIncremental()
        {
            // 1. Original content (header, body and previous trailer).
            FileParser parser = file.Reader.Parser;

            stream.Write(parser.Stream);

            // 2. Body update (modified indirect objects insertion).
            XRefEntry xrefStreamEntry;

            {
                // Create the xref stream!

                /*
                 * NOTE: Incremental xref information structure comprises multiple sections; this update adds
                 * a new section.
                 */
                XRefStream xrefStream = new XRefStream(file);

                // 2.1. Indirect objects.
                IndirectObjects indirectObjects = file.IndirectObjects;

                // 2.1.1. Modified indirect objects serialization.
                XRefEntry prevFreeEntry = null;

                /*
                 * NOTE: Any uncompressed indirect object will be compressed.
                 */
                ObjectStream objectStream = null;

                /*
                 * NOTE: Any previously-compressed indirect object will have its original object stream
                 * updated through a new extension object stream.
                 */
                IDictionary <int, ObjectStream> extensionObjectStreams = new Dictionary <int, ObjectStream>();
                int indirectObjectsPrecompressCount = indirectObjects.Count;
                foreach (PdfIndirectObject indirectObject in new List <PdfIndirectObject>(indirectObjects.ModifiedObjects.Values))
                {
                    if (indirectObject.IsCompressible())
                    {
                        if (objectStream == null ||
                            objectStream.Count >= ObjectStreamMaxEntryCount)
                        {
                            file.Register(objectStream = new ObjectStream());
                        }

                        indirectObject.Compress(objectStream);
                    }

                    prevFreeEntry = AddXRefEntry(
                        indirectObject,
                        xrefStream,
                        prevFreeEntry,
                        extensionObjectStreams
                        );
                }
                // 2.1.2. Additional object streams serialization.
                for (int index = indirectObjectsPrecompressCount, limit = indirectObjects.Count; index < limit; index++)
                {
                    prevFreeEntry = AddXRefEntry(
                        indirectObjects[index],
                        xrefStream,
                        prevFreeEntry,
                        null
                        );
                }
                if (prevFreeEntry != null)
                {
                    prevFreeEntry.Offset = 0; // Links back to the first free object. NOTE: The first entry in the table (object number 0) is always free.
                }

                // 2.2. XRef stream.
                UpdateTrailer(xrefStream.Header, stream);
                xrefStream.Header[PdfName.Prev] = PdfInteger.Get((int)parser.RetrieveXRefOffset());
                AddXRefEntry(

                    /*
                     * NOTE: This xref stream indirect object is purposely temporary (i.e. not registered into
                     * the file's indirect objects collection).
                     */
                    new PdfIndirectObject(
                        file,
                        xrefStream,
                        xrefStreamEntry = new XRefEntry(indirectObjects.Count, 0, (int)stream.Length, XRefEntry.UsageEnum.InUse)
                        ),
                    xrefStream,
                    null,
                    null
                    );
            }

            // 3. Tail.
            WriteTail(xrefStreamEntry.Offset);
        }