All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.poi.poifs.storage.BlockAllocationTableWriter Maven / Gradle / Ivy

There is a newer version: 3.1-FINAL
Show newest version

/* ====================================================================
   Copyright 2002-2004   Apache Software Foundation

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
        

package org.apache.poi.poifs.storage;

import java.io.IOException;
import java.io.OutputStream;

import java.util.*;

import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.filesystem.BATManaged;
import org.apache.poi.util.IntList;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;

/**
 * This class manages and creates the Block Allocation Table, which is
 * basically a set of linked lists of block indices.
 * 

* Each block of the filesystem has an index. The first block, the * header, is skipped; the first block after the header is index 0, * the next is index 1, and so on. *

* A block's index is also its index into the Block Allocation * Table. The entry that it finds in the Block Allocation Table is the * index of the next block in the linked list of blocks making up a * file, or it is set to -2: end of list. * * @author Marc Johnson (mjohnson at apache dot org) */ public class BlockAllocationTableWriter implements BlockWritable, BATManaged { private IntList _entries; private BATBlock[] _blocks; private int _start_block; /** * create a BlockAllocationTableWriter */ public BlockAllocationTableWriter() { _start_block = POIFSConstants.END_OF_CHAIN; _entries = new IntList(); _blocks = new BATBlock[ 0 ]; } /** * Create the BATBlocks we need * * @return start block index of BAT blocks */ public int createBlocks() { int xbat_blocks = 0; int bat_blocks = 0; while (true) { int calculated_bat_blocks = BATBlock.calculateStorageRequirements(bat_blocks + xbat_blocks + _entries.size()); int calculated_xbat_blocks = HeaderBlockWriter .calculateXBATStorageRequirements(calculated_bat_blocks); if ((bat_blocks == calculated_bat_blocks) && (xbat_blocks == calculated_xbat_blocks)) { // stable ... we're OK break; } else { bat_blocks = calculated_bat_blocks; xbat_blocks = calculated_xbat_blocks; } } int startBlock = allocateSpace(bat_blocks); allocateSpace(xbat_blocks); simpleCreateBlocks(); return startBlock; } /** * Allocate space for a block of indices * * @param blockCount the number of blocks to allocate space for * * @return the starting index of the blocks */ public int allocateSpace(final int blockCount) { int startBlock = _entries.size(); if (blockCount > 0) { int limit = blockCount - 1; int index = startBlock + 1; for (int k = 0; k < limit; k++) { _entries.add(index++); } _entries.add(POIFSConstants.END_OF_CHAIN); } return startBlock; } /** * get the starting block * * @return the starting block index */ public int getStartBlock() { return _start_block; } /** * create the BATBlocks */ void simpleCreateBlocks() { _blocks = BATBlock.createBATBlocks(_entries.toArray()); } /* ********** START implementation of BlockWritable ********** */ /** * Write the storage to an OutputStream * * @param stream the OutputStream to which the stored data should * be written * * @exception IOException on problems writing to the specified * stream */ public void writeBlocks(final OutputStream stream) throws IOException { for (int j = 0; j < _blocks.length; j++) { _blocks[ j ].writeBlocks(stream); } } /* ********** END implementation of BlockWritable ********** */ /* ********** START implementation of BATManaged ********** */ /** * Return the number of BigBlock's this instance uses * * @return count of BigBlock instances */ public int countBlocks() { return _blocks.length; } /** * Set the start block for this instance * * @param index index into the array of BigBlock instances making * up the the filesystem * * @param start_block */ public void setStartBlock(int start_block) { _start_block = start_block; } /* ********** END implementation of BATManaged ********** */ } // end class BlockAllocationTableWriter





© 2015 - 2024 Weber Informatics LLC | Privacy Policy