예제 #1
0
파일: ClassID.cs 프로젝트: leo0530/Zephyr
        /// <summary>
        /// Checks whether this ClassID is equal to another
        /// object.
        /// </summary>
        /// <param name="o">the object to compare this PropertySet with</param>
        /// <returns>true if the objects are equal, else
        /// false</returns>
        public override bool Equals(Object o)
        {
            if (o == null || !(o is ClassID))
            {
                return(false);
            }
            ClassID cid = (ClassID)o;

            if (bytes.Length != cid.bytes.Length)
            {
                return(false);
            }
            for (int i = 0; i < bytes.Length; i++)
            {
                if (bytes[i] != cid.bytes[i])
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #2
0
 /// <summary>
 /// Sets the section's format ID.
 /// </summary>
 /// <param name="formatID">The section's format ID as a byte array. It components
 /// are in big-endian format.</param>
 public void SetFormatID(byte[] formatID)
 {
     ClassID fid = this.FormatID;
     if (fid == null)
     {
         fid = new ClassID();
         SetFormatID(fid);
     }
     fid.Bytes=formatID;
 }
예제 #3
0
 /// <summary>
 /// Sets the section's format ID.
 /// </summary>
 /// <param name="formatID">The section's format ID</param>
 public void SetFormatID(ClassID formatID)
 {
     this.formatID = formatID;
 }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Property"/> class.
        /// </summary>
        protected Property()
        {
            _raw_data = new byte[POIFSConstants.PROPERTY_SIZE];
            for (int i = 0; i < this._raw_data.Length; i++)
            {
                this._raw_data[i] = _default_fill;
            }
            _name_size         = new ShortField(_name_size_offset);
            _property_type     =
                new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET);
            _node_color        = new ByteField(_node_color_offset);
            _previous_property = new IntegerField(_previous_property_offset,
                                                  _NO_INDEX, _raw_data);
            _next_property     = new IntegerField(_next_property_offset,
                                                  _NO_INDEX, _raw_data);
            _child_property    = new IntegerField(_child_property_offset,
                                                  _NO_INDEX, _raw_data);
            _storage_clsid     = new ClassID(_raw_data,_storage_clsid_offset);
            _user_flags        = new IntegerField(_user_flags_offset, 0, _raw_data);
            _seconds_1         = new IntegerField(_seconds_1_offset, 0,
                                                  _raw_data);
            _days_1            = new IntegerField(_days_1_offset, 0, _raw_data);
            _seconds_2         = new IntegerField(_seconds_2_offset, 0,
                                                  _raw_data);
            _days_2            = new IntegerField(_days_2_offset, 0, _raw_data);
            _start_block       = new IntegerField(_start_block_offset);
            _size              = new IntegerField(_size_offset, 0, _raw_data);
            _index             = _NO_INDEX;

            this.Name="";
            this.NextChild=null;
            this.PreviousChild=null;
        }
예제 #5
0
        /// <summary>
        /// Constructor from byte data
        /// </summary>
        /// <param name="index">index number</param>
        /// <param name="array">byte data</param>
        /// <param name="offset">offset into byte data</param>
        protected Property(int index, byte [] array, int offset)
        {
            _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ];
            System.Array.Copy(array, offset, _raw_data, 0, POIFSConstants.PROPERTY_SIZE);
            _name_size         = new ShortField(_name_size_offset, _raw_data);
            _property_type     =
                new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data);
            _node_color        = new ByteField(_node_color_offset, _raw_data);
            _previous_property = new IntegerField(_previous_property_offset,
                                                  _raw_data);
            _next_property     = new IntegerField(_next_property_offset,
                                                  _raw_data);
            _child_property    = new IntegerField(_child_property_offset,
                                                  _raw_data);
            _storage_clsid     = new ClassID(_raw_data,_storage_clsid_offset);
            _user_flags        = new IntegerField(_user_flags_offset, 0, _raw_data);
            _seconds_1         = new IntegerField(_seconds_1_offset, _raw_data);
            _days_1            = new IntegerField(_days_1_offset, _raw_data);
            _seconds_2         = new IntegerField(_seconds_2_offset, _raw_data);
            _days_2            = new IntegerField(_days_2_offset, _raw_data);
            _start_block       = new IntegerField(_start_block_offset, _raw_data);
            _size              = new IntegerField(_size_offset, _raw_data);
            _index             = index;
            int name_length = (_name_size.Value / LittleEndianConsts.SHORT_SIZE)
                              - 1;

            if (name_length < 1)
            {
                _name = "";
            }
            else
            {
                char[] char_array  = new char[ name_length ];
                int    name_offset = 0;

                for (int j = 0; j < name_length; j++)
                {
                    char_array[ j ] = ( char ) new ShortField(name_offset,
                                                              _raw_data).Value;
                    name_offset     += LittleEndianConsts.SHORT_SIZE;
                }
                _name = new String(char_array, 0, name_length);
            }
            _next_child     = null;
            _previous_child = null;
        }
