1 2 /* ==================================================================== 3 * The Apache Software License, Version 1.1 4 * 5 * Copyright (c) 2002 The Apache Software Foundation. All rights 6 * reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The end-user documentation included with the redistribution, 21 * if any, must include the following acknowledgment: 22 * "This product includes software developed by the 23 * Apache Software Foundation (http://www.apache.org/)." 24 * Alternately, this acknowledgment may appear in the software itself, 25 * if and wherever such third-party acknowledgments normally appear. 26 * 27 * 4. The names "Apache" and "Apache Software Foundation" and 28 * "Apache POI" must not be used to endorse or promote products 29 * derived from this software without prior written permission. For 30 * written permission, please contact apache@apache.org. 31 * 32 * 5. Products derived from this software may not be called "Apache", 33 * "Apache POI", nor may "Apache" appear in their name, without 34 * prior written permission of the Apache Software Foundation. 35 * 36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This software consists of voluntary contributions made by many 51 * individuals on behalf of the Apache Software Foundation. For more 52 * information on the Apache Software Foundation, please see 53 * <http://www.apache.org/>. 54 */ 55 56 package org.apache.poi.poifs.storage; 57 58 import java.io.*; 59 60 import java.util.*; 61 62 import org.apache.poi.poifs.common.POIFSConstants; 63 import org.apache.poi.util.IntegerField; 64 import org.apache.poi.util.LittleEndian; 65 import org.apache.poi.util.LittleEndianConsts; 66 import org.apache.poi.util.LongField; 67 import org.apache.poi.util.ShortField; 68 69 /** 70 * The block containing the archive header 71 * 72 * @author Marc Johnson (mjohnson at apache dot org) 73 */ 74 75 public class HeaderBlockReader 76 implements HeaderBlockConstants 77 { 78 79 // number of big block allocation table blocks (int) 80 private IntegerField _bat_count; 81 82 // start of the property set block (int index of the property set 83 // chain's first big block) 84 private IntegerField _property_start; 85 86 // start of the small block allocation table (int index of small 87 // block allocation table's first big block) 88 private IntegerField _sbat_start; 89 90 // big block index for extension to the big block allocation table 91 private IntegerField _xbat_start; 92 private IntegerField _xbat_count; 93 private byte[] _data; 94 95 /** 96 * create a new HeaderBlockReader from an InputStream 97 * 98 * @param stream the source InputStream 99 * 100 * @exception IOException on errors or bad data 101 */ 102 103 public HeaderBlockReader(final InputStream stream) 104 throws IOException 105 { 106 _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ]; 107 int byte_count = stream.read(_data); 108 109 if (byte_count != POIFSConstants.BIG_BLOCK_SIZE) 110 { 111 String type = " byte" + ((byte_count == 1) ? ("") 112 : ("s")); 113 114 throw new IOException("Unable to read entire header; " 115 + byte_count + type + " read; expected " 116 + POIFSConstants.BIG_BLOCK_SIZE + " bytes"); 117 } 118 119 // verify signature 120 LongField signature = new LongField(_signature_offset, _data); 121 122 if (signature.get() != _signature) 123 { 124 throw new IOException("Invalid header signature; read " 125 + signature.get() + ", expected " 126 + _signature); 127 } 128 _bat_count = new IntegerField(_bat_count_offset, _data); 129 _property_start = new IntegerField(_property_start_offset, _data); 130 _sbat_start = new IntegerField(_sbat_start_offset, _data); 131 _xbat_start = new IntegerField(_xbat_start_offset, _data); 132 _xbat_count = new IntegerField(_xbat_count_offset, _data); 133 } 134 135 /** 136 * get start of Property Table 137 * 138 * @return the index of the first block of the Property Table 139 */ 140 141 public int getPropertyStart() 142 { 143 return _property_start.get(); 144 } 145 146 /** 147 * @return start of small block allocation table 148 */ 149 150 public int getSBATStart() 151 { 152 return _sbat_start.get(); 153 } 154 155 /** 156 * @return number of BAT blocks 157 */ 158 159 public int getBATCount() 160 { 161 return _bat_count.get(); 162 } 163 164 /** 165 * @return BAT array 166 */ 167 168 public int [] getBATArray() 169 { 170 int[] result = new int[ _max_bats_in_header ]; 171 int offset = _bat_array_offset; 172 173 for (int j = 0; j < _max_bats_in_header; j++) 174 { 175 result[ j ] = LittleEndian.getInt(_data, offset); 176 offset += LittleEndianConsts.INT_SIZE; 177 } 178 return result; 179 } 180 181 /** 182 * @return XBAT count 183 */ 184 185 public int getXBATCount() 186 { 187 return _xbat_count.get(); 188 } 189 190 /** 191 * @return XBAT index 192 */ 193 194 public int getXBATIndex() 195 { 196 return _xbat_start.get(); 197 } 198 } // end public class HeaderBlockReader 199 200