Пример #1
0
        /**
         * Checks whether this section is equal To another object. The result Is
         * <c>false</c> if one of the the following conditions holds:
         *
         * <ul>
         *
         * <li>The other object is not a {@link Section}.</li>
         *
         * <li>The format IDs of the two sections are not equal.</li>
         *
         * <li>The sections have a different number of properties. However,
         * properties with ID 1 (codepage) are not counted.</li>
         *
         * <li>The other object is not a {@link Section}.</li>
         *
         * <li>The properties have different values. The order of the properties
         * is irrelevant.</li>
         *
         * </ul>
         *
         * @param o The object To Compare this section with
         * @return <c>true</c> if the objects are equal, <c>false</c> if
         * not
         */
        public override bool Equals(Object o)
        {
            if (o == null || !(o is Section))
            {
                return(false);
            }
            Section s = (Section)o;

            if (!s.FormatID.Equals(FormatID))
            {
                return(false);
            }

            /* Compare all properties except 0 and 1 as they must be handled
             * specially. */
            Property[] pa1 = new Property[Properties.Length];
            Property[] pa2 = new Property[s.Properties.Length];
            System.Array.Copy(Properties, 0, pa1, 0, pa1.Length);
            System.Array.Copy(s.Properties, 0, pa2, 0, pa2.Length);

            /* Extract properties 0 and 1 and Remove them from the copy of the
             * arrays. */
            Property p10 = null;
            Property p20 = null;

            for (int i = 0; i < pa1.Length; i++)
            {
                long id = pa1[i].ID;
                if (id == 0)
                {
                    p10 = pa1[i];
                    pa1 = Remove(pa1, i);
                    i--;
                }
                if (id == 1)
                {
                    // p11 = pa1[i];
                    pa1 = Remove(pa1, i);
                    i--;
                }
            }
            for (int i = 0; i < pa2.Length; i++)
            {
                long id = pa2[i].ID;
                if (id == 0)
                {
                    p20 = pa2[i];
                    pa2 = Remove(pa2, i);
                    i--;
                }
                if (id == 1)
                {
                    // p21 = pa2[i];
                    pa2 = Remove(pa2, i);
                    i--;
                }
            }

            /* If the number of properties (not counting property 1) is unequal the
             * sections are unequal. */
            if (pa1.Length != pa2.Length)
            {
                return(false);
            }

            /* If the dictionaries are unequal the sections are unequal. */
            bool dictionaryEqual = true;

            if (p10 != null && p20 != null)
            {
                //tony qu fixed this issue
                Hashtable a = (Hashtable)p10.Value;
                Hashtable b = (Hashtable)p20.Value;
                dictionaryEqual = a.Count == b.Count;
            }
            else if (p10 != null || p20 != null)
            {
                dictionaryEqual = false;
            }
            if (!dictionaryEqual)
            {
                return(false);
            }
            else
            {
                return(Util.AreEqual(pa1, pa2));
            }
        }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MutableProperty"/> class.
 /// </summary>
 /// <param name="p">The property To copy.</param>
 public MutableProperty(Property p)
 {
     this.ID=p.ID;
     this.Type=p.Type;
     this.Value=p.Value;
 }
