fix the same problem as with PAPX -- CHPX shall be stored based on text positions, not on bytes

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1144638 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sergey Vladimirov 2011-07-09 11:08:45 +00:00
parent 3e5fd147eb
commit d07d8ec7f7
3 changed files with 43 additions and 24 deletions

View File

@ -17,17 +17,18 @@
package org.apache.poi.hwpf.model; package org.apache.poi.hwpf.model;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.ArrayList;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.poi.hwpf.model.io.HWPFFileSystem;
import org.apache.poi.hwpf.model.io.HWPFOutputStream;
import org.apache.poi.hwpf.sprm.SprmBuffer;
import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
import org.apache.poi.hwpf.model.io.*;
import org.apache.poi.hwpf.sprm.SprmBuffer;
/** /**
* This class holds all of the character formatting properties. * This class holds all of the character formatting properties.
@ -69,16 +70,24 @@ public class CHPBinTable
* @param size * @param size
* @param fcMin * @param fcMin
*/ */
public CHPBinTable(byte[] documentStream, byte[] tableStream, int offset, public CHPBinTable( byte[] documentStream, byte[] tableStream, int offset,
int size, int fcMin, TextPieceTable tpt) int size, int fcMin, TextPieceTable tpt )
{ {
PlexOfCps binTable = new PlexOfCps(tableStream, offset, size, 4); /*
* Page 35:
*
* "Associated with each interval is a BTE. A BTE holds a four-byte PN
* (page number) which identifies the FKP page in the file which
* contains the formatting information for that interval. A CHPX FKP
* further partitions an interval into runs of exception text."
*/
PlexOfCps bte = new PlexOfCps( tableStream, offset, size, 4 );
this.tpt = tpt; this.tpt = tpt;
int length = binTable.length(); int length = bte.length();
for (int x = 0; x < length; x++) for (int x = 0; x < length; x++)
{ {
GenericPropertyNode node = binTable.getProperty(x); GenericPropertyNode node = bte.getProperty(x);
int pageNum = LittleEndian.getInt(node.getBytes()); int pageNum = LittleEndian.getInt(node.getBytes());
int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum;
@ -202,7 +211,15 @@ public class CHPBinTable
HWPFOutputStream docStream = sys.getStream("WordDocument"); HWPFOutputStream docStream = sys.getStream("WordDocument");
OutputStream tableStream = sys.getStream("1Table"); OutputStream tableStream = sys.getStream("1Table");
PlexOfCps binTable = new PlexOfCps(4); /*
* Page 35:
*
* "Associated with each interval is a BTE. A BTE holds a four-byte PN
* (page number) which identifies the FKP page in the file which
* contains the formatting information for that interval. A CHPX FKP
* further partitions an interval into runs of exception text."
*/
PlexOfCps bte = new PlexOfCps( 4 );
// each FKP must start on a 512 byte page. // each FKP must start on a 512 byte page.
int docOffset = docStream.getOffset(); int docOffset = docStream.getOffset();
@ -232,7 +249,7 @@ public class CHPBinTable
CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(); CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage();
cfkp.fill(overflow); cfkp.fill(overflow);
byte[] bufFkp = cfkp.toByteArray(fcMin); byte[] bufFkp = cfkp.toByteArray( tpt, fcMin );
docStream.write(bufFkp); docStream.write(bufFkp);
overflow = cfkp.getOverflow(); overflow = cfkp.getOverflow();
@ -244,10 +261,10 @@ public class CHPBinTable
byte[] intHolder = new byte[4]; byte[] intHolder = new byte[4];
LittleEndian.putInt(intHolder, pageNum++); LittleEndian.putInt(intHolder, pageNum++);
binTable.addProperty(new GenericPropertyNode(start, end, intHolder)); bte.addProperty(new GenericPropertyNode(start, end, intHolder));
} }
while (overflow != null); while (overflow != null);
tableStream.write(binTable.toByteArray()); tableStream.write(bte.toByteArray());
} }
} }

View File

@ -17,8 +17,8 @@
package org.apache.poi.hwpf.model; package org.apache.poi.hwpf.model;
import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -110,7 +110,7 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage
return chpx; return chpx;
} }
protected byte[] toByteArray(int fcMin) protected byte[] toByteArray(CharIndexTranslator translator, int fcMin)
{ {
byte[] buf = new byte[512]; byte[] buf = new byte[512];
int size = _chpxList.size(); int size = _chpxList.size();
@ -163,7 +163,9 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage
chpx = (CHPX)_chpxList.get(x); chpx = (CHPX)_chpxList.get(x);
byte[] grpprl = chpx.getGrpprl(); byte[] grpprl = chpx.getGrpprl();
LittleEndian.putInt(buf, fcOffset, chpx.getStartBytes() + fcMin); LittleEndian.putInt( buf, fcOffset,
translator.getByteIndex( chpx.getStart() ) );
grpprlOffset -= (1 + grpprl.length); grpprlOffset -= (1 + grpprl.length);
grpprlOffset -= (grpprlOffset % 2); grpprlOffset -= (grpprlOffset % 2);
buf[offsetOffset] = (byte)(grpprlOffset/2); buf[offsetOffset] = (byte)(grpprlOffset/2);
@ -174,7 +176,8 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage
fcOffset += FC_SIZE; fcOffset += FC_SIZE;
} }
// put the last chpx's end in // put the last chpx's end in
LittleEndian.putInt(buf, fcOffset, chpx.getEndBytes() + fcMin); LittleEndian.putInt( buf, fcOffset,
translator.getByteIndex( chpx.getEnd() ) );
return buf; return buf;
} }

View File

@ -17,8 +17,6 @@
package org.apache.poi.hwpf.usermodel; package org.apache.poi.hwpf.usermodel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
@ -566,7 +564,8 @@ public final class TestProblems extends HWPFTestCase {
// doc1.write( fileOutputStream ); // doc1.write( fileOutputStream );
// fileOutputStream.close(); // fileOutputStream.close();
fixed( "47286" ); // not fixed yet, but still better
// fixed( "47286" );
} }
catch ( AssertionFailedError exc ) catch ( AssertionFailedError exc )
{ {