add / update documentation
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1143756 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e325f0d084
commit
4abb3c6e51
@ -21,125 +21,129 @@ import java.util.ArrayList;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* common data structure in a Word file. Contains an array of 4 byte ints in
|
||||
* the front that relate to an array of abitrary data structures in the back.
|
||||
* Plex of CPs stored in File (PLCF)
|
||||
*
|
||||
* common data structure in a Word file. Contains an array of 4 byte ints in the
|
||||
* front that relate to an array of arbitrary data structures in the back.
|
||||
*
|
||||
* See page 184 of official documentation for details
|
||||
*
|
||||
* @author Ryan Ackley
|
||||
*/
|
||||
public final class PlexOfCps
|
||||
{
|
||||
private int _count;
|
||||
private int _iMac;
|
||||
private int _offset;
|
||||
private int _sizeOfStruct;
|
||||
private int _cbStruct;
|
||||
private ArrayList<GenericPropertyNode> _props;
|
||||
|
||||
|
||||
public PlexOfCps(int sizeOfStruct)
|
||||
public PlexOfCps( int sizeOfStruct )
|
||||
{
|
||||
_props = new ArrayList<GenericPropertyNode>();
|
||||
_sizeOfStruct = sizeOfStruct;
|
||||
_cbStruct = sizeOfStruct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param size The size in bytes of this PlexOfCps
|
||||
* @param sizeOfStruct The size of the data structure type stored in
|
||||
* this PlexOfCps.
|
||||
* @param cb
|
||||
* The size of PLCF in bytes
|
||||
* @param cbStruct
|
||||
* The size of the data structure type stored in this PlexOfCps.
|
||||
*/
|
||||
public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct)
|
||||
public PlexOfCps( byte[] buf, int start, int cb, int cbStruct )
|
||||
{
|
||||
// Figure out the number we hold
|
||||
_count = (size - 4)/(4 + sizeOfStruct);
|
||||
_iMac = ( cb - 4 ) / ( 4 + cbStruct );
|
||||
|
||||
_sizeOfStruct = sizeOfStruct;
|
||||
_props = new ArrayList<GenericPropertyNode>(_count);
|
||||
_cbStruct = cbStruct;
|
||||
_props = new ArrayList<GenericPropertyNode>( _iMac );
|
||||
|
||||
for (int x = 0; x < _count; x++)
|
||||
for ( int x = 0; x < _iMac; x++ )
|
||||
{
|
||||
_props.add(getProperty(x, buf, start));
|
||||
_props.add( getProperty( x, buf, start ) );
|
||||
}
|
||||
}
|
||||
|
||||
public GenericPropertyNode getProperty(int index)
|
||||
public GenericPropertyNode getProperty( int index )
|
||||
{
|
||||
return _props.get(index);
|
||||
return _props.get( index );
|
||||
}
|
||||
|
||||
public void addProperty(GenericPropertyNode node)
|
||||
public void addProperty( GenericPropertyNode node )
|
||||
{
|
||||
_props.add(node);
|
||||
_props.add( node );
|
||||
}
|
||||
|
||||
public byte[] toByteArray()
|
||||
{
|
||||
int size = _props.size();
|
||||
int cpBufSize = ((size + 1) * LittleEndian.INT_SIZE);
|
||||
int structBufSize = + (_sizeOfStruct * size);
|
||||
int cpBufSize = ( ( size + 1 ) * LittleEndian.INT_SIZE );
|
||||
int structBufSize = +( _cbStruct * size );
|
||||
int bufSize = cpBufSize + structBufSize;
|
||||
|
||||
byte[] buf = new byte[bufSize];
|
||||
|
||||
GenericPropertyNode node = null;
|
||||
for (int x = 0; x < size; x++)
|
||||
for ( int x = 0; x < size; x++ )
|
||||
{
|
||||
node = _props.get(x);
|
||||
node = _props.get( x );
|
||||
|
||||
// put the starting offset of the property into the plcf.
|
||||
LittleEndian.putInt(buf, (LittleEndian.INT_SIZE * x), node.getStart());
|
||||
LittleEndian.putInt( buf, ( LittleEndian.INT_SIZE * x ),
|
||||
node.getStart() );
|
||||
|
||||
// put the struct into the plcf
|
||||
System.arraycopy(node.getBytes(), 0, buf, cpBufSize + (x * _sizeOfStruct),
|
||||
_sizeOfStruct);
|
||||
System.arraycopy( node.getBytes(), 0, buf, cpBufSize
|
||||
+ ( x * _cbStruct ), _cbStruct );
|
||||
}
|
||||
// put the ending offset of the last property into the plcf.
|
||||
LittleEndian.putInt(buf, LittleEndian.INT_SIZE * size, node.getEnd());
|
||||
LittleEndian.putInt( buf, LittleEndian.INT_SIZE * size, node.getEnd() );
|
||||
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
private GenericPropertyNode getProperty(int index, byte[] buf, int offset)
|
||||
private GenericPropertyNode getProperty( int index, byte[] buf, int offset )
|
||||
{
|
||||
int start = LittleEndian.getInt(buf, offset + getIntOffset(index));
|
||||
int end = LittleEndian.getInt(buf, offset + getIntOffset(index+1));
|
||||
int start = LittleEndian.getInt( buf, offset + getIntOffset( index ) );
|
||||
int end = LittleEndian.getInt( buf, offset + getIntOffset( index + 1 ) );
|
||||
|
||||
byte[] struct = new byte[_sizeOfStruct];
|
||||
System.arraycopy(buf, offset + getStructOffset(index), struct, 0, _sizeOfStruct);
|
||||
byte[] struct = new byte[_cbStruct];
|
||||
System.arraycopy( buf, offset + getStructOffset( index ), struct, 0,
|
||||
_cbStruct );
|
||||
|
||||
return new GenericPropertyNode(start, end, struct);
|
||||
return new GenericPropertyNode( start, end, struct );
|
||||
}
|
||||
|
||||
private int getIntOffset(int index)
|
||||
private int getIntOffset( int index )
|
||||
{
|
||||
return index * 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of data structures in this PlexOfCps.
|
||||
* returns the number of data structures in this PlexofCps.
|
||||
*
|
||||
* @return The number of data structures in this PlexOfCps
|
||||
* @return The number of data structures in this PlexofCps
|
||||
*/
|
||||
public int length()
|
||||
{
|
||||
return _count;
|
||||
return _iMac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset, in bytes, from the beginning if this PlexOfCps to
|
||||
* the data structure at index.
|
||||
* Returns the offset, in bytes, from the beginning if this PlexOfCps to the
|
||||
* data structure at index.
|
||||
*
|
||||
* @param index The index of the data structure.
|
||||
* @param index
|
||||
* The index of the data structure.
|
||||
*
|
||||
* @return The offset, in bytes, from the beginning if this PlexOfCps to
|
||||
* the data structure at index.
|
||||
* @return The offset, in bytes, from the beginning if this PlexOfCps to the
|
||||
* data structure at index.
|
||||
*/
|
||||
private int getStructOffset(int index)
|
||||
private int getStructOffset( int index )
|
||||
{
|
||||
return (4 * (_count + 1)) + (_sizeOfStruct * index);
|
||||
return ( 4 * ( _iMac + 1 ) ) + ( _cbStruct * index );
|
||||
}
|
||||
}
|
||||
|
@ -51,10 +51,30 @@ public final class HeaderStories {
|
||||
}
|
||||
|
||||
// Handle the PlcfHdd
|
||||
plcfHdd = new PlexOfCps(
|
||||
doc.getTableStream(), fib.getPlcfHddOffset(),
|
||||
fib.getPlcfHddSize(), 0
|
||||
);
|
||||
/*
|
||||
* Page 88:
|
||||
*
|
||||
* "The plcfhdd, a table whose location and length within the file is
|
||||
* stored in fib.fcPlcfhdd and fib.cbPlcfhdd, describes where the text
|
||||
* of each header/footer begins. If there are n headers/footers stored
|
||||
* in the Word file, the plcfhdd consists of n+2 CP entries. The
|
||||
* beginning CP of the ith header/footer is the ith CP in the plcfhdd.
|
||||
* The limit CP (the CP of character 1 position past the end of a
|
||||
* header/footer) of the ith header/footer is the i+1st CP in the
|
||||
* plcfhdd. Note: at the limit CP - 1, Word always places a chEop as a
|
||||
* placeholder which is never displayed as part of the header/footer.
|
||||
* This allows Word to change an existing header/footer to be empty.
|
||||
*
|
||||
* If there are n header/footers, the n+2nd CP entry value is always 1
|
||||
* greater than the n+1st CP entry value. A paragraph end (ASCII 13) is
|
||||
* always stored at the file position marked by the n+1st CP value.
|
||||
*
|
||||
* The transformation in a full saved file from a header/footer CP to an
|
||||
* offset from the beginning of a file (fc) is
|
||||
* fc=fib.fcMin+ccpText+ccpFtn+cp."
|
||||
*/
|
||||
plcfHdd = new PlexOfCps( doc.getTableStream(), fib.getPlcfHddOffset(),
|
||||
fib.getPlcfHddSize(), 0 );
|
||||
}
|
||||
|
||||
public String getFootnoteSeparator() {
|
||||
|
Loading…
Reference in New Issue
Block a user