Example #1
0
        public void TestGetDouble()
        {
            Assert.AreEqual(_DOUBLEs[0], LittleEndian.GetDouble(_DOUBLE_array), 0.000001);
            Assert.AreEqual(_DOUBLEs[1], LittleEndian.GetDouble(_DOUBLE_array, LittleEndianConstants.DOUBLE_SIZE), 0.000001);
            Assert.IsTrue(Double.IsNaN(LittleEndian.GetDouble(_nan_DOUBLE_array)));

            double nan = LittleEndian.GetDouble(_nan_DOUBLE_array);

            byte[] data = new byte[8];
            LittleEndian.PutDouble(data, nan);
            for (int i = 0; i < data.Length; i++)
            {
                byte b = data[i];
                Assert.AreEqual(data[i], _nan_DOUBLE_array[i]);
            }
        }
Example #2
0
        /// <summary>
        /// Reads a variant type from a byte array
        /// </summary>
        /// <param name="src">The byte array</param>
        /// <param name="offset">The offset in the byte array where the variant starts</param>
        /// <param name="Length">The Length of the variant including the variant type field</param>
        /// <param name="type">The variant type To Read</param>
        /// <param name="codepage">The codepage To use for non-wide strings</param>
        /// <returns>A Java object that corresponds best To the variant field. For
        /// example, a VT_I4 is returned as a {@link long}, a VT_LPSTR as a
        /// {@link String}.</returns>
        public static Object Read(byte[] src, int offset,
                                  int Length, long type,
                                  int codepage)
        {
            Object value;
            int    o1    = offset;
            int    l1    = Length - LittleEndianConsts.INT_SIZE;
            long   lType = type;

            /* Instead of trying To Read 8-bit characters from a Unicode string,
             * Read 16-bit characters. */
            if (codepage == (int)Constants.CP_UNICODE && type == Variant.VT_LPSTR)
            {
                lType = Variant.VT_LPWSTR;
            }

            switch ((int)lType)
            {
            case Variant.VT_EMPTY:
            {
                value = null;
                break;
            }

            case Variant.VT_I2:
            {
                /*
                 * Read a short. In Java it is represented as an
                 * Integer object.
                 */
                value = LittleEndian.GetShort(src, o1);
                break;
            }

            case Variant.VT_I4:
            {
                /*
                 * Read a word. In Java it is represented as an
                 * Integer object.
                 */
                value = LittleEndian.GetInt(src, o1);
                break;
            }

            case Variant.VT_I8:
            {
                /*
                 * Read a double word. In Java it is represented as a
                 * long object.
                 */
                value = LittleEndian.GetLong(src, o1);
                break;
            }

            case Variant.VT_R8:
            {
                /*
                 * Read an eight-byte double value. In Java it is represented as
                 * a Double object.
                 */
                value = LittleEndian.GetDouble(src, o1);
                break;
            }

            case Variant.VT_FILETIME:
            {
                /*
                 * Read a FILETIME object. In Java it is represented
                 * as a Date object.
                 */
                int low = LittleEndian.GetInt(src, o1);
                o1 += LittleEndianConsts.INT_SIZE;
                int high = LittleEndian.GetInt(src, o1);
                if (low == 0 && high == 0)
                {
                    value = null;
                }
                else
                {
                    value = Util.FiletimeToDate(high, low);
                }
                break;
            }

            case Variant.VT_LPSTR:
            {
                /*
                 * Read a byte string. In Java it is represented as a
                 * String object. The 0x00 bytes at the end must be
                 * stripped.
                 */
                int  first = o1 + LittleEndianConsts.INT_SIZE;
                long last  = first + LittleEndian.GetUInt(src, o1) - 1;
                o1 += LittleEndianConsts.INT_SIZE;
                while (src[(int)last] == 0 && first <= last)
                {
                    last--;
                }
                int l = (int)(last - first + 1);
                value = codepage != -1 ?
                        Encoding.GetEncoding(codepage).GetString(src, first, l) :
                        Encoding.UTF8.GetString(src, first, l);
                break;
            }

            case Variant.VT_LPWSTR:
            {
                /*
                 * Read a Unicode string. In Java it is represented as
                 * a String object. The 0x00 bytes at the end must be
                 * stripped.
                 */
                int  first = o1 + LittleEndianConsts.INT_SIZE;
                long last  = first + LittleEndian.GetUInt(src, o1) - 1;
                long l     = last - first;
                o1 += LittleEndianConsts.INT_SIZE;
                StringBuilder b = new StringBuilder((int)(last - first));
                for (int i = 0; i <= l; i++)
                {
                    int  i1   = o1 + (i * 2);
                    int  i2   = i1 + 1;
                    int  high = src[i2] << 8;
                    int  low  = src[i1] & 0x00ff;
                    char c    = (char)(high | low);
                    b.Append(c);
                }
                /* Strip 0x00 characters from the end of the string: */
                while (b.Length > 0 && b[b.Length - 1] == 0x00)
                {
                    b.Length = b.Length - 1;
                }
                value = b.ToString();
                break;
            }

            case Variant.VT_CF:
            {
                if (l1 < 0)
                {
                    /**
                     *  YK: reading the ClipboardData packet (VT_CF) is not quite correct.
                     *  The size of the data is determined by the first four bytes of the packet
                     *  while the current implementation calculates it in the Section constructor.
                     *  Test files in Bugzilla 42726 and 45583 clearly show that this approach does not always work.
                     *  The workaround below attempts to gracefully handle such cases instead of throwing exceptions.
                     *
                     *  August 20, 2009
                     */
                    l1  = LittleEndian.GetInt(src, o1);
                    o1 += LittleEndian.INT_SIZE;
                }
                byte[] v = new byte[l1];
                for (int i = 0; i < l1; i++)
                {
                    v[i] = src[(o1 + i)];
                }
                value = v;
                break;
            }

            case Variant.VT_BOOL:
            {
                /*
                 * The first four bytes in src, from src[offset] To
                 * src[offset + 3] contain the DWord for VT_BOOL, so
                 * skip it, we don't need it.
                 */
                // int first = offset + LittleEndianConstants.INT_SIZE;
                long boolean = LittleEndian.GetUInt(src, o1);
                if (boolean != 0)
                {
                    value = true;
                }
                else
                {
                    value = false;
                }
                break;
            }

            default:
            {
                byte[] v = new byte[l1];
                for (int i = 0; i < l1; i++)
                {
                    v[i] = src[(o1 + i)];
                }
                throw new ReadingNotSupportedException(type, v);
            }
            }
            return(value);
        }
