public int Read(byte[] data, int startOffset) { int offset = startOffset; _header = new ArrayHeader(data, offset); offset += _header.Size; long numberOfScalarsLong = _header.NumberOfScalarValues; if (numberOfScalarsLong > int.MaxValue) { throw new InvalidOperationException( "Sorry, but POI can't store array of properties with size of " + numberOfScalarsLong + " in memory"); } int numberOfScalars = (int)numberOfScalarsLong; _values = new TypedPropertyValue[numberOfScalars]; int type = _header._type; if (type == Variant.VT_VARIANT) { for (int i = 0; i < numberOfScalars; i++) { TypedPropertyValue typedPropertyValue = new TypedPropertyValue(); offset += typedPropertyValue.Read(data, offset); } } else { for (int i = 0; i < numberOfScalars; i++) { TypedPropertyValue typedPropertyValue = new TypedPropertyValue( type, null); offset += typedPropertyValue.ReadValuePadded(data, offset); } } return(offset - startOffset); }
public int Read(byte[] data, int startOffset) { int offset = startOffset; long longLength = LittleEndian.GetUInt(data, offset); offset += LittleEndian.INT_SIZE; if (longLength > int.MaxValue) { throw new InvalidOperationException("Vector is too long -- " + longLength); } int length = (int)longLength; _values = new TypedPropertyValue[length]; if (_type == Variant.VT_VARIANT) { for (int i = 0; i < length; i++) { TypedPropertyValue value = new TypedPropertyValue(); offset += value.Read(data, offset); _values[i] = value; } } else { for (int i = 0; i < length; i++) { TypedPropertyValue value = new TypedPropertyValue(_type, null); // be aware: not padded here offset += value.ReadValue(data, offset); _values[i] = value; } } return(offset - startOffset); }
/// <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) { TypedPropertyValue typedPropertyValue = new TypedPropertyValue( (int)type, null); int unpadded; try { unpadded = typedPropertyValue.ReadValue(src, offset); } catch (InvalidOperationException) { int propLength = Math.Min(length, src.Length - offset); byte[] v = new byte[propLength]; System.Array.Copy(src, offset, v, 0, propLength); throw new ReadingNotSupportedException(type, v); } switch ((int)type) { case Variant.VT_EMPTY: case Variant.VT_I4: case Variant.VT_I8: case Variant.VT_R8: /* * we have more property types that can be converted into Java * objects, but current API need to be preserved, and it returns * other types as byte arrays. In future major versions it shall be * changed -- sergey */ return(typedPropertyValue.Value); case Variant.VT_I2: { /* * also for backward-compatibility with prev. versions of POI * --sergey */ return((short)typedPropertyValue.Value); } case Variant.VT_FILETIME: { Filetime filetime = (Filetime)typedPropertyValue.Value; return(Util.FiletimeToDate((int)filetime.High, (int)filetime.Low)); } case Variant.VT_LPSTR: { CodePageString string1 = (CodePageString)typedPropertyValue.Value; return(string1.GetJavaValue(codepage)); } case Variant.VT_LPWSTR: { UnicodeString string1 = (UnicodeString)typedPropertyValue.Value; return(string1.ToJavaString()); } 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; // } // final byte[] v = new byte[l1]; // System.arraycopy(src, o1, v, 0, v.length); // value = v; // break; ClipboardData clipboardData = (ClipboardData)typedPropertyValue.Value; return(clipboardData.ToByteArray()); } case Variant.VT_BOOL: { VariantBool bool1 = (VariantBool)typedPropertyValue.Value; return((bool)bool1.Value); } default: { /* * it is not very good, but what can do without breaking current * API? --sergey */ byte[] v = new byte[unpadded]; System.Array.Copy(src, offset, v, 0, unpadded); throw new ReadingNotSupportedException(type, v); } } }