Reached first milestone
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353212 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9aae367586
commit
7132ebe1c5
@ -57,14 +57,23 @@ package org.apache.poi.hwpf;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
|
import org.apache.poi.poifs.common.POIFSConstants;
|
||||||
|
|
||||||
import org.apache.poi.hwpf.model.hdftypes.*;
|
import org.apache.poi.hwpf.model.hdftypes.*;
|
||||||
|
import org.apache.poi.hwpf.model.io.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
|
* This class acts as the bucket that we throw all of the Word data structures
|
||||||
|
* into.
|
||||||
|
*
|
||||||
* @author Ryan Ackley
|
* @author Ryan Ackley
|
||||||
*/
|
*/
|
||||||
public class HWPFDocument
|
public class HWPFDocument
|
||||||
@ -76,11 +85,40 @@ public class HWPFDocument
|
|||||||
private FileInformationBlock _fib;
|
private FileInformationBlock _fib;
|
||||||
|
|
||||||
/** main document stream buffer*/
|
/** main document stream buffer*/
|
||||||
byte[] _mainStream;
|
private byte[] _mainStream;
|
||||||
|
|
||||||
/** table stream buffer*/
|
/** table stream buffer*/
|
||||||
byte[] _tableStream;
|
private byte[] _tableStream;
|
||||||
|
|
||||||
|
/** Document wide Properties*/
|
||||||
|
private DocumentProperties _dop;
|
||||||
|
|
||||||
|
/** Contains text of the document wrapped in a obfuscated Wod data structure*/
|
||||||
|
private ComplexFileTable _cft;
|
||||||
|
|
||||||
|
/** Contains formatting properties for text*/
|
||||||
|
private CHPBinTable _cbt;
|
||||||
|
|
||||||
|
/** Contains formatting properties for paragraphs*/
|
||||||
|
private PAPBinTable _pbt;
|
||||||
|
|
||||||
|
/** Contains formatting properties for sections.*/
|
||||||
|
private SectionTable _st;
|
||||||
|
|
||||||
|
/** Holds styles for this document.*/
|
||||||
|
private StyleSheet _ss;
|
||||||
|
|
||||||
|
/** Holds fonts for this document.*/
|
||||||
|
private FontTable _ft;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor loads a Word document from an InputStream.
|
||||||
|
*
|
||||||
|
* @param istream The InputStream that contains the Word document.
|
||||||
|
* @throws IOException If there is an unexpected IOException from the passed
|
||||||
|
* in InputStream.
|
||||||
|
*/
|
||||||
public HWPFDocument(InputStream istream) throws IOException
|
public HWPFDocument(InputStream istream) throws IOException
|
||||||
{
|
{
|
||||||
//do Ole stuff
|
//do Ole stuff
|
||||||
@ -110,23 +148,148 @@ public class HWPFDocument
|
|||||||
// get the start of text in the main stream
|
// get the start of text in the main stream
|
||||||
int fcMin = _fib.getFcMin();
|
int fcMin = _fib.getFcMin();
|
||||||
|
|
||||||
DocumentProperties dop = new DocumentProperties(_tableStream, _fib.getFcDop());
|
// load up our standard structures.
|
||||||
ComplexFileTable cft = new ComplexFileTable(_mainStream, _tableStream, _fib.getFcClx(), fcMin);
|
_dop = new DocumentProperties(_tableStream, _fib.getFcDop());
|
||||||
CHPBinTable cbt = new CHPBinTable(_mainStream, _tableStream, _fib.getFcPlcfbteChpx(), _fib.getLcbPlcfbteChpx(), fcMin);
|
_cft = new ComplexFileTable(_mainStream, _tableStream, _fib.getFcClx(), fcMin);
|
||||||
PAPBinTable pbt = new PAPBinTable(_mainStream, _tableStream, _fib.getFcPlcfbtePapx(), _fib.getLcbPlcfbtePapx(), fcMin);
|
_cbt = new CHPBinTable(_mainStream, _tableStream, _fib.getFcPlcfbteChpx(), _fib.getLcbPlcfbteChpx(), fcMin);
|
||||||
SectionTable st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin);
|
_pbt = new PAPBinTable(_mainStream, _tableStream, _fib.getFcPlcfbtePapx(), _fib.getLcbPlcfbtePapx(), fcMin);
|
||||||
StyleSheet ss = new StyleSheet(_tableStream, _fib.getFcStshf());
|
_st = new SectionTable(_mainStream, _tableStream, _fib.getFcPlcfsed(), _fib.getLcbPlcfsed(), fcMin);
|
||||||
|
_ss = new StyleSheet(_tableStream, _fib.getFcStshf());
|
||||||
|
_ft = new FontTable(_tableStream, _fib.getFcSttbfffn(), _fib.getLcbSttbfffn());
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes out the word file that is represented by an instance of this class.
|
||||||
|
*
|
||||||
|
* @param out The OutputStream to write to.
|
||||||
|
* @throws IOException If there is an unexpected IOException from the passed
|
||||||
|
* in OutputStream.
|
||||||
|
*/
|
||||||
|
public void write(OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// initialize our streams for writing.
|
||||||
|
HWPFFileSystem docSys = new HWPFFileSystem();
|
||||||
|
HWPFOutputStream mainStream = docSys.getStream("WordDocument");
|
||||||
|
HWPFOutputStream tableStream = docSys.getStream("1Table");
|
||||||
|
int tableOffset = 0;
|
||||||
|
|
||||||
|
// clear the offsets and sizes in our FileInformationBlock.
|
||||||
|
_fib.clearOffsetsSizes();
|
||||||
|
|
||||||
|
// determine the FileInformationBLock size
|
||||||
|
int fibSize = _fib.getSize();
|
||||||
|
fibSize += POIFSConstants.BIG_BLOCK_SIZE -
|
||||||
|
(fibSize % POIFSConstants.BIG_BLOCK_SIZE);
|
||||||
|
|
||||||
|
// preserve space for the FileInformationBlock because we will be writing
|
||||||
|
// it after we write everything else.
|
||||||
|
byte[] placeHolder = new byte[fibSize];
|
||||||
|
mainStream.write(placeHolder);
|
||||||
|
int mainOffset = mainStream.getOffset();
|
||||||
|
|
||||||
|
// write out the StyleSheet.
|
||||||
|
_fib.setFcStshf(tableOffset);
|
||||||
|
_ss.writeTo(tableStream);
|
||||||
|
_fib.setLcbStshf(tableStream.getOffset() - tableOffset);
|
||||||
|
tableOffset = tableStream.getOffset();
|
||||||
|
|
||||||
|
// get fcMin and fcMac because we will be writing the actual text with the
|
||||||
|
// complex table.
|
||||||
|
int fcMin = mainOffset;
|
||||||
|
|
||||||
|
// write out the Complex table, includes text.
|
||||||
|
_fib.setFcClx(tableOffset);
|
||||||
|
_cft.writeTo(docSys);
|
||||||
|
_fib.setLcbClx(tableStream.getOffset() - tableOffset);
|
||||||
|
tableOffset = tableStream.getOffset();
|
||||||
|
int fcMac = mainStream.getOffset();
|
||||||
|
|
||||||
|
// write out the CHPBinTable.
|
||||||
|
_fib.setFcPlcfbteChpx(tableOffset);
|
||||||
|
_cbt.writeTo(docSys, fcMin);
|
||||||
|
_fib.setLcbPlcfbteChpx(tableStream.getOffset() - tableOffset);
|
||||||
|
tableOffset = tableStream.getOffset();
|
||||||
|
|
||||||
|
// write out the PAPBinTable.
|
||||||
|
_fib.setFcPlcfbtePapx(tableOffset);
|
||||||
|
_pbt.writeTo(docSys, fcMin);
|
||||||
|
_fib.setLcbPlcfbtePapx(tableStream.getOffset() - tableOffset);
|
||||||
|
tableOffset = tableStream.getOffset();
|
||||||
|
|
||||||
|
// write out the SectionTable.
|
||||||
|
_fib.setFcPlcfsed(tableOffset);
|
||||||
|
_st.writeTo(docSys, fcMin);
|
||||||
|
_fib.setLcbPlcfsed(tableStream.getOffset() - tableOffset);
|
||||||
|
tableOffset = tableStream.getOffset();
|
||||||
|
|
||||||
|
// write out the FontTable.
|
||||||
|
_fib.setFcSttbfffn(tableOffset);
|
||||||
|
_ft.writeTo(docSys);
|
||||||
|
_fib.setLcbSttbfffn(tableStream.getOffset() - tableOffset);
|
||||||
|
tableOffset = tableStream.getOffset();
|
||||||
|
|
||||||
|
// write out the DocumentProperties.
|
||||||
|
_fib.setFcDop(tableOffset);
|
||||||
|
byte[] buf = new byte[_dop.getSize()];
|
||||||
|
_fib.setLcbDop(_dop.getSize());
|
||||||
|
_dop.serialize(buf, 0);
|
||||||
|
tableStream.write(buf);
|
||||||
|
|
||||||
|
// set some variables in the FileInformationBlock.
|
||||||
|
_fib.setFcMin(fcMin);
|
||||||
|
_fib.setFcMac(fcMac);
|
||||||
|
_fib.setCbMac(mainStream.getOffset());
|
||||||
|
|
||||||
|
// make sure that the table and doc stream use big blocks.
|
||||||
|
byte[] mainBuf = mainStream.toByteArray();
|
||||||
|
if (mainBuf.length < 4096)
|
||||||
|
{
|
||||||
|
byte[] tempBuf = new byte[4096];
|
||||||
|
System.arraycopy(mainBuf, 0, tempBuf, 0, mainBuf.length);
|
||||||
|
mainBuf = tempBuf;
|
||||||
|
}
|
||||||
|
byte[] tableBuf = tableStream.toByteArray();
|
||||||
|
if (tableBuf.length < 4096)
|
||||||
|
{
|
||||||
|
byte[] tempBuf = new byte[4096];
|
||||||
|
System.arraycopy(tableBuf, 0, tempBuf, 0, tableBuf.length);
|
||||||
|
tableBuf = tempBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write out the FileInformationBlock.
|
||||||
|
_fib.serialize(mainBuf, 0);
|
||||||
|
|
||||||
|
// spit out the Word document.
|
||||||
|
POIFSFileSystem pfs = new POIFSFileSystem();
|
||||||
|
pfs.createDocument(new ByteArrayInputStream(mainBuf), "WordDocument");
|
||||||
|
pfs.createDocument(new ByteArrayInputStream(tableBuf), "1Table");
|
||||||
|
|
||||||
|
pfs.writeFilesystem(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes two arguments, 1) name of the Word file to read in 2) location to
|
||||||
|
* write it out at.
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HWPFDocument doc = new HWPFDocument(new FileInputStream(args[0]));
|
HWPFDocument doc = new HWPFDocument(new FileInputStream(args[0]));
|
||||||
|
|
||||||
|
OutputStream out = new FileOutputStream(args[1]);
|
||||||
|
doc.write(out);
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
|
@ -142,7 +142,7 @@ public class CHPBinTable
|
|||||||
int end = endingFc;
|
int end = endingFc;
|
||||||
if (overflow != null)
|
if (overflow != null)
|
||||||
{
|
{
|
||||||
end = ((PropertyNode)overflow.get(0)).getStart();
|
end = ((PropertyNode)overflow.get(0)).getStart() + fcMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] intHolder = new byte[4];
|
byte[] intHolder = new byte[4];
|
||||||
|
@ -56,93 +56,212 @@ package org.apache.poi.hwpf.model.hdftypes;
|
|||||||
|
|
||||||
import org.apache.poi.util.BitField;
|
import org.apache.poi.util.BitField;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FFN - Font Family Name. FFN is a data structure that stores the names of the Main
|
||||||
|
* Font and that of Alternate font as an array of characters. It has also a header
|
||||||
|
* that stores info about the whole structure and the fonts
|
||||||
|
*
|
||||||
|
* @author Praveen Mathew
|
||||||
|
*/
|
||||||
public class Ffn
|
public class Ffn
|
||||||
{
|
{
|
||||||
private int field1_cbFfnM1; //total length of FFN - 1.
|
private int field_1_cbFfnM1;//total length of FFN - 1.
|
||||||
private byte field2;
|
private byte field_2;
|
||||||
private static BitField _prq = new BitField(0x0003);// pitch request
|
private static BitField _prq = new BitField(0x0003);// pitch request
|
||||||
private static BitField _fTrueType = new BitField(0x0004);// when 1, font is a TrueType font
|
private static BitField _fTrueType = new BitField(0x0004);// when 1, font is a TrueType font
|
||||||
private static BitField _ff = new BitField(0x0070);
|
private static BitField _ff = new BitField(0x0070);
|
||||||
private short field3_wWeight;// base weight of font
|
private short field_3_wWeight;// base weight of font
|
||||||
private byte field4_chs;// character set identifier
|
private byte field_4_chs;// character set identifier
|
||||||
private byte field5_ixchSzAlt; // index into ffn.szFfn to the name of
|
private byte field_5_ixchSzAlt; // index into ffn.szFfn to the name of
|
||||||
// the alternate font
|
// the alternate font
|
||||||
private byte [] panose = new byte[10]; //????
|
private byte [] field_6_panose = new byte[10];//????
|
||||||
private byte [] fontSig = new byte[24]; //????
|
private byte [] field_7_fontSig = new byte[24];//????
|
||||||
|
|
||||||
// zero terminated string that records name of font, cuurently not
|
// zero terminated string that records name of font, cuurently not
|
||||||
// supporting Extended chars
|
// supporting Extended chars
|
||||||
private char [] xszFfn;
|
private char [] field_8_xszFfn;
|
||||||
|
|
||||||
|
// extra facilitator members
|
||||||
private int xszFfnLength;
|
private int xszFfnLength;
|
||||||
|
|
||||||
public Ffn(byte[] buf, int offset)
|
public Ffn(byte[] buf, int offset)
|
||||||
{
|
{
|
||||||
field1_cbFfnM1 = LittleEndian.getUnsignedByte(buf, offset);
|
int offsetTmp = offset;
|
||||||
|
|
||||||
|
field_1_cbFfnM1 = LittleEndian.getUnsignedByte(buf,offset);
|
||||||
offset += LittleEndian.BYTE_SIZE;
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
field2 = buf[offset];
|
field_2 = buf[offset];
|
||||||
offset += LittleEndian.BYTE_SIZE;
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
field3_wWeight = LittleEndian.getShort(buf, offset);
|
field_3_wWeight = LittleEndian.getShort(buf, offset);
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
field4_chs = buf[offset];
|
field_4_chs = buf[offset];
|
||||||
offset += LittleEndian.BYTE_SIZE;
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
field5_ixchSzAlt = buf[offset];
|
field_5_ixchSzAlt = buf[offset];
|
||||||
offset += LittleEndian.BYTE_SIZE;
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
|
|
||||||
// read panose and fs so we can write them back out.
|
// read panose and fs so we can write them back out.
|
||||||
System.arraycopy(buf, offset, panose, 0, panose.length);
|
System.arraycopy(buf, offset, field_6_panose, 0, field_6_panose.length);
|
||||||
offset += panose.length;
|
offset += field_6_panose.length;
|
||||||
System.arraycopy(buf, offset, fontSig, 0, fontSig.length);
|
System.arraycopy(buf, offset, field_7_fontSig, 0, field_7_fontSig.length);
|
||||||
offset += fontSig.length;
|
offset += field_7_fontSig.length;
|
||||||
|
|
||||||
xszFfnLength = this.getSize() - offset;
|
offsetTmp = offset - offsetTmp;
|
||||||
xszFfn = new char[xszFfnLength];
|
xszFfnLength = this.getSize() - offsetTmp;
|
||||||
|
field_8_xszFfn = new char[xszFfnLength];
|
||||||
|
|
||||||
for(int i = 0; i < xszFfnLength; i++)
|
for(int i = 0; i < xszFfnLength; i++)
|
||||||
{
|
{
|
||||||
xszFfn[i] = (char)LittleEndian.getUnsignedByte(buf, offset);
|
field_8_xszFfn[i] = (char)LittleEndian.getUnsignedByte(buf, offset);
|
||||||
offset += LittleEndian.BYTE_SIZE;
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getField1_cbFfnM1()
|
public int getField_1_cbFfnM1()
|
||||||
{
|
{
|
||||||
return field1_cbFfnM1;
|
return field_1_cbFfnM1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getField_2()
|
||||||
|
{
|
||||||
|
return field_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getField_3_wWeight()
|
||||||
|
{
|
||||||
|
return field_3_wWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getField_4_chs()
|
||||||
|
{
|
||||||
|
return field_4_chs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getField_5_ixchSzAlt()
|
||||||
|
{
|
||||||
|
return field_5_ixchSzAlt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte [] getField_6_panose()
|
||||||
|
{
|
||||||
|
return field_6_panose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte [] getField_7_fontSig()
|
||||||
|
{
|
||||||
|
return field_7_fontSig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char [] getField_8_xszFfn()
|
||||||
|
{
|
||||||
|
return field_8_xszFfn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize()
|
public int getSize()
|
||||||
{
|
{
|
||||||
return (field1_cbFfnM1 + 1);
|
return (field_1_cbFfnM1 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public char [] getMainFontName()
|
public char [] getMainFontName()
|
||||||
{
|
{
|
||||||
char [] temp = new char[field5_ixchSzAlt];
|
char [] temp = new char[field_5_ixchSzAlt];
|
||||||
System.arraycopy(xszFfn,0,temp,0,temp.length);
|
System.arraycopy(field_8_xszFfn,0,temp,0,temp.length);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char [] getAltFontName()
|
public char [] getAltFontName()
|
||||||
{
|
{
|
||||||
char [] temp = new char[xszFfnLength - field5_ixchSzAlt];
|
char [] temp = new char[xszFfnLength - field_5_ixchSzAlt];
|
||||||
System.arraycopy(xszFfn, field5_ixchSzAlt, temp, 0, temp.length);
|
System.arraycopy(field_8_xszFfn, field_5_ixchSzAlt, temp, 0, temp.length);
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setField1_cbFfnM1(short field1_cbFfnM1)
|
public void setField_1_cbFfnM1(int field_1_cbFfnM1)
|
||||||
{
|
{
|
||||||
this.field1_cbFfnM1 = field1_cbFfnM1;
|
this.field_1_cbFfnM1 = field_1_cbFfnM1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] toByteArray()
|
// changed protected to public
|
||||||
|
public byte[] toByteArray()
|
||||||
{
|
{
|
||||||
//return buf;
|
int offset = 0;
|
||||||
return null;
|
byte[] buf = new byte[this.getSize()];
|
||||||
|
|
||||||
|
buf[offset] = (byte)field_1_cbFfnM1;
|
||||||
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
|
buf[offset] = field_2;
|
||||||
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
|
LittleEndian.putShort(buf, offset, field_3_wWeight);
|
||||||
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
|
buf[offset] = field_4_chs;
|
||||||
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
|
buf[offset] = field_5_ixchSzAlt;
|
||||||
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
|
|
||||||
|
System.arraycopy(field_6_panose,0,buf, offset,field_6_panose.length);
|
||||||
|
offset += field_6_panose.length;
|
||||||
|
System.arraycopy(field_7_fontSig,0,buf, offset, field_7_fontSig.length);
|
||||||
|
offset += field_7_fontSig.length;
|
||||||
|
|
||||||
|
for(int i = 0; i < field_8_xszFfn.length; i++)
|
||||||
|
{
|
||||||
|
buf[offset] = (byte)field_8_xszFfn[i];
|
||||||
|
offset += LittleEndian.BYTE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
boolean retVal = true;
|
||||||
|
|
||||||
|
if (((Ffn)o).getField_1_cbFfnM1() == field_1_cbFfnM1)
|
||||||
|
{
|
||||||
|
if(((Ffn)o).getField_2() == field_2)
|
||||||
|
{
|
||||||
|
if(((Ffn)o).getField_3_wWeight() == field_3_wWeight)
|
||||||
|
{
|
||||||
|
if(((Ffn)o).getField_4_chs() == field_4_chs)
|
||||||
|
{
|
||||||
|
if(((Ffn)o).getField_5_ixchSzAlt() == field_5_ixchSzAlt)
|
||||||
|
{
|
||||||
|
if(Arrays.equals(((Ffn)o).getField_6_panose(),field_6_panose))
|
||||||
|
{
|
||||||
|
if(Arrays.equals(((Ffn)o).getField_7_fontSig(),field_7_fontSig))
|
||||||
|
{
|
||||||
|
if(!(Arrays.equals(((Ffn)o).getField_8_xszFfn(),field_8_xszFfn)))
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwpf.model.hdftypes;
|
package org.apache.poi.hwpf.model.hdftypes;
|
||||||
|
|
||||||
|
import java.lang.reflect.AccessibleObject;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import org.apache.poi.util.BitField;
|
import org.apache.poi.util.BitField;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
@ -66,6 +69,7 @@ import org.apache.poi.hwpf.model.hdftypes.definitions.FIBAbstractType;
|
|||||||
* @author andy
|
* @author andy
|
||||||
*/
|
*/
|
||||||
public class FileInformationBlock extends FIBAbstractType
|
public class FileInformationBlock extends FIBAbstractType
|
||||||
|
implements Cloneable
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Creates a new instance of FileInformationBlock */
|
/** Creates a new instance of FileInformationBlock */
|
||||||
@ -74,5 +78,48 @@ public class FileInformationBlock extends FIBAbstractType
|
|||||||
fillFields(mainDocument, (short)0, (short)0);
|
fillFields(mainDocument, (short)0, (short)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearOffsetsSizes()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Field[] fields = FileInformationBlock.class.getSuperclass().getDeclaredFields();
|
||||||
|
AccessibleObject.setAccessible(fields, true);
|
||||||
|
|
||||||
|
for (int x = 0; x < fields.length; x++)
|
||||||
|
{
|
||||||
|
String name = fields[x].getName();
|
||||||
|
int index = name.indexOf('_');
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
int nextIndex = name.indexOf('_', index + 1);
|
||||||
|
if (nextIndex != -1)
|
||||||
|
{
|
||||||
|
// clear any field greater than field_53
|
||||||
|
if (Integer.parseInt(name.substring(index + 1, nextIndex)) > 53)
|
||||||
|
{
|
||||||
|
fields[x].setInt(this, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException iae)
|
||||||
|
{
|
||||||
|
iae.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,67 +54,64 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwpf.model.hdftypes;
|
package org.apache.poi.hwpf.model.hdftypes;
|
||||||
|
|
||||||
import org.apache.poi.util.BitField;
|
import java.io.IOException;
|
||||||
|
import org.apache.poi.hwpf.model.io.HWPFFileSystem;
|
||||||
|
import org.apache.poi.hwpf.model.io.HWPFOutputStream;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FontTable or in MS terminology sttbfffn is a common data structure written in all
|
||||||
|
* Word files. The sttbfffn is an sttbf where each string is an FFN structure instead
|
||||||
|
* of pascal-style strings. An sttbf is a string Table stored in file. Thus sttbffn
|
||||||
|
* is like an Sttbf with an array of FFN structures that stores the font name strings
|
||||||
|
*
|
||||||
|
* @author Praveen Mathew
|
||||||
|
*/
|
||||||
public class FontTable
|
public class FontTable
|
||||||
{
|
{
|
||||||
private short exntdChar; // strings are extended character if = 0xFFFF
|
private short _stringCount;// how many strings are included in the string table
|
||||||
private short stringCount; // how many strings are included in the string table
|
private short _extraDataSz;// size in bytes of the extra data
|
||||||
private short extraDataSz; // size in bytes of the extra data
|
|
||||||
|
|
||||||
private int lcbSttbfffn; // count of bytes in sttbfffn
|
|
||||||
private boolean isExtndChar;
|
|
||||||
|
|
||||||
|
// added extra facilitator members
|
||||||
|
private int lcbSttbfffn;// count of bytes in sttbfffn
|
||||||
|
private int fcSttbfffn;// table stream offset for sttbfffn
|
||||||
|
|
||||||
// FFN structure containing strings of font names
|
// FFN structure containing strings of font names
|
||||||
private Ffn [] fontNames = null;
|
private Ffn[] _fontNames = null;
|
||||||
|
|
||||||
|
|
||||||
public FontTable(byte[] buf, int offset, int lcbSttbfffn)
|
public FontTable(byte[] buf, int offset, int lcbSttbfffn)
|
||||||
{
|
{
|
||||||
this.lcbSttbfffn = lcbSttbfffn;
|
this.lcbSttbfffn = lcbSttbfffn;
|
||||||
|
this.fcSttbfffn = offset;
|
||||||
|
|
||||||
exntdChar = LittleEndian.getShort(buf, offset);
|
_stringCount = LittleEndian.getShort(buf, offset);
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
stringCount = LittleEndian.getShort(buf, offset);
|
_extraDataSz = LittleEndian.getShort(buf, offset);
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
|
||||||
extraDataSz = LittleEndian.getShort(buf, offset);
|
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
|
|
||||||
if ((exntdChar & 0xFFFF) == 0xFFFF)
|
_fontNames = new Ffn[_stringCount]; //Ffn corresponds to a Pascal style String in STTBF.
|
||||||
|
|
||||||
|
for(int i = 0;i<_stringCount; i++)
|
||||||
{
|
{
|
||||||
isExtndChar = true;
|
_fontNames[i] = new Ffn(buf,offset);
|
||||||
|
offset += _fontNames[i].getSize();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
isExtndChar = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fontNames = new Ffn[stringCount]; //Ffn corresponds to a Pascal style String in STTBF.
|
|
||||||
|
|
||||||
for(int i = 0;i<stringCount; i++)
|
|
||||||
{
|
|
||||||
// some mistake in the fields we have chosen
|
|
||||||
if(offset >= this.getSize())
|
|
||||||
{
|
|
||||||
System.out.println("Total size of Sttbfn mismatched with calculated size");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fontNames[i] = new Ffn(buf,offset);
|
|
||||||
offset += fontNames[i].getSize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isExtndChar()
|
|
||||||
{
|
|
||||||
return isExtndChar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getStringCount()
|
public short getStringCount()
|
||||||
{
|
{
|
||||||
return stringCount;
|
return _stringCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getExtraDataSz()
|
||||||
|
{
|
||||||
|
return _extraDataSz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ffn[] getFontNames()
|
||||||
|
{
|
||||||
|
return _fontNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize()
|
public int getSize()
|
||||||
@ -124,31 +121,76 @@ public class FontTable
|
|||||||
|
|
||||||
public char [] getMainFont(int chpFtc )
|
public char [] getMainFont(int chpFtc )
|
||||||
{
|
{
|
||||||
if(chpFtc >= stringCount)
|
if(chpFtc >= _stringCount)
|
||||||
{
|
{
|
||||||
System.out.println("Mismatch in chpFtc with stringCount");
|
System.out.println("Mismatch in chpFtc with stringCount");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fontNames[chpFtc].getMainFontName();
|
return _fontNames[chpFtc].getMainFontName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public char [] getAltFont(int chpFtc )
|
public char [] getAltFont(int chpFtc )
|
||||||
{
|
{
|
||||||
if(chpFtc >= stringCount)
|
if(chpFtc >= _stringCount)
|
||||||
{
|
{
|
||||||
System.out.println("Mismatch in chpFtc with stringCount");
|
System.out.println("Mismatch in chpFtc with stringCount");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fontNames[chpFtc].getAltFontName();
|
return _fontNames[chpFtc].getAltFontName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStringCount(short stringCount)
|
public void setStringCount(short stringCount)
|
||||||
{
|
{
|
||||||
this.stringCount = stringCount;
|
this._stringCount = stringCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeTo(HWPFFileSystem sys)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
HWPFOutputStream tableStream = sys.getStream("1Table");
|
||||||
|
|
||||||
|
byte[] buf = new byte[LittleEndian.SHORT_SIZE];
|
||||||
|
LittleEndian.putShort(buf, _stringCount);
|
||||||
|
tableStream.write(buf);
|
||||||
|
LittleEndian.putShort(buf, _extraDataSz);
|
||||||
|
tableStream.write(buf);
|
||||||
|
|
||||||
|
for(int i = 0; i < _fontNames.length; i++)
|
||||||
|
{
|
||||||
|
tableStream.write(_fontNames[i].toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
boolean retVal = true;
|
||||||
|
|
||||||
|
if(((FontTable)o).getStringCount() == _stringCount)
|
||||||
|
{
|
||||||
|
if(((FontTable)o).getExtraDataSz() == _extraDataSz)
|
||||||
|
{
|
||||||
|
Ffn[] fontNamesNew = ((FontTable)o).getFontNames();
|
||||||
|
for(int i = 0;i<_stringCount; i++)
|
||||||
|
{
|
||||||
|
if(!(_fontNames[i].equals(fontNamesNew[i])))
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
retVal = false;
|
||||||
|
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public class PAPBinTable
|
|||||||
int end = endingFc;
|
int end = endingFc;
|
||||||
if (overflow != null)
|
if (overflow != null)
|
||||||
{
|
{
|
||||||
end = ((PropertyNode)overflow.get(0)).getStart();
|
end = ((PropertyNode)overflow.get(0)).getStart() + fcMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] intHolder = new byte[4];
|
byte[] intHolder = new byte[4];
|
||||||
|
@ -58,6 +58,7 @@ import org.apache.poi.util.LittleEndian;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a PAP FKP. The style properties for paragraph and character runs
|
* Represents a PAP FKP. The style properties for paragraph and character runs
|
||||||
@ -152,6 +153,7 @@ public class PAPFormattedDiskPage extends FormattedDiskPage
|
|||||||
int grpprlOffset = 0;
|
int grpprlOffset = 0;
|
||||||
int bxOffset = 0;
|
int bxOffset = 0;
|
||||||
int fcOffset = 0;
|
int fcOffset = 0;
|
||||||
|
byte[] lastGrpprl = new byte[0];
|
||||||
|
|
||||||
// total size is currently the size of one FC
|
// total size is currently the size of one FC
|
||||||
int totalSize = FC_SIZE;
|
int totalSize = FC_SIZE;
|
||||||
@ -159,16 +161,28 @@ public class PAPFormattedDiskPage extends FormattedDiskPage
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
for (; index < size; index++)
|
for (; index < size; index++)
|
||||||
{
|
{
|
||||||
int grpprlLength = ((PAPX)_papxList.get(index)).getGrpprl().length;
|
byte[] grpprl = ((PAPX)_papxList.get(index)).getGrpprl();
|
||||||
|
int grpprlLength = grpprl.length;
|
||||||
|
|
||||||
// check to see if we have enough room for an FC, a BX, and the grpprl
|
// check to see if we have enough room for an FC, a BX, and the grpprl
|
||||||
// and the 1 byte size of the grpprl.
|
// and the 1 byte size of the grpprl.
|
||||||
totalSize += (FC_SIZE + BX_SIZE + grpprlLength + 1);
|
int addition = 0;
|
||||||
|
if (!Arrays.equals(grpprl, lastGrpprl))
|
||||||
|
{
|
||||||
|
addition = (FC_SIZE + BX_SIZE + grpprlLength + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addition = (FC_SIZE + BX_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
totalSize += addition;
|
||||||
|
|
||||||
// if size is uneven we will have to add one so the first grpprl falls
|
// if size is uneven we will have to add one so the first grpprl falls
|
||||||
// on a word boundary
|
// on a word boundary
|
||||||
if (totalSize > 511 + (index % 2))
|
if (totalSize > 511 + (index % 2))
|
||||||
{
|
{
|
||||||
totalSize -= (FC_SIZE + BX_SIZE + grpprlLength);
|
totalSize -= addition;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,6 +195,7 @@ public class PAPFormattedDiskPage extends FormattedDiskPage
|
|||||||
{
|
{
|
||||||
totalSize += 2;
|
totalSize += 2;
|
||||||
}
|
}
|
||||||
|
lastGrpprl = grpprl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if we couldn't fit some
|
// see if we couldn't fit some
|
||||||
@ -197,14 +212,19 @@ public class PAPFormattedDiskPage extends FormattedDiskPage
|
|||||||
grpprlOffset = 511;
|
grpprlOffset = 511;
|
||||||
|
|
||||||
PAPX papx = null;
|
PAPX papx = null;
|
||||||
|
lastGrpprl = new byte[0];
|
||||||
for (int x = 0; x < index; x++)
|
for (int x = 0; x < index; x++)
|
||||||
{
|
{
|
||||||
papx = (PAPX)_papxList.get(x);
|
papx = (PAPX)_papxList.get(x);
|
||||||
byte[] phe = papx.getParagraphHeight().toByteArray();
|
byte[] phe = papx.getParagraphHeight().toByteArray();
|
||||||
byte[] grpprl = papx.getGrpprl();
|
byte[] grpprl = papx.getGrpprl();
|
||||||
|
|
||||||
grpprlOffset -= (grpprl.length + (2 - grpprl.length % 2));
|
boolean same = Arrays.equals(lastGrpprl, grpprl);
|
||||||
grpprlOffset -= (grpprlOffset % 2);
|
if (!same)
|
||||||
|
{
|
||||||
|
grpprlOffset -= (grpprl.length + (2 - grpprl.length % 2));
|
||||||
|
grpprlOffset -= (grpprlOffset % 2);
|
||||||
|
}
|
||||||
LittleEndian.putInt(buf, fcOffset, papx.getStart() + fcMin);
|
LittleEndian.putInt(buf, fcOffset, papx.getStart() + fcMin);
|
||||||
buf[bxOffset] = (byte)(grpprlOffset/2);
|
buf[bxOffset] = (byte)(grpprlOffset/2);
|
||||||
System.arraycopy(phe, 0, buf, bxOffset + 1, phe.length);
|
System.arraycopy(phe, 0, buf, bxOffset + 1, phe.length);
|
||||||
@ -212,20 +232,25 @@ public class PAPFormattedDiskPage extends FormattedDiskPage
|
|||||||
// refer to the section on PAPX in the spec. Places a size on the front
|
// refer to the section on PAPX in the spec. Places a size on the front
|
||||||
// of the PAPX. Has to do with how the grpprl stays on word
|
// of the PAPX. Has to do with how the grpprl stays on word
|
||||||
// boundaries.
|
// boundaries.
|
||||||
int copyOffset = grpprlOffset;
|
if (!same)
|
||||||
if ((grpprl.length % 2) > 0)
|
|
||||||
{
|
{
|
||||||
buf[copyOffset++] = (byte)((grpprl.length + 1)/2);
|
int copyOffset = grpprlOffset;
|
||||||
|
if ( (grpprl.length % 2) > 0)
|
||||||
|
{
|
||||||
|
buf[copyOffset++] = (byte) ( (grpprl.length + 1) / 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf[++copyOffset] = (byte) ( (grpprl.length) / 2);
|
||||||
|
copyOffset++;
|
||||||
|
}
|
||||||
|
System.arraycopy(grpprl, 0, buf, copyOffset, grpprl.length);
|
||||||
|
lastGrpprl = grpprl;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
buf[++copyOffset] = (byte)((grpprl.length)/2);
|
|
||||||
copyOffset++;
|
|
||||||
}
|
|
||||||
System.arraycopy(grpprl, 0, buf, copyOffset, grpprl.length);
|
|
||||||
|
|
||||||
bxOffset += BX_SIZE;
|
bxOffset += BX_SIZE;
|
||||||
fcOffset += FC_SIZE;
|
fcOffset += FC_SIZE;
|
||||||
|
|
||||||
}
|
}
|
||||||
// put the last papx's end in
|
// put the last papx's end in
|
||||||
LittleEndian.putInt(buf, fcOffset, papx.getEnd() + fcMin);
|
LittleEndian.putInt(buf, fcOffset, papx.getEnd() + fcMin);
|
||||||
|
@ -146,38 +146,42 @@ public class StyleDescription implements HDFType
|
|||||||
|
|
||||||
// the spec only refers to two possible upxs but it mentions
|
// the spec only refers to two possible upxs but it mentions
|
||||||
// that more may be added in the future
|
// that more may be added in the future
|
||||||
int add = 0;
|
int varOffset = grupxStart;
|
||||||
int numUPX = _numUPX.getValue(_infoShort3);
|
int numUPX = _numUPX.getValue(_infoShort3);
|
||||||
for(int x = 0; x < numUPX; x++)
|
for(int x = 0; x < numUPX; x++)
|
||||||
{
|
{
|
||||||
int upxSize = LittleEndian.getShort(std, grupxStart + add);
|
int upxSize = LittleEndian.getShort(std, varOffset);
|
||||||
|
varOffset += LittleEndian.SHORT_SIZE;
|
||||||
if(_styleTypeCode.getValue(_infoShort2) == PARAGRAPH_STYLE)
|
if(_styleTypeCode.getValue(_infoShort2) == PARAGRAPH_STYLE)
|
||||||
{
|
{
|
||||||
if(x == 0)
|
if(x == 0)
|
||||||
{
|
{
|
||||||
_istd = LittleEndian.getShort(std, grupxStart + add + 2);
|
_istd = LittleEndian.getShort(std, varOffset);
|
||||||
|
varOffset += LittleEndian.SHORT_SIZE;
|
||||||
int grrprlSize = upxSize - 2;
|
int grrprlSize = upxSize - 2;
|
||||||
_papx = new byte[upxSize];
|
_papx = new byte[grrprlSize];
|
||||||
System.arraycopy(std, grupxStart + add + 4, _papx, 0, grrprlSize);
|
System.arraycopy(std, varOffset, _papx, 0, grrprlSize);
|
||||||
|
varOffset += grrprlSize;
|
||||||
}
|
}
|
||||||
else if(x == 1)
|
else if(x == 1)
|
||||||
{
|
{
|
||||||
_chpx = new byte[upxSize];
|
_chpx = new byte[upxSize];
|
||||||
System.arraycopy(std, grupxStart + add + 2, _chpx, 0, upxSize);
|
System.arraycopy(std, varOffset, _chpx, 0, upxSize);
|
||||||
|
varOffset += upxSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(_styleTypeCode.getValue(_infoShort2) == CHARACTER_STYLE && x == 0)
|
else if(_styleTypeCode.getValue(_infoShort2) == CHARACTER_STYLE && x == 0)
|
||||||
{
|
{
|
||||||
_chpx = new byte[upxSize];
|
_chpx = new byte[upxSize];
|
||||||
System.arraycopy(std, grupxStart + add + 2, _chpx, 0, upxSize);
|
System.arraycopy(std, varOffset, _chpx, 0, upxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the upx will always start on a word boundary.
|
// the upx will always start on a word boundary.
|
||||||
if(upxSize % 2 == 1)
|
if(upxSize % 2 == 1)
|
||||||
{
|
{
|
||||||
++upxSize;
|
++varOffset;
|
||||||
}
|
}
|
||||||
add += 2 + upxSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -259,7 +263,7 @@ public class StyleDescription implements HDFType
|
|||||||
//only worry about papx and chpx for upxs
|
//only worry about papx and chpx for upxs
|
||||||
if(_styleTypeCode.getValue(_infoShort2) == PARAGRAPH_STYLE)
|
if(_styleTypeCode.getValue(_infoShort2) == PARAGRAPH_STYLE)
|
||||||
{
|
{
|
||||||
LittleEndian.putShort(buf, offset, (short)_papx.length);
|
LittleEndian.putShort(buf, offset, (short)(_papx.length + 2));
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
LittleEndian.putShort(buf, offset, (short)_istd);
|
LittleEndian.putShort(buf, offset, (short)_istd);
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
|
@ -161,7 +161,7 @@ public class StyleSheet implements HDFType
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
// add two bytes so we can prepend the styelsheet w/ its size
|
// add two bytes so we can prepend the stylesheet w/ its size
|
||||||
byte[] buf = new byte[_stshiLength + 2];
|
byte[] buf = new byte[_stshiLength + 2];
|
||||||
LittleEndian.putShort(buf, offset, (short)_stshiLength);
|
LittleEndian.putShort(buf, offset, (short)_stshiLength);
|
||||||
offset += LittleEndian.SHORT_SIZE;
|
offset += LittleEndian.SHORT_SIZE;
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package org.apache.poi.hwpf.model.hdftypes;
|
||||||
|
|
||||||
|
import junit.framework.*;
|
||||||
|
import org.apache.poi.hwpf.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class TestDocumentProperties
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
private DocumentProperties _documentProperties = null;
|
||||||
|
private HWPFDocFixture _hWPFDocFixture;
|
||||||
|
|
||||||
|
public TestDocumentProperties(String name)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testReadWrite()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
int size = _documentProperties.getSize();
|
||||||
|
byte[] buf = new byte[size];
|
||||||
|
|
||||||
|
_documentProperties.serialize(buf, 0);
|
||||||
|
|
||||||
|
DocumentProperties newDocProperties =
|
||||||
|
new DocumentProperties(buf, 0);
|
||||||
|
|
||||||
|
Field[] fields = DocumentProperties.class.getSuperclass().getDeclaredFields();
|
||||||
|
AccessibleObject.setAccessible(fields, true);
|
||||||
|
|
||||||
|
for (int x = 0; x < fields.length; x++)
|
||||||
|
{
|
||||||
|
if (!fields[x].getType().isArray())
|
||||||
|
{
|
||||||
|
assertEquals(fields[x].get(_documentProperties),
|
||||||
|
fields[x].get(newDocProperties));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] buf1 = (byte[])fields[x].get(_documentProperties);
|
||||||
|
byte[] buf2 = (byte[])fields[x].get(newDocProperties);
|
||||||
|
Arrays.equals(buf1, buf2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
super.setUp();
|
||||||
|
/**@todo verify the constructors*/
|
||||||
|
|
||||||
|
_hWPFDocFixture = new HWPFDocFixture(this);
|
||||||
|
|
||||||
|
_hWPFDocFixture.setUp();
|
||||||
|
|
||||||
|
_documentProperties = new DocumentProperties(_hWPFDocFixture._tableStream, _hWPFDocFixture._fib.getFcDop());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void tearDown()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_documentProperties = null;
|
||||||
|
_hWPFDocFixture.tearDown();
|
||||||
|
|
||||||
|
_hWPFDocFixture = null;
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
* The Apache Software License, Version 1.1
|
||||||
|
*
|
||||||
|
* Copyright (c) 2003 The Apache Software Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The end-user documentation included with the redistribution,
|
||||||
|
* if any, must include the following acknowledgment:
|
||||||
|
* "This product includes software developed by the
|
||||||
|
* Apache Software Foundation (http://www.apache.org/)."
|
||||||
|
* Alternately, this acknowledgment may appear in the software itself,
|
||||||
|
* if and wherever such third-party acknowledgments normally appear.
|
||||||
|
*
|
||||||
|
* 4. The names "Apache" and "Apache Software Foundation" and
|
||||||
|
* "Apache POI" must not be used to endorse or promote products
|
||||||
|
* derived from this software without prior written permission. For
|
||||||
|
* written permission, please contact apache@apache.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "Apache",
|
||||||
|
* "Apache POI", nor may "Apache" appear in their name, without
|
||||||
|
* prior written permission of the Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.poi.hwpf.model.hdftypes;
|
||||||
|
|
||||||
|
import junit.framework.*;
|
||||||
|
import org.apache.poi.hwpf.*;
|
||||||
|
import org.apache.poi.hwpf.model.io.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class TestFontTable
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
private FontTable _fontTable = null;
|
||||||
|
private HWPFDocFixture _hWPFDocFixture;
|
||||||
|
|
||||||
|
public TestFontTable(String name)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReadWrite()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
FileInformationBlock fib = _hWPFDocFixture._fib;
|
||||||
|
byte[] tableStream = _hWPFDocFixture._tableStream;
|
||||||
|
|
||||||
|
int fcSttbfffn = fib.getFcSttbfffn();
|
||||||
|
int lcbSttbfffn = fib.getLcbSttbfffn();
|
||||||
|
|
||||||
|
_fontTable = new FontTable(tableStream, fcSttbfffn, lcbSttbfffn);
|
||||||
|
|
||||||
|
HWPFFileSystem fileSys = new HWPFFileSystem();
|
||||||
|
|
||||||
|
_fontTable.writeTo(fileSys);
|
||||||
|
HWPFOutputStream tableOut = fileSys.getStream("1Table");
|
||||||
|
|
||||||
|
|
||||||
|
byte[] newTableStream = tableOut.toByteArray();
|
||||||
|
|
||||||
|
|
||||||
|
FontTable newFontTable = new FontTable(newTableStream, 0, newTableStream.length);
|
||||||
|
|
||||||
|
assertTrue(_fontTable.equals(newFontTable));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUp()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
super.setUp();
|
||||||
|
/**@todo verify the constructors*/
|
||||||
|
_hWPFDocFixture = new HWPFDocFixture(this);
|
||||||
|
|
||||||
|
_hWPFDocFixture.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void tearDown()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
_hWPFDocFixture.tearDown();
|
||||||
|
|
||||||
|
_hWPFDocFixture = null;
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user