122 lines
3.4 KiB
Java
Raw Normal View History

package org.apache.poi.hpsf;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
@Internal
class Array
{
static class ArrayDimension
{
static final int SIZE = 8;
private int _indexOffset;
private long _size;
ArrayDimension( byte[] data, int offset )
{
_size = LittleEndian.getUInt( data, offset );
_indexOffset = LittleEndian.getInt( data, offset
+ LittleEndian.INT_SIZE );
}
}
static class ArrayHeader
{
private ArrayDimension[] _dimensions;
private int _type;
ArrayHeader( byte[] data, int startOffset )
{
int offset = startOffset;
_type = LittleEndian.getInt( data, offset );
offset += LittleEndian.INT_SIZE;
long numDimensionsUnsigned = LittleEndian.getUInt( data, offset );
offset += LittleEndian.INT_SIZE;
if ( !( 1 <= numDimensionsUnsigned && numDimensionsUnsigned <= 31 ) )
throw new IllegalPropertySetDataException(
"Array dimension number " + numDimensionsUnsigned
+ " is not in [1; 31] range" );
int numDimensions = (int) numDimensionsUnsigned;
_dimensions = new ArrayDimension[numDimensions];
for ( int i = 0; i < numDimensions; i++ )
{
_dimensions[i] = new ArrayDimension( data, offset );
offset += ArrayDimension.SIZE;
}
}
long getNumberOfScalarValues()
{
long result = 1;
for ( ArrayDimension dimension : _dimensions )
result *= dimension._size;
return result;
}
int getSize()
{
return LittleEndian.INT_SIZE * 2 + _dimensions.length
* ArrayDimension.SIZE;
}
int getType()
{
return _type;
}
}
private ArrayHeader _header;
private TypedPropertyValue[] _values;
Array()
{
}
Array( final byte[] data, final int offset )
{
read( data, offset );
}
int read( final byte[] data, final int startOffset )
{
int offset = startOffset;
_header = new ArrayHeader( data, offset );
offset += _header.getSize();
long numberOfScalarsLong = _header.getNumberOfScalarValues();
if ( numberOfScalarsLong > Integer.MAX_VALUE )
throw new UnsupportedOperationException(
"Sorry, but POI can't store array of properties with size of "
+ numberOfScalarsLong + " in memory" );
int numberOfScalars = (int) numberOfScalarsLong;
_values = new TypedPropertyValue[numberOfScalars];
final 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;
}
}