KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > hwpf > model > SectionTable


1 /* ====================================================================
2    Copyright 2002-2004 Apache Software Foundation
3
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7
8        http://www.apache.org/licenses/LICENSE-2.0
9
10    Unless required by applicable law or agreed to in writing, software
11    distributed under the License is distributed on an "AS IS" BASIS,
12    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    See the License for the specific language governing permissions and
14    limitations under the License.
15 ==================================================================== */

16
17 package org.apache.poi.hwpf.model;
18
19 import java.util.ArrayList JavaDoc;
20 import java.io.ByteArrayOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.util.List JavaDoc;
23
24 import org.apache.poi.util.LittleEndian;
25 import org.apache.poi.hwpf.model.io.*;
26
27 /**
28  * @author Ryan Ackley
29  */

30 public class SectionTable
31 {
32   private static final int SED_SIZE = 12;
33
34   protected ArrayList JavaDoc _sections = new ArrayList JavaDoc();
35   protected List JavaDoc _text;
36
37   public SectionTable()
38   {
39   }
40
41
42   public SectionTable(byte[] documentStream, byte[] tableStream, int offset,
43                       int size, int fcMin,
44                       List JavaDoc tpt)
45   {
46     PlexOfCps sedPlex = new PlexOfCps(tableStream, offset, size, SED_SIZE);
47     _text = tpt;
48
49     int length = sedPlex.length();
50
51     for (int x = 0; x < length; x++)
52     {
53       GenericPropertyNode node = sedPlex.getProperty(x);
54       SectionDescriptor sed = new SectionDescriptor(node.getBytes(), 0);
55
56       int fileOffset = sed.getFc();
57
58       // check for the optimization
59
if (fileOffset == 0xffffffff)
60       {
61         _sections.add(new SEPX(sed, CPtoFC(node.getStart()), CPtoFC(node.getEnd()), new byte[0]));
62       }
63       else
64       {
65         // The first short at the offset is the size of the grpprl.
66
int sepxSize = LittleEndian.getShort(documentStream, fileOffset);
67         byte[] buf = new byte[sepxSize];
68         fileOffset += LittleEndian.SHORT_SIZE;
69         System.arraycopy(documentStream, fileOffset, buf, 0, buf.length);
70         _sections.add(new SEPX(sed, CPtoFC(node.getStart()), CPtoFC(node.getEnd()), buf));
71       }
72     }
73   }
74
75   public void adjustForInsert(int listIndex, int length)
76   {
77     int size = _sections.size();
78     SEPX sepx = (SEPX)_sections.get(listIndex);
79     sepx.setEnd(sepx.getEnd() + length);
80
81     for (int x = listIndex + 1; x < size; x++)
82     {
83       sepx = (SEPX)_sections.get(x);
84       sepx.setStart(sepx.getStart() + length);
85       sepx.setEnd(sepx.getEnd() + length);
86     }
87   }
88
89   // goss version of CPtoFC - this takes into account non-contiguous textpieces
90
// that we have come across in real world documents. Tests against the example
91
// code in HWPFDocument show no variation to Ryan's version of the code in
92
// normal use, but this version works with our non-contiguous test case.
93
// So far unable to get this test case to be written out as well due to
94
// other issues. - piers
95
private int CPtoFC(int CP)
96   {
97       TextPiece TP = null;
98
99       for(int i=_text.size()-1; i>-1; i--)
100       {
101         TP = (TextPiece)_text.get(i);
102
103         if(CP >= TP.getCP()) break;
104       }
105       int FC = TP.getPieceDescriptor().getFilePosition();
106       int offset = CP - TP.getCP();
107       if(TP.usesUnicode()) offset*=2;
108       FC = FC+offset-((TextPiece)_text.get(0)).getPieceDescriptor().getFilePosition();
109       return FC;
110     }
111
112     // Ryans code
113
private int FCtoCP(int fc)
114    {
115      int size = _text.size();
116      int cp = 0;
117      for (int x = 0; x < size; x++)
118      {
119        TextPiece piece = (TextPiece)_text.get(x);
120
121        if (fc <= piece.getEnd())
122        {
123          cp += ((fc - piece.getStart())/ (piece.usesUnicode() ? 2 : 1));
124          break;
125        }
126        else
127        {
128          cp += ((piece.getEnd() - piece.getStart())/ (piece.usesUnicode() ? 2 : 1));
129        }
130      }
131      return cp;
132    }
133
134
135   public ArrayList JavaDoc getSections()
136   {
137     return _sections;
138   }
139
140   public void writeTo(HWPFFileSystem sys, int fcMin)
141     throws IOException JavaDoc
142   {
143     HWPFOutputStream docStream = sys.getStream("WordDocument");
144     HWPFOutputStream tableStream = sys.getStream("1Table");
145
146     int offset = docStream.getOffset();
147     int len = _sections.size();
148     PlexOfCps plex = new PlexOfCps(SED_SIZE);
149
150     for (int x = 0; x < len; x++)
151     {
152       SEPX sepx = (SEPX)_sections.get(x);
153       byte[] grpprl = sepx.getGrpprl();
154
155       // write the sepx to the document stream. starts with a 2 byte size
156
// followed by the grpprl
157
byte[] shortBuf = new byte[2];
158       LittleEndian.putShort(shortBuf, (short)grpprl.length);
159
160       docStream.write(shortBuf);
161       docStream.write(grpprl);
162
163       // set the fc in the section descriptor
164
SectionDescriptor sed = sepx.getSectionDescriptor();
165       sed.setFc(offset);
166
167       // add the section descriptor bytes to the PlexOfCps.
168

169
170       // original line -
171
//GenericPropertyNode property = new GenericPropertyNode(sepx.getStart(), sepx.getEnd(), sed.toByteArray());
172

173       // Line using Ryan's FCtoCP() conversion method -
174
// unable to observe any effect on our testcases when using this code - piers
175
GenericPropertyNode property = new GenericPropertyNode(FCtoCP(sepx.getStart()), FCtoCP(sepx.getEnd()), sed.toByteArray());
176
177
178       plex.addProperty(property);
179
180       offset = docStream.getOffset();
181     }
182     tableStream.write(plex.toByteArray());
183   }
184 }
185
Popular Tags