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:
Sergey Vladimirov 2011-07-07 10:56:46 +00:00
parent e325f0d084
commit 4abb3c6e51
2 changed files with 130 additions and 106 deletions

View File

@ -21,125 +21,129 @@ import java.util.ArrayList;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
/** /**
* common data structure in a Word file. Contains an array of 4 byte ints in * Plex of CPs stored in File (PLCF)
* the front that relate to an array of abitrary data structures in the back.
* *
* 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 * @author Ryan Ackley
*/ */
public final class PlexOfCps public final class PlexOfCps
{ {
private int _count; private int _iMac;
private int _offset; private int _offset;
private int _sizeOfStruct; private int _cbStruct;
private ArrayList<GenericPropertyNode> _props; private ArrayList<GenericPropertyNode> _props;
public PlexOfCps( int sizeOfStruct )
public PlexOfCps(int sizeOfStruct)
{
_props = new ArrayList<GenericPropertyNode>();
_sizeOfStruct = sizeOfStruct;
}
/**
* Constructor
*
* @param size The size in bytes of this PlexOfCps
* @param sizeOfStruct The size of the data structure type stored in
* this PlexOfCps.
*/
public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct)
{
// Figure out the number we hold
_count = (size - 4)/(4 + sizeOfStruct);
_sizeOfStruct = sizeOfStruct;
_props = new ArrayList<GenericPropertyNode>(_count);
for (int x = 0; x < _count; x++)
{ {
_props.add(getProperty(x, buf, start)); _props = new ArrayList<GenericPropertyNode>();
_cbStruct = sizeOfStruct;
} }
}
public GenericPropertyNode getProperty(int index) /**
{ * Constructor
return _props.get(index); *
} * @param cb
* The size of PLCF in bytes
public void addProperty(GenericPropertyNode node) * @param cbStruct
{ * The size of the data structure type stored in this PlexOfCps.
_props.add(node); */
} public PlexOfCps( byte[] buf, int start, int cb, int cbStruct )
public byte[] toByteArray()
{
int size = _props.size();
int cpBufSize = ((size + 1) * LittleEndian.INT_SIZE);
int structBufSize = + (_sizeOfStruct * size);
int bufSize = cpBufSize + structBufSize;
byte[] buf = new byte[bufSize];
GenericPropertyNode node = null;
for (int x = 0; x < size; x++)
{ {
node = _props.get(x); // Figure out the number we hold
_iMac = ( cb - 4 ) / ( 4 + cbStruct );
// put the starting offset of the property into the plcf. _cbStruct = cbStruct;
LittleEndian.putInt(buf, (LittleEndian.INT_SIZE * x), node.getStart()); _props = new ArrayList<GenericPropertyNode>( _iMac );
// put the struct into the plcf for ( int x = 0; x < _iMac; x++ )
System.arraycopy(node.getBytes(), 0, buf, cpBufSize + (x * _sizeOfStruct), {
_sizeOfStruct); _props.add( getProperty( x, buf, start ) );
}
} }
// put the ending offset of the last property into the plcf.
LittleEndian.putInt(buf, LittleEndian.INT_SIZE * size, node.getEnd());
return buf; public GenericPropertyNode getProperty( int index )
{
return _props.get( index );
}
} public void addProperty( GenericPropertyNode node )
{
_props.add( node );
}
private GenericPropertyNode getProperty(int index, byte[] buf, int offset) public byte[] toByteArray()
{ {
int start = LittleEndian.getInt(buf, offset + getIntOffset(index)); int size = _props.size();
int end = LittleEndian.getInt(buf, offset + getIntOffset(index+1)); int cpBufSize = ( ( size + 1 ) * LittleEndian.INT_SIZE );
int structBufSize = +( _cbStruct * size );
int bufSize = cpBufSize + structBufSize;
byte[] struct = new byte[_sizeOfStruct]; byte[] buf = new byte[bufSize];
System.arraycopy(buf, offset + getStructOffset(index), struct, 0, _sizeOfStruct);
return new GenericPropertyNode(start, end, struct); GenericPropertyNode node = null;
} for ( int x = 0; x < size; x++ )
{
node = _props.get( x );
private int getIntOffset(int index) // put the starting offset of the property into the plcf.
{ LittleEndian.putInt( buf, ( LittleEndian.INT_SIZE * x ),
return index * 4; node.getStart() );
}
/** // put the struct into the plcf
* returns the number of data structures in this PlexOfCps. System.arraycopy( node.getBytes(), 0, buf, cpBufSize
* + ( x * _cbStruct ), _cbStruct );
* @return The number of data structures in this PlexOfCps }
*/ // put the ending offset of the last property into the plcf.
public int length() LittleEndian.putInt( buf, LittleEndian.INT_SIZE * size, node.getEnd() );
{
return _count;
}
/** return buf;
* 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. private GenericPropertyNode getProperty( int index, byte[] buf, int offset )
* {
* @return The offset, in bytes, from the beginning if this PlexOfCps to int start = LittleEndian.getInt( buf, offset + getIntOffset( index ) );
* the data structure at index. int end = LittleEndian.getInt( buf, offset + getIntOffset( index + 1 ) );
*/
private int getStructOffset(int index) byte[] struct = new byte[_cbStruct];
{ System.arraycopy( buf, offset + getStructOffset( index ), struct, 0,
return (4 * (_count + 1)) + (_sizeOfStruct * index); _cbStruct );
}
return new GenericPropertyNode( start, end, struct );
}
private int getIntOffset( int index )
{
return index * 4;
}
/**
* returns the number of data structures in this PlexofCps.
*
* @return The number of data structures in this PlexofCps
*/
public int length()
{
return _iMac;
}
/**
* 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.
*
* @return The offset, in bytes, from the beginning if this PlexOfCps to the
* data structure at index.
*/
private int getStructOffset( int index )
{
return ( 4 * ( _iMac + 1 ) ) + ( _cbStruct * index );
}
} }

View File

@ -50,12 +50,32 @@ public final class HeaderStories {
return; return;
} }
// Handle the PlcfHdd // Handle the PlcfHdd
plcfHdd = new PlexOfCps( /*
doc.getTableStream(), fib.getPlcfHddOffset(), * Page 88:
fib.getPlcfHddSize(), 0 *
); * "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() { public String getFootnoteSeparator() {
return getAt(0); return getAt(0);