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;
/**
* 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 _offset;
private int _sizeOfStruct;
private ArrayList<GenericPropertyNode> _props;
private int _iMac;
private int _offset;
private int _cbStruct;
private ArrayList<GenericPropertyNode> _props;
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++)
public PlexOfCps( int sizeOfStruct )
{
_props.add(getProperty(x, buf, start));
_props = new ArrayList<GenericPropertyNode>();
_cbStruct = sizeOfStruct;
}
}
public GenericPropertyNode getProperty(int index)
{
return _props.get(index);
}
public void addProperty(GenericPropertyNode node)
{
_props.add(node);
}
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++)
/**
* Constructor
*
* @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 cb, int cbStruct )
{
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.
LittleEndian.putInt(buf, (LittleEndian.INT_SIZE * x), node.getStart());
_cbStruct = cbStruct;
_props = new ArrayList<GenericPropertyNode>( _iMac );
// put the struct into the plcf
System.arraycopy(node.getBytes(), 0, buf, cpBufSize + (x * _sizeOfStruct),
_sizeOfStruct);
for ( int x = 0; x < _iMac; x++ )
{
_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)
{
int start = LittleEndian.getInt(buf, offset + getIntOffset(index));
int end = LittleEndian.getInt(buf, offset + getIntOffset(index+1));
public byte[] toByteArray()
{
int size = _props.size();
int cpBufSize = ( ( size + 1 ) * LittleEndian.INT_SIZE );
int structBufSize = +( _cbStruct * size );
int bufSize = cpBufSize + structBufSize;
byte[] struct = new byte[_sizeOfStruct];
System.arraycopy(buf, offset + getStructOffset(index), struct, 0, _sizeOfStruct);
byte[] buf = new byte[bufSize];
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)
{
return index * 4;
}
// put the starting offset of the property into the plcf.
LittleEndian.putInt( buf, ( LittleEndian.INT_SIZE * x ),
node.getStart() );
/**
* returns the number of data structures in this PlexOfCps.
*
* @return The number of data structures in this PlexOfCps
*/
public int length()
{
return _count;
}
// put the struct into the plcf
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() );
/**
* 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 * (_count + 1)) + (_sizeOfStruct * index);
}
return buf;
}
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 ) );
byte[] struct = new byte[_cbStruct];
System.arraycopy( buf, offset + getStructOffset( index ), struct, 0,
_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;
}
// Handle the PlcfHdd
plcfHdd = new PlexOfCps(
doc.getTableStream(), fib.getPlcfHddOffset(),
fib.getPlcfHddSize(), 0
);
}
// Handle the PlcfHdd
/*
* 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() {
return getAt(0);