Return-Path: Delivered-To: apmail-poi-commits-archive@minotaur.apache.org Received: (qmail 85675 invoked from network); 19 Dec 2010 07:17:38 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 19 Dec 2010 07:17:38 -0000 Received: (qmail 96941 invoked by uid 500); 19 Dec 2010 07:17:37 -0000 Delivered-To: apmail-poi-commits-archive@poi.apache.org Received: (qmail 96903 invoked by uid 500); 19 Dec 2010 07:17:37 -0000 Mailing-List: contact commits-help@poi.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@poi.apache.org Delivered-To: mailing list commits@poi.apache.org Received: (qmail 96896 invoked by uid 99); 19 Dec 2010 07:17:36 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 19 Dec 2010 07:17:36 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 19 Dec 2010 07:17:35 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 2855E23888CF; Sun, 19 Dec 2010 07:17:15 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1050770 - in /poi/trunk/src/java/org/apache/poi/poifs/storage: BATBlock.java BigBlock.java Date: Sun, 19 Dec 2010 07:17:15 -0000 To: commits@poi.apache.org From: nick@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101219071715.2855E23888CF@eris.apache.org> Author: nick Date: Sun Dec 19 07:17:14 2010 New Revision: 1050770 URL: http://svn.apache.org/viewvc?rev=1050770&view=rev Log: Make BATBlock useful for read (was previously write only) Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java poi/trunk/src/java/org/apache/poi/poifs/storage/BigBlock.java Modified: poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java?rev=1050770&r1=1050769&r2=1050770&view=diff ============================================================================== --- poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java (original) +++ poi/trunk/src/java/org/apache/poi/poifs/storage/BATBlock.java Sun Dec 19 07:17:14 2010 @@ -19,13 +19,12 @@ package org.apache.poi.poifs.storage; import java.io.IOException; import java.io.OutputStream; - +import java.nio.ByteBuffer; import java.util.Arrays; import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; -import org.apache.poi.util.IntegerField; -import org.apache.poi.util.LittleEndianConsts; +import org.apache.poi.util.LittleEndian; /** * A block of block allocation table entries. BATBlocks are created @@ -34,10 +33,19 @@ import org.apache.poi.util.LittleEndianC * @author Marc Johnson (mjohnson at apache dot org) */ public final class BATBlock extends BigBlock { - private static final byte _default_value = ( byte ) 0xFF; - private IntegerField[] _fields; - private byte[] _data; - + /** + * For a regular fat block, these are 128 / 1024 + * next sector values. + * For a XFat (DIFat) block, these are 127 / 1023 + * next sector values, then a chaining value. + */ + private int[] _values; + + /** + * Does this BATBlock have any free sectors in it? + */ + private boolean _has_free_sectors; + /** * Create a single instance initialized with default values */ @@ -46,19 +54,69 @@ public final class BATBlock extends BigB { super(bigBlockSize); - int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); - - _data = new byte[ bigBlockSize.getBigBlockSize() ]; - Arrays.fill(_data, _default_value); - _fields = new IntegerField[ _entries_per_block ]; - int offset = 0; + int _entries_per_block = bigBlockSize.getBATEntriesPerBlock(); + _values = new int[_entries_per_block]; + _has_free_sectors = true; - for (int j = 0; j < _entries_per_block; j++) - { - _fields[ j ] = new IntegerField(offset); - offset += LittleEndianConsts.INT_SIZE; + Arrays.fill(_values, POIFSConstants.UNUSED_BLOCK); + } + + /** + * Create a single instance initialized (perhaps partially) with entries + * + * @param entries the array of block allocation table entries + * @param start_index the index of the first entry to be written + * to the block + * @param end_index the index, plus one, of the last entry to be + * written to the block (writing is for all index + * k, start_index <= k < end_index) + */ + + private BATBlock(POIFSBigBlockSize bigBlockSize, final int [] entries, + final int start_index, final int end_index) + { + this(bigBlockSize); + for (int k = start_index; k < end_index; k++) { + _values[k - start_index] = entries[k]; + } + + // Do we have any free sectors? + if(end_index - start_index == _values.length) { + recomputeFree(); } } + + private void recomputeFree() { + boolean hasFree = false; + for(int k=0; k<_values.length; k++) { + if(_values[k] == POIFSConstants.UNUSED_BLOCK) { + hasFree = true; + break; + } + } + _has_free_sectors = hasFree; + } + + /** + * Create a single BATBlock from the byte buffer, which must hold at least + * one big block of data to be read. + */ + public static BATBlock createBATBlock(final POIFSBigBlockSize bigBlockSize, ByteBuffer data) + { + // Create an empty block + BATBlock block = new BATBlock(bigBlockSize); + + // Fill it + byte[] buffer = new byte[LittleEndian.INT_SIZE]; + for(int i=0; i