Exemple #1
0
 public override int CompareTo(
     PdfDirectObject obj
     )
 {
     throw new NotImplementedException();
 }
Exemple #2
0
        public override void WriteTo(
            IOutputStream stream
            )
        {
            bool unencodedBody;

            byte[] bodyData;
            int    bodyLength;

            // 1. Header.
            // Encoding.

            /*
             * NOTE: As the contract establishes that a stream instance should be kept
             * free from encodings in order to be editable, encoding is NOT applied to
             * the actual online stream, but to its serialized representation only.
             * That is, as encoding is just a serialization practise, it is excluded from
             * alive, instanced streams.
             */
            PdfDirectObject filterObj = header[PdfName.Filter];

            if (filterObj == null) // Unencoded body.
            {
                /*
                 * NOTE: As online representation is unencoded,
                 * header entries related to the encoded stream body are temporary
                 * (instrumental to the current serialization process).
                 */
                unencodedBody = true;

                // Set the filter to apply!
                filterObj = PdfName.FlateDecode; // zlib/deflate filter.
                // Get encoded body data applying the filter to the stream!
                bodyData = body.Encode(Filter.Get((PdfName)filterObj), null);
                // Set encoded length!
                bodyLength = bodyData.Length;
                // Update 'Filter' entry!
                header[PdfName.Filter] = filterObj;
            }
            else // Encoded body.
            {
                unencodedBody = false;

                // Get encoded body data!
                bodyData = body.ToByteArray();
                // Set encoded length!
                bodyLength = (int)body.Length;
            }
            // Set encoded length!
            header[PdfName.Length] = new PdfInteger(bodyLength);

            header.WriteTo(stream);

            // Is the body free from encodings?
            if (unencodedBody)
            {
                // Restore actual header entries!
                ((PdfInteger)header[PdfName.Length]).Value = (int)body.Length;
                header[PdfName.Filter] = null;
            }

            // 2. Body.
            stream.Write(BeginStreamBodyChunk);
            stream.Write(bodyData);
            stream.Write(EndStreamBodyChunk);
        }
Exemple #3
0
 /**
  * <summary>Wraps a base object within its corresponding high-level representation.</summary>
  */
 protected abstract TValue WrapValue(
     PdfDirectObject baseObject
     );
Exemple #4
0
 protected NameTree(
     PdfDirectObject baseObject
     ) : base(baseObject)
 {
 }
Exemple #5
0
 protected Tree(
     PdfDirectObject baseObject
     ) : base(baseObject)
 {
     Initialize();
 }
