KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > poifs > storage > BATBlock


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

17         
18
19 package org.apache.poi.poifs.storage;
20
21 import java.io.IOException JavaDoc;
22 import java.io.OutputStream JavaDoc;
23
24 import java.util.Arrays JavaDoc;
25
26 import org.apache.poi.poifs.common.POIFSConstants;
27 import org.apache.poi.util.IntegerField;
28 import org.apache.poi.util.LittleEndian;
29 import org.apache.poi.util.LittleEndianConsts;
30
31 /**
32  * A block of block allocation table entries. BATBlocks are created
33  * only through a static factory method: createBATBlocks.
34  *
35  * @author Marc Johnson (mjohnson at apache dot org)
36  */

37
38 public class BATBlock
39     extends BigBlock
40 {
41     private static final int _entries_per_block =
42         POIFSConstants.BIG_BLOCK_SIZE / LittleEndianConsts.INT_SIZE;
43     private static final int _entries_per_xbat_block = _entries_per_block
44                                                             - 1;
45     private static final int _xbat_chain_offset =
46         _entries_per_xbat_block * LittleEndianConsts.INT_SIZE;
47     private static final byte _default_value = ( byte ) 0xFF;
48     private IntegerField[] _fields;
49     private byte[] _data;
50
51     /**
52      * Create a single instance initialized with default values
53      */

54
55     private BATBlock()
56     {
57         _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ];
58         Arrays.fill(_data, _default_value);
59         _fields = new IntegerField[ _entries_per_block ];
60         int offset = 0;
61
62         for (int j = 0; j < _entries_per_block; j++)
63         {
64             _fields[ j ] = new IntegerField(offset);
65             offset += LittleEndianConsts.INT_SIZE;
66         }
67     }
68
69     /**
70      * Create an array of BATBlocks from an array of int block
71      * allocation table entries
72      *
73      * @param entries the array of int entries
74      *
75      * @return the newly created array of BATBlocks
76      */

77
78     public static BATBlock [] createBATBlocks(final int [] entries)
79     {
80         int block_count = calculateStorageRequirements(entries.length);
81         BATBlock[] blocks = new BATBlock[ block_count ];
82         int index = 0;
83         int remaining = entries.length;
84
85         for (int j = 0; j < entries.length; j += _entries_per_block)
86         {
87             blocks[ index++ ] = new BATBlock(entries, j,
88                                              (remaining > _entries_per_block)
89                                              ? j + _entries_per_block
90                                              : entries.length);
91             remaining -= _entries_per_block;
92         }
93         return blocks;
94     }
95
96     /**
97      * Create an array of XBATBlocks from an array of int block
98      * allocation table entries
99      *
100      * @param entries the array of int entries
101      * @param startBlock the start block of the array of XBAT blocks
102      *
103      * @return the newly created array of BATBlocks
104      */

105
106     public static BATBlock [] createXBATBlocks(final int [] entries,
107                                                final int startBlock)
108     {
109         int block_count =
110             calculateXBATStorageRequirements(entries.length);
111         BATBlock[] blocks = new BATBlock[ block_count ];
112         int index = 0;
113         int remaining = entries.length;
114
115         if (block_count != 0)
116         {
117             for (int j = 0; j < entries.length; j += _entries_per_xbat_block)
118             {
119                 blocks[ index++ ] =
120                     new BATBlock(entries, j,
121                                  (remaining > _entries_per_xbat_block)
122                                  ? j + _entries_per_xbat_block
123                                  : entries.length);
124                 remaining -= _entries_per_xbat_block;
125             }
126             for (index = 0; index < blocks.length - 1; index++)
127             {
128                 blocks[ index ].setXBATChain(startBlock + index + 1);
129             }
130             blocks[ index ].setXBATChain(POIFSConstants.END_OF_CHAIN);
131         }
132         return blocks;
133     }
134
135     /**
136      * Calculate how many BATBlocks are needed to hold a specified
137      * number of BAT entries.
138      *
139      * @param entryCount the number of entries
140      *
141      * @return the number of BATBlocks needed
142      */

143
144     public static int calculateStorageRequirements(final int entryCount)
145     {
146         return (entryCount + _entries_per_block - 1) / _entries_per_block;
147     }
148
149     /**
150      * Calculate how many XBATBlocks are needed to hold a specified
151      * number of BAT entries.
152      *
153      * @param entryCount the number of entries
154      *
155      * @return the number of XBATBlocks needed
156      */

157
158     public static int calculateXBATStorageRequirements(final int entryCount)
159     {
160         return (entryCount + _entries_per_xbat_block - 1)
161                / _entries_per_xbat_block;
162     }
163
164     /**
165      * @return number of entries per block
166      */

167
168     public static final int entriesPerBlock()
169     {
170         return _entries_per_block;
171     }
172
173     /**
174      * @return number of entries per XBAT block
175      */

176
177     public static final int entriesPerXBATBlock()
178     {
179         return _entries_per_xbat_block;
180     }
181
182     /**
183      * @return offset of chain index of XBAT block
184      */

185
186     public static final int getXBATChainOffset()
187     {
188         return _xbat_chain_offset;
189     }
190
191     private void setXBATChain(int chainIndex)
192     {
193         _fields[ _entries_per_xbat_block ].set(chainIndex, _data);
194     }
195
196     /**
197      * Create a single instance initialized (perhaps partially) with entries
198      *
199      * @param entries the array of block allocation table entries
200      * @param start_index the index of the first entry to be written
201      * to the block
202      * @param end_index the index, plus one, of the last entry to be
203      * written to the block (writing is for all index
204      * k, start_index <= k < end_index)
205      */

206
207     private BATBlock(final int [] entries, final int start_index,
208                      final int end_index)
209     {
210         this();
211         for (int k = start_index; k < end_index; k++)
212         {
213             _fields[ k - start_index ].set(entries[ k ], _data);
214         }
215     }
216
217     /* ********** START extension of BigBlock ********** */
218
219     /**
220      * Write the block's data to an OutputStream
221      *
222      * @param stream the OutputStream to which the stored data should
223      * be written
224      *
225      * @exception IOException on problems writing to the specified
226      * stream
227      */

228
229     void writeData(final OutputStream JavaDoc stream)
230         throws IOException JavaDoc
231     {
232         doWriteData(stream, _data);
233     }
234
235     /* ********** END extension of BigBlock ********** */
236 } // end public class BATBlock
237

238
Popular Tags