Пример #3
0
        /// <summary>
        /// Creates a {@link Section} instance from a byte array.
        /// </summary>
        /// <param name="src">Contains the complete property Set stream.</param>
        /// <param name="offset">The position in the stream that points To the
        /// section's format ID.</param>
        public Section(byte[] src, int offset)
        {
            int o1 = offset;

            /*
             * Read the format ID.
             */
            formatID = new ClassID(src, o1);
            o1      += ClassID.LENGTH;

            /*
             * Read the offset from the stream's start and positions To
             * the section header.
             */
            this.offset = LittleEndian.GetUInt(src, o1);
            o1          = (int)this.offset;

            /*
             * Read the section Length.
             */
            size = (int)LittleEndian.GetUInt(src, o1);
            o1  += LittleEndianConsts.INT_SIZE;

            /*
             * Read the number of properties.
             */
            int propertyCount = (int)LittleEndian.GetUInt(src, o1);

            o1 += LittleEndianConsts.INT_SIZE;

            /*
             * Read the properties. The offset is positioned at the first
             * entry of the property list. There are two problems:
             *
             * 1. For each property we have To Find out its Length. In the
             *    property list we Find each property's ID and its offset relative
             *    To the section's beginning. Unfortunately the properties in the
             *    property list need not To be in ascending order, so it is not
             *    possible To calculate the Length as
             *    (offset of property(i+1) - offset of property(i)). Before we can
             *    that we first have To sort the property list by ascending offsets.
             *
             * 2. We have To Read the property with ID 1 before we Read other
             *    properties, at least before other properties containing strings.
             *    The reason is that property 1 specifies the codepage. If it Is
             *    1200, all strings are in Unicode. In other words: Before we can
             *    Read any strings we have To know whether they are in Unicode or
             *    not. Unfortunately property 1 is not guaranteed To be the first in
             *    a section.
             *
             *    The algorithm below Reads the properties in two passes: The first
             *    one looks for property ID 1 and extracts the codepage number. The
             *    seconds pass Reads the other properties.
             */
            properties = new Property[propertyCount];

            /* Pass 1: Read the property list. */
            int               pass1OffSet  = o1;
            ArrayList         propertyList = new ArrayList(propertyCount);
            PropertyListEntry ple;

            for (int i = 0; i < properties.Length; i++)
            {
                ple = new PropertyListEntry();

                /* Read the property ID. */
                ple.id       = (int)LittleEndian.GetUInt(src, pass1OffSet);
                pass1OffSet += LittleEndianConsts.INT_SIZE;

                /* OffSet from the section's start. */
                ple.offset   = (int)LittleEndian.GetUInt(src, pass1OffSet);
                pass1OffSet += LittleEndianConsts.INT_SIZE;

                /* Add the entry To the property list. */
                propertyList.Add(ple);
            }

            /* Sort the property list by ascending offsets: */
            propertyList.Sort();

            /* Calculate the properties' Lengths. */
            for (int i = 0; i < propertyCount - 1; i++)
            {
                PropertyListEntry ple1 =
                    (PropertyListEntry)propertyList[i];
                PropertyListEntry ple2 =
                    (PropertyListEntry)propertyList[i + 1];
                ple1.Length = ple2.offset - ple1.offset;
            }
            if (propertyCount > 0)
            {
                ple        = (PropertyListEntry)propertyList[propertyCount - 1];
                ple.Length = size - ple.offset;
                //if (ple.Length <= 0)
                //{
                //    StringBuilder b = new StringBuilder();
                //    b.Append("The property Set claims To have a size of ");
                //    b.Append(size);
                //    b.Append(" bytes. However, it exceeds ");
                //    b.Append(ple.offset);
                //    b.Append(" bytes.");
                //    throw new IllegalPropertySetDataException(b.ToString());
                //}
            }

            /* Look for the codepage. */
            int codepage = -1;

            for (IEnumerator i = propertyList.GetEnumerator();
                 codepage == -1 && i.MoveNext();)
            {
                ple = (PropertyListEntry)i.Current;

                /* Read the codepage if the property ID is 1. */
                if (ple.id == PropertyIDMap.PID_CODEPAGE)
                {
                    /* Read the property's value type. It must be
                     * VT_I2. */
                    int  o    = (int)(this.offset + ple.offset);
                    long type = LittleEndian.GetUInt(src, o);
                    o += LittleEndianConsts.INT_SIZE;

                    if (type != Variant.VT_I2)
                    {
                        throw new HPSFRuntimeException
                                  ("Value type of property ID 1 is not VT_I2 but " +
                                  type + ".");
                    }

                    /* Read the codepage number. */
                    codepage = LittleEndian.GetUShort(src, o);
                }
            }

            /* Pass 2: Read all properties - including the codepage property,
             * if available. */
            int i1 = 0;

            for (IEnumerator i = propertyList.GetEnumerator(); i.MoveNext();)
            {
                ple = (PropertyListEntry)i.Current;
                Property p = new Property(ple.id, src,
                                          this.offset + ple.offset,
                                          ple.Length, codepage);
                if (p.ID == PropertyIDMap.PID_CODEPAGE)
                {
                    p = new Property(p.ID, p.Type, codepage);
                }
                properties[i1++] = p;
            }

            /*
             * Extract the dictionary (if available).
             * Tony changed the logic
             */
            this.dictionary = (IDictionary)GetProperty(0);
        }