Exemple #6
0
        public virtual bool Remove(
            TKey key
            )
        {
            PdfDictionary        node = BaseDataObject;
            Stack <PdfReference> nodeReferenceStack = new Stack <PdfReference>();

            while (true)
            {
                Children nodeChildren = Children.Get(node, pairsKey);
                if (nodeChildren.IsLeaf()) // Leaf node.
                {
                    int low = 0, high = nodeChildren.Items.Count - nodeChildren.Info.ItemCount;
                    while (true)
                    {
                        if (low > high) // No match.
                        {
                            return(false);
                        }

                        int mid        = (mid = ((low + high) / 2)) - (mid % 2);
                        int comparison = key.CompareTo(nodeChildren.Items[mid]);
                        if (comparison < 0) // Key before.
                        {
                            high = mid - 2;
                        }
                        else if (comparison > 0) // Key after.
                        {
                            low = mid + 2;
                        }
                        else // Key matched.
                        {
                            // We got it!
                            nodeChildren.Items.RemoveAt(mid + 1);            // Removes value.
                            nodeChildren.Items.RemoveAt(mid);                // Removes key.
                            if (mid == 0 || mid == nodeChildren.Items.Count) // Limits changed.
                            {
                                // Update key limits!
                                UpdateNodeLimits(nodeChildren);

                                // Updating key limits on ascendants...
                                PdfReference rootReference = (PdfReference)BaseObject;
                                PdfReference nodeReference;
                                while (nodeReferenceStack.Count > 0 && !(nodeReference = nodeReferenceStack.Pop()).Equals(rootReference))
                                {
                                    PdfArray parentChildren = (PdfArray)nodeReference.Parent;
                                    int      nodeIndex      = parentChildren.IndexOf(nodeReference);
                                    if (nodeIndex == 0 || nodeIndex == parentChildren.Count - 1)
                                    {
                                        PdfDictionary parent = (PdfDictionary)parentChildren.Parent;
                                        UpdateNodeLimits(parent, parentChildren, PdfName.Kids);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            return(true);
                        }
                    }
                }
                else // Intermediate node.
                {
                    int low = 0, high = nodeChildren.Items.Count - nodeChildren.Info.ItemCount;
                    while (true)
                    {
                        if (low > high) // Outside the limit range.
                        {
                            return(false);
                        }

                        int           mid          = (low + high) / 2;
                        PdfReference  kidReference = (PdfReference)nodeChildren.Items[mid];
                        PdfDictionary kid          = (PdfDictionary)kidReference.DataObject;
                        PdfArray      limits       = (PdfArray)kid.Resolve(PdfName.Limits);
                        if (key.CompareTo(limits[0]) < 0) // Before the lower limit.
                        {
                            high = mid - 1;
                        }
                        else if (key.CompareTo(limits[1]) > 0) // After the upper limit.
                        {
                            low = mid + 1;
                        }
                        else // Limit range matched.
                        {
                            Children kidChildren = Children.Get(kid, pairsKey);
                            if (kidChildren.IsUndersized())
                            {
                                /*
                                 * NOTE: Rebalancing is required as minimum node size invariant is violated.
                                 */
                                PdfDictionary leftSibling         = null;
                                Children      leftSiblingChildren = null;
                                if (mid > 0)
                                {
                                    leftSibling         = (PdfDictionary)nodeChildren.Items.Resolve(mid - 1);
                                    leftSiblingChildren = Children.Get(leftSibling, pairsKey);
                                }
                                PdfDictionary rightSibling         = null;
                                Children      rightSiblingChildren = null;
                                if (mid < nodeChildren.Items.Count - 1)
                                {
                                    rightSibling         = (PdfDictionary)nodeChildren.Items.Resolve(mid + 1);
                                    rightSiblingChildren = Children.Get(rightSibling, pairsKey);
                                }

                                if (leftSiblingChildren != null && !leftSiblingChildren.IsUndersized())
                                {
                                    // Move the last child subtree of the left sibling to be the first child subtree of the kid!
                                    for (int index = 0, endIndex = leftSiblingChildren.Info.ItemCount; index < endIndex; index++)
                                    {
                                        int             itemIndex = leftSiblingChildren.Items.Count - 1;
                                        PdfDirectObject item      = leftSiblingChildren.Items[itemIndex];
                                        leftSiblingChildren.Items.RemoveAt(itemIndex);
                                        kidChildren.Items.Insert(0, item);
                                    }
                                    // Update left sibling's key limits!
                                    UpdateNodeLimits(leftSiblingChildren);
                                }
                                else if (rightSiblingChildren != null && !rightSiblingChildren.IsUndersized())
                                {
                                    // Move the first child subtree of the right sibling to be the last child subtree of the kid!
                                    for (int index = 0, endIndex = rightSiblingChildren.Info.ItemCount; index < endIndex; index++)
                                    {
                                        int             itemIndex = 0;
                                        PdfDirectObject item      = rightSiblingChildren.Items[itemIndex];
                                        rightSiblingChildren.Items.RemoveAt(itemIndex);
                                        kidChildren.Items.Add(item);
                                    }
                                    // Update right sibling's key limits!
                                    UpdateNodeLimits(rightSiblingChildren);
                                }
                                else
                                {
                                    if (leftSibling != null)
                                    {
                                        // Merging with the left sibling...
                                        for (int index = leftSiblingChildren.Items.Count; index-- > 0;)
                                        {
                                            PdfDirectObject item = leftSiblingChildren.Items[index];
                                            leftSiblingChildren.Items.RemoveAt(index);
                                            kidChildren.Items.Insert(0, item);
                                        }
                                        nodeChildren.Items.RemoveAt(mid - 1);
                                        leftSibling.Reference.Delete();
                                    }
                                    else if (rightSibling != null)
                                    {
                                        // Merging with the right sibling...
                                        for (int index = rightSiblingChildren.Items.Count; index-- > 0;)
                                        {
                                            int             itemIndex = 0;
                                            PdfDirectObject item      = rightSiblingChildren.Items[itemIndex];
                                            rightSiblingChildren.Items.RemoveAt(itemIndex);
                                            kidChildren.Items.Add(item);
                                        }
                                        nodeChildren.Items.RemoveAt(mid + 1);
                                        rightSibling.Reference.Delete();
                                    }
                                    if (nodeChildren.Items.Count == 1)
                                    {
                                        // Collapsing root...
                                        nodeChildren.Items.RemoveAt(0);
                                        for (int index = kidChildren.Items.Count; index-- > 0;)
                                        {
                                            int             itemIndex = 0;
                                            PdfDirectObject item      = kidChildren.Items[itemIndex];
                                            kidChildren.Items.RemoveAt(itemIndex);
                                            nodeChildren.Items.Add(item);
                                        }
                                        kid.Reference.Delete();
                                        kid          = node;
                                        kidReference = kid.Reference;
                                        kidChildren  = nodeChildren;
                                    }
                                }
                                // Update key limits!
                                UpdateNodeLimits(kidChildren);
                            }
                            // Go down one level!
                            nodeReferenceStack.Push(kidReference);
                            node = kid;
                            break;
                        }
                    }
                }
            }
        }
Exemple #7
0
 protected NumberTree(
     PdfDirectObject baseObject
     ) : base(baseObject)
 {
 }
Exemple #8
0
            private KeyValuePair <TKey, TValue>?GetNext(
                )
            {
                /*
                 * NOTE: Algorithm:
                 * 1. [Vertical, down] We have to go downward the name tree till we reach
                 * a names collection (leaf node).
                 * 2. [Horizontal] Then we iterate across the names collection.
                 * 3. [Vertical, up] When leaf-nodes scan is complete, we go upward solving
                 * parent nodes, repeating step 1.
                 */
                while (true)
                {
                    if (names == null)
                    {
                        if (kids == null ||
                            kids.Count == levelIndex) // Kids subtree complete.
                        {
                            if (levels.Count == 0)
                            {
                                return(null);
                            }

                            // 3. Go upward one level.
                            // Restore current level!
                            object[] level = levels.Pop();
                            container  = (PdfIndirectObject)level[0];
                            kids       = (PdfArray)level[1];
                            levelIndex = ((int)level[2]) + 1; // Next node (partially scanned level).
                        }
                        else // Kids subtree incomplete.
                        {
                            // 1. Go downward one level.
                            // Save current level!
                            levels.Push(new object[] { container, kids, levelIndex });

                            // Move downward!
                            PdfReference kidReference = (PdfReference)kids[levelIndex];
                            container = kidReference.IndirectObject;
                            PdfDictionary   kid        = (PdfDictionary)kidReference.DataObject;
                            PdfDirectObject kidsObject = kid[PdfName.Kids];
                            if (kidsObject == null) // Leaf node.
                            {
                                PdfDirectObject namesObject = kid[PdfName.Names];
                                if (namesObject is PdfReference)
                                {
                                    container = ((PdfReference)namesObject).IndirectObject;
                                }
                                names = (PdfArray)namesObject.Resolve();
                                kids  = null;
                            }
                            else // Intermediate node.
                            {
                                if (kidsObject is PdfReference)
                                {
                                    container = ((PdfReference)kidsObject).IndirectObject;
                                }
                                kids = (PdfArray)kidsObject.Resolve();
                            }
                            levelIndex = 0; // First node (new level).
                        }
                    }
                    else
                    {
                        if (names.Count == levelIndex) // Names complete.
                        {
                            names = null;
                        }
                        else // Names incomplete.
                        {
                            // 2. Object found.
                            TKey   key   = (TKey)names[levelIndex];
                            TValue value = tree.WrapValue(names[levelIndex + 1]);
                            levelIndex += 2;

                            return(new KeyValuePair <TKey, TValue>(key, value));
                        }
                    }
                }
            }
Exemple #9
0
 //TODO:integrate with the container update infrastructure (see other PdfObjectWrapper subclass implementations)!!
 public Rectangle(
     PdfDirectObject baseObject
     ) : base(Normalize((PdfArray)File.Resolve(baseObject)), null)
 {
 }
Exemple #10
0
 /**
  * <summary>Wraps a base object within its corresponding high-level representation.</summary>
  */
 protected abstract TValue Wrap(
     PdfDirectObject baseObject,
     PdfIndirectObject container,
     PdfString name
     );
Exemple #11
0
        public TValue this[
            PdfString key
        ]
        {
            get
            {
                PdfDirectObject containerObject = BaseObject;
                PdfDictionary   parent          = BaseDataObject;
                while (true)
                {
                    PdfDirectObject namesObject = parent[PdfName.Names];
                    if (namesObject == null) // Intermediate node.
                    {
                        PdfArray kids = (PdfArray)File.Resolve(parent[PdfName.Kids]);
                        int      low = 0, high = kids.Count - 1;
                        while (true)
                        {
                            if (low > high)
                            {
                                return(null);
                            }

                            int             mid       = (low + high) / 2;
                            PdfDirectObject kidObject = kids[mid];
                            PdfDictionary   kid       = (PdfDictionary)File.Resolve(kidObject);
                            PdfArray        limits    = (PdfArray)File.Resolve(kid[PdfName.Limits]);
                            // Compare to the lower limit!
                            int comparison = key.CompareTo(
                                (PdfString)limits[0]
                                );
                            if (comparison < 0)
                            {
                                high = mid - 1;
                            }
                            else
                            {
                                // Compare to the upper limit!
                                comparison = key.CompareTo(
                                    (PdfString)limits[1]
                                    );
                                if (comparison > 0)
                                {
                                    low = mid + 1;
                                }
                                else
                                {
                                    // Go down one level!
                                    containerObject = kidObject; // NOTE: Node children MUST be indirectly referenced.
                                    parent          = kid;
                                    break;
                                }
                            }
                        }
                    }
                    else // Leaf node.
                    {
                        if (namesObject is PdfReference)
                        {
                            containerObject = namesObject;
                        }

                        PdfArray names = (PdfArray)File.Resolve(namesObject);
                        int      low = 0, high = names.Count;
                        while (true)
                        {
                            if (low > high)
                            {
                                return(null);
                            }

                            int mid        = (mid = ((low + high) / 2)) - (mid % 2);
                            int comparison = key.CompareTo(
                                (PdfString)names[mid]
                                );
                            if (comparison < 0)
                            {
                                high = mid - 2;
                            }
                            else if (comparison > 0)
                            {
                                low = mid + 2;
                            }
                            else
                            {
                                // We got it!
                                return(Wrap(
                                           names[mid + 1],
                                           ((PdfReference)containerObject).IndirectObject,
                                           (PdfString)names[mid]
                                           ));
                            }
                        }
                    }
                }
            }
            set
            { Add(key, value, true); }
        }
Exemple #12
0
 /**
  * <summary>Wraps an existing base array using the default wrapper for wrapping its items.
  * </summary>
  * <param name="itemClass">Item class.</param>
  * <param name="baseObject">Base array. MUST be a {@link PdfReference reference} every time
  * available.</param>
  */
 public static Array <T> Wrap <T>(
     PdfDirectObject baseObject
     ) where T : TItem
 {
     return(baseObject != null ? new Array <T>(baseObject) : null);
 }
Exemple #13
0
 public T Wrap(
     PdfDirectObject baseObject
     )
 {
     return((T)itemConstructor.Invoke(null, new object[] { baseObject }));
 }