1 2 17 18 19 package org.apache.poi.poifs.storage; 20 21 import java.io.*; 22 23 import java.util.*; 24 25 import org.apache.poi.poifs.common.POIFSConstants; 26 27 33 34 public class SmallDocumentBlock 35 implements BlockWritable, ListManagedBlock 36 { 37 private byte[] _data; 38 private static final byte _default_fill = ( byte ) 0xff; 39 private static final int _block_size = 64; 40 private static final int _blocks_per_big_block = 41 POIFSConstants.BIG_BLOCK_SIZE / _block_size; 42 43 private SmallDocumentBlock(final byte [] data, final int index) 44 { 45 this(); 46 System.arraycopy(data, index * _block_size, _data, 0, _block_size); 47 } 48 49 private SmallDocumentBlock() 50 { 51 _data = new byte[ _block_size ]; 52 } 53 54 64 65 public static SmallDocumentBlock [] convert(final byte [] array, 66 final int size) 67 { 68 SmallDocumentBlock[] rval = 69 new SmallDocumentBlock[ (size + _block_size - 1) / _block_size ]; 70 int offset = 0; 71 72 for (int k = 0; k < rval.length; k++) 73 { 74 rval[ k ] = new SmallDocumentBlock(); 75 if (offset < array.length) 76 { 77 int length = Math.min(_block_size, array.length - offset); 78 79 System.arraycopy(array, offset, rval[ k ]._data, 0, length); 80 if (length != _block_size) 81 { 82 Arrays.fill(rval[ k ]._data, length, _block_size, 83 _default_fill); 84 } 85 } 86 else 87 { 88 Arrays.fill(rval[ k ]._data, _default_fill); 89 } 90 offset += _block_size; 91 } 92 return rval; 93 } 94 95 103 104 public static int fill(final List blocks) 105 { 106 int count = blocks.size(); 107 int big_block_count = (count + _blocks_per_big_block - 1) 108 / _blocks_per_big_block; 109 int full_count = big_block_count * _blocks_per_big_block; 110 111 for (; count < full_count; count++) 112 { 113 blocks.add(makeEmptySmallDocumentBlock()); 114 } 115 return big_block_count; 116 } 117 118 130 131 public static SmallDocumentBlock [] convert(final BlockWritable [] store, 132 final int size) 133 throws IOException, ArrayIndexOutOfBoundsException 134 { 135 ByteArrayOutputStream stream = new ByteArrayOutputStream(); 136 137 for (int j = 0; j < store.length; j++) 138 { 139 store[ j ].writeBlocks(stream); 140 } 141 byte[] data = stream.toByteArray(); 142 SmallDocumentBlock[] rval = 143 new SmallDocumentBlock[ convertToBlockCount(size) ]; 144 145 for (int index = 0; index < rval.length; index++) 146 { 147 rval[ index ] = new SmallDocumentBlock(data, index); 148 } 149 return rval; 150 } 151 152 162 163 public static List extract(ListManagedBlock [] blocks) 164 throws IOException 165 { 166 List sdbs = new ArrayList(); 167 168 for (int j = 0; j < blocks.length; j++) 169 { 170 byte[] data = blocks[ j ].getData(); 171 172 for (int k = 0; k < _blocks_per_big_block; k++) 173 { 174 sdbs.add(new SmallDocumentBlock(data, k)); 175 } 176 } 177 return sdbs; 178 } 179 180 187 188 public static void read(final BlockWritable [] blocks, 189 final byte [] buffer, final int offset) 190 { 191 int firstBlockIndex = offset / _block_size; 192 int firstBlockOffset = offset % _block_size; 193 int lastBlockIndex = (offset + buffer.length - 1) / _block_size; 194 195 if (firstBlockIndex == lastBlockIndex) 196 { 197 System.arraycopy( 198 (( SmallDocumentBlock ) blocks[ firstBlockIndex ])._data, 199 firstBlockOffset, buffer, 0, buffer.length); 200 } 201 else 202 { 203 int buffer_offset = 0; 204 205 System.arraycopy( 206 (( SmallDocumentBlock ) blocks[ firstBlockIndex ])._data, 207 firstBlockOffset, buffer, buffer_offset, 208 _block_size - firstBlockOffset); 209 buffer_offset += _block_size - firstBlockOffset; 210 for (int j = firstBlockIndex + 1; j < lastBlockIndex; j++) 211 { 212 System.arraycopy((( SmallDocumentBlock ) blocks[ j ])._data, 213 0, buffer, buffer_offset, _block_size); 214 buffer_offset += _block_size; 215 } 216 System.arraycopy( 217 (( SmallDocumentBlock ) blocks[ lastBlockIndex ])._data, 0, 218 buffer, buffer_offset, buffer.length - buffer_offset); 219 } 220 } 221 222 229 230 public static int calcSize(int size) 231 { 232 return size * _block_size; 233 } 234 235 private static SmallDocumentBlock makeEmptySmallDocumentBlock() 236 { 237 SmallDocumentBlock block = new SmallDocumentBlock(); 238 239 Arrays.fill(block._data, _default_fill); 240 return block; 241 } 242 243 private static int convertToBlockCount(final int size) 244 { 245 return (size + _block_size - 1) / _block_size; 246 } 247 248 249 250 259 260 public void writeBlocks(final OutputStream stream) 261 throws IOException 262 { 263 stream.write(_data); 264 } 265 266 267 268 269 276 277 public byte [] getData() 278 throws IOException 279 { 280 return _data; 281 } 282 283 284 } 286 | Popular Tags |