1 2 17 18 19 package org.apache.poi.poifs.storage; 20 21 import java.io.IOException ; 22 import java.io.OutputStream ; 23 24 import java.util.Arrays ; 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 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 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 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 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 143 144 public static int calculateStorageRequirements(final int entryCount) 145 { 146 return (entryCount + _entries_per_block - 1) / _entries_per_block; 147 } 148 149 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 167 168 public static final int entriesPerBlock() 169 { 170 return _entries_per_block; 171 } 172 173 176 177 public static final int entriesPerXBATBlock() 178 { 179 return _entries_per_xbat_block; 180 } 181 182 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 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 218 219 228 229 void writeData(final OutputStream stream) 230 throws IOException 231 { 232 doWriteData(stream, _data); 233 } 234 235 236 } 238 | Popular Tags |