예제 #6
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);
        }
예제 #7
0
        /// <summary>
        /// Initializes this {@link PropertySet} instance from a byte
        /// array. The method assumes that it has been checked alReady that
        /// the byte array indeed represents a property Set stream. It does
        /// no more checks on its own.
        /// </summary>
        /// <param name="src">Byte array containing the property Set stream</param>
        /// <param name="offset">The property Set stream starts at this offset</param>
        /// <param name="Length">Length of the property Set stream.</param>
        private void init(byte[] src, int offset, int Length)
        {
            /* FIXME (3): Ensure that at most "Length" bytes are Read. */

            /*
             * Read the stream's header fields.
             */
            int o = offset;
            byteOrder = LittleEndian.GetUShort(src, o);
            o += LittleEndianConsts.SHORT_SIZE;
            format = LittleEndian.GetUShort(src, o);
            o += LittleEndianConsts.SHORT_SIZE;
            osVersion = (int)LittleEndian.GetUInt(src, o);
            o += LittleEndianConsts.INT_SIZE;
            classID = new ClassID(src, o);
            o += ClassID.LENGTH;
            int sectionCount = LittleEndian.GetInt(src, o);
            o += LittleEndianConsts.INT_SIZE;
            if (sectionCount < 0)
                throw new HPSFRuntimeException("Section count " + sectionCount +
                                               " is negative.");

            /*
             * Read the sections, which are following the header. They
             * start with an array of section descriptions. Each one
             * consists of a format ID telling what the section Contains
             * and an offset telling how many bytes from the start of the
             * stream the section begins.
             */
            /*
             * Most property Sets have only one section. The Document
             * Summary Information stream has 2. Everything else is a rare
             * exception and is no longer fostered by Microsoft.
             */
            sections = new ArrayList(sectionCount);

            /*
             * Loop over the section descriptor array. Each descriptor
             * consists of a ClassID and a DWord, and we have To increment
             * "offset" accordingly.
             */
            for (int i = 0; i < sectionCount; i++)
            {
                Section s = new Section(src, o);
                o += ClassID.Length + LittleEndianConsts.INT_SIZE;
                sections.Add(s);
            }
        }
예제 #8
0
        /// <summary>
        /// Checks whether a byte array is in the Horrible Property Set
        /// Format.
        /// </summary>
        /// <param name="src">The byte array To check.</param>
        /// <param name="offset">The offset in the byte array.</param>
        /// <param name="Length">The significant number of bytes in the byte
        /// array. Only this number of bytes will be checked.</param>
        /// <returns>
        /// 	<c>true</c> if the byte array is a property Set
        /// stream; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsPropertySetStream(byte[] src,
                                                  int offset,
                                                  int Length)
        {
            /* FIXME (3): Ensure that at most "Length" bytes are Read. */

            /*
             * Read the header fields of the stream. They must always be
             * there.
             */
            int o = offset;
            int byteOrder = LittleEndian.GetUShort(src, o);
            o += LittleEndianConsts.SHORT_SIZE;
            byte[] temp = new byte[LittleEndianConsts.SHORT_SIZE];
            LittleEndian.PutShort(temp, (short)byteOrder);
            if (!Arrays.Equals(temp, BYTE_ORDER_ASSERTION))
                return false;
            int format = LittleEndian.GetUShort(src, o);
            o += LittleEndianConsts.SHORT_SIZE;
            temp = new byte[LittleEndianConsts.SHORT_SIZE];
            LittleEndian.PutShort(temp, (short)format);
            if (!Arrays.Equals(temp, FORMAT_ASSERTION))
                return false;
            long osVersion = LittleEndian.GetUInt(src, offset);
            o += LittleEndianConsts.INT_SIZE;
            ClassID classID = new ClassID(src, offset);
            o += ClassID.LENGTH;
            long sectionCount = LittleEndian.GetUInt(src, o);
            o += LittleEndianConsts.INT_SIZE;
            if (sectionCount < 0)
                return false;
            return true;
        }
예제 #9
0
 /**
  * Writes a 16-byte {@link ClassID} To an output stream.
  *
  * @param out The stream To Write To
  * @param n The value To Write
  * @return The number of bytes written
  * @exception IOException if an I/O error occurs
  */
 public static int WriteToStream(Stream out1, ClassID n)
 {
     byte[] b = new byte[16];
     n.Write(b, 0);
     out1.Write(b, 0, b.Length);
     return b.Length;
 }