Example #3
0
        public int ReadValue(byte[] data, int offset)
        {
            switch (_type)
            {
            case Variant.VT_EMPTY:
            case Variant.VT_NULL:
                _value = null;
                return(0);

            case Variant.VT_I2:
                _value = LittleEndian.GetShort(data, offset);
                return(4);

            case Variant.VT_I4:
                _value = LittleEndian.GetInt(data, offset);
                return(4);

            case Variant.VT_R4:
                _value = LittleEndian.GetShort(data, offset);
                return(4);

            case Variant.VT_R8:
                _value = LittleEndian.GetDouble(data, offset);
                return(8);

            case Variant.VT_CY:
                _value = new Currency(data, offset);
                return(Currency.SIZE);

            case Variant.VT_DATE:
                _value = new Date(data, offset);
                return(Date.SIZE);

            case Variant.VT_BSTR:
                _value = new CodePageString(data, offset);
                return(((CodePageString)_value).Size);

            case Variant.VT_ERROR:
                _value = LittleEndian.GetUInt(data, offset);
                return(4);

            case Variant.VT_BOOL:
                _value = new VariantBool(data, offset);
                return(VariantBool.SIZE);

            case Variant.VT_DECIMAL:
                _value = new Decimal(data, offset);
                return(Decimal.SIZE);

            case Variant.VT_I1:
                _value = data[offset];
                return(1);

            case Variant.VT_UI1:
                _value = LittleEndian.GetUByte(data, offset);
                return(2);

            case Variant.VT_UI2:
                _value = LittleEndian.GetUShort(data, offset);
                return(4);

            case Variant.VT_UI4:
                _value = LittleEndian.GetUInt(data, offset);
                return(4);

            case Variant.VT_I8:
                _value = LittleEndian.GetLong(data, offset);
                return(8);

            case Variant.VT_UI8:
                _value = LittleEndian.GetByteArray(data, offset, 8);
                return(8);

            case Variant.VT_INT:
                _value = LittleEndian.GetInt(data, offset);
                return(4);

            case Variant.VT_UINT:
                _value = LittleEndian.GetUInt(data, offset);
                return(4);

            case Variant.VT_LPSTR:
                _value = new CodePageString(data, offset);
                return(((CodePageString)_value).Size);

            case Variant.VT_LPWSTR:
                _value = new UnicodeString(data, offset);
                return(((UnicodeString)_value).Size);

            case Variant.VT_FILETIME:
                _value = new Filetime(data, offset);
                return(Filetime.SIZE);

            case Variant.VT_BLOB:
                _value = new Blob(data, offset);
                return(((Blob)_value).Size);

            case Variant.VT_STREAM:
            case Variant.VT_STORAGE:
            case Variant.VT_STREAMED_OBJECT:
            case Variant.VT_STORED_OBJECT:
                _value = new IndirectPropertyName(data, offset);
                return(((IndirectPropertyName)_value).Size);

            case Variant.VT_BLOB_OBJECT:
                _value = new Blob(data, offset);
                return(((Blob)_value).Size);

            case Variant.VT_CF:
                _value = new ClipboardData(data, offset);
                return(((ClipboardData)_value).Size);

            case Variant.VT_CLSID:
                _value = new GUID(data, offset);
                return(GUID.SIZE);

            case Variant.VT_VERSIONED_STREAM:
                _value = new VersionedStream(data, offset);
                return(((VersionedStream)_value).Size);

            case Variant.VT_VECTOR | Variant.VT_I2:
            case Variant.VT_VECTOR | Variant.VT_I4:
            case Variant.VT_VECTOR | Variant.VT_R4:
            case Variant.VT_VECTOR | Variant.VT_R8:
            case Variant.VT_VECTOR | Variant.VT_CY:
            case Variant.VT_VECTOR | Variant.VT_DATE:
            case Variant.VT_VECTOR | Variant.VT_BSTR:
            case Variant.VT_VECTOR | Variant.VT_ERROR:
            case Variant.VT_VECTOR | Variant.VT_BOOL:
            case Variant.VT_VECTOR | Variant.VT_VARIANT:
            case Variant.VT_VECTOR | Variant.VT_I1:
            case Variant.VT_VECTOR | Variant.VT_UI1:
            case Variant.VT_VECTOR | Variant.VT_UI2:
            case Variant.VT_VECTOR | Variant.VT_UI4:
            case Variant.VT_VECTOR | Variant.VT_I8:
            case Variant.VT_VECTOR | Variant.VT_UI8:
            case Variant.VT_VECTOR | Variant.VT_LPSTR:
            case Variant.VT_VECTOR | Variant.VT_LPWSTR:
            case Variant.VT_VECTOR | Variant.VT_FILETIME:
            case Variant.VT_VECTOR | Variant.VT_CF:
            case Variant.VT_VECTOR | Variant.VT_CLSID:
                _value = new Vector((short)(_type & 0x0FFF));
                return(((Vector)_value).Read(data, offset));

            case Variant.VT_ARRAY | Variant.VT_I2:
            case Variant.VT_ARRAY | Variant.VT_I4:
            case Variant.VT_ARRAY | Variant.VT_R4:
            case Variant.VT_ARRAY | Variant.VT_R8:
            case Variant.VT_ARRAY | Variant.VT_CY:
            case Variant.VT_ARRAY | Variant.VT_DATE:
            case Variant.VT_ARRAY | Variant.VT_BSTR:
            case Variant.VT_ARRAY | Variant.VT_ERROR:
            case Variant.VT_ARRAY | Variant.VT_BOOL:
            case Variant.VT_ARRAY | Variant.VT_VARIANT:
            case Variant.VT_ARRAY | Variant.VT_DECIMAL:
            case Variant.VT_ARRAY | Variant.VT_I1:
            case Variant.VT_ARRAY | Variant.VT_UI1:
            case Variant.VT_ARRAY | Variant.VT_UI2:
            case Variant.VT_ARRAY | Variant.VT_UI4:
            case Variant.VT_ARRAY | Variant.VT_INT:
            case Variant.VT_ARRAY | Variant.VT_UINT:
                _value = new Array();
                return(((Array)_value).Read(data, offset));

            default:
                throw new InvalidOperationException(
                          "Unknown (possibly, incorrect) TypedPropertyValue type: "
                          + _type);
            }
        }