From 9864686a25f5f040cba3b1ac89b0efe834976ac3 Mon Sep 17 00:00:00 2001 From: Sergey Vladimirov Date: Sat, 9 Jul 2011 11:08:45 +0000 Subject: [PATCH] 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 --- .../apache/poi/hwpf/model/CHPBinTable.java | 49 +++++++++++++------ .../poi/hwpf/model/CHPFormattedDiskPage.java | 13 +++-- .../poi/hwpf/usermodel/TestProblems.java | 5 +- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java index aaa9ceedbd..d616f51140 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPBinTable.java @@ -17,17 +17,18 @@ 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.Comparator; 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.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. @@ -69,16 +70,24 @@ public class CHPBinTable * @param size * @param fcMin */ - public CHPBinTable(byte[] documentStream, byte[] tableStream, int offset, - int size, int fcMin, TextPieceTable tpt) - { - PlexOfCps binTable = new PlexOfCps(tableStream, offset, size, 4); - this.tpt = tpt; + public CHPBinTable( byte[] documentStream, byte[] tableStream, int offset, + int size, int fcMin, TextPieceTable tpt ) + { + /* + * 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; - int length = binTable.length(); + int length = bte.length(); for (int x = 0; x < length; x++) { - GenericPropertyNode node = binTable.getProperty(x); + GenericPropertyNode node = bte.getProperty(x); int pageNum = LittleEndian.getInt(node.getBytes()); int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; @@ -202,7 +211,15 @@ public class CHPBinTable HWPFOutputStream docStream = sys.getStream("WordDocument"); 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. int docOffset = docStream.getOffset(); @@ -232,7 +249,7 @@ public class CHPBinTable CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(); cfkp.fill(overflow); - byte[] bufFkp = cfkp.toByteArray(fcMin); + byte[] bufFkp = cfkp.toByteArray( tpt, fcMin ); docStream.write(bufFkp); overflow = cfkp.getOverflow(); @@ -244,10 +261,10 @@ public class CHPBinTable byte[] intHolder = new byte[4]; LittleEndian.putInt(intHolder, pageNum++); - binTable.addProperty(new GenericPropertyNode(start, end, intHolder)); + bte.addProperty(new GenericPropertyNode(start, end, intHolder)); } while (overflow != null); - tableStream.write(binTable.toByteArray()); + tableStream.write(bte.toByteArray()); } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java index 10bb77d851..496e7f4acf 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPFormattedDiskPage.java @@ -17,8 +17,8 @@ package org.apache.poi.hwpf.model; -import java.util.List; import java.util.ArrayList; +import java.util.List; import org.apache.poi.util.LittleEndian; @@ -110,7 +110,7 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage return chpx; } - protected byte[] toByteArray(int fcMin) + protected byte[] toByteArray(CharIndexTranslator translator, int fcMin) { byte[] buf = new byte[512]; int size = _chpxList.size(); @@ -163,7 +163,9 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage chpx = (CHPX)_chpxList.get(x); byte[] grpprl = chpx.getGrpprl(); - LittleEndian.putInt(buf, fcOffset, chpx.getStartBytes() + fcMin); + LittleEndian.putInt( buf, fcOffset, + translator.getByteIndex( chpx.getStart() ) ); + grpprlOffset -= (1 + grpprl.length); grpprlOffset -= (grpprlOffset % 2); buf[offsetOffset] = (byte)(grpprlOffset/2); @@ -173,8 +175,9 @@ public final class CHPFormattedDiskPage extends FormattedDiskPage offsetOffset += 1; fcOffset += FC_SIZE; } - // put the last chpx's end in - LittleEndian.putInt(buf, fcOffset, chpx.getEndBytes() + fcMin); + // put the last chpx's end in + LittleEndian.putInt( buf, fcOffset, + translator.getByteIndex( chpx.getEnd() ) ); return buf; } diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java index 9618cbacca..f52df00e71 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java @@ -17,8 +17,6 @@ package org.apache.poi.hwpf.usermodel; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; @@ -566,7 +564,8 @@ public final class TestProblems extends HWPFTestCase { // doc1.write( fileOutputStream ); // fileOutputStream.close(); - fixed( "47286" ); + // not fixed yet, but still better + // fixed( "47286" ); } catch ( AssertionFailedError exc ) {