Java Code Examples for org.apache.poi.poifs.common.POIFSConstants#END_OF_CHAIN

The following examples show how to use org.apache.poi.poifs.common.POIFSConstants#END_OF_CHAIN . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: PropertyTable.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
public PropertyTable(final XlsInputStream is, HeaderBlock header, BlockStore blockStore) {
  this.is = is;
  this.sectorSize = header.getBigBlockSize().getBigBlockSize();


  // Directory sectors are stored as a chain starting from sector # header.propertyStart
  // and FAT table contains link to next sector in the chain

  int nextBlock = header.getPropertyStart(); // first sector in directory chain
  while (nextBlock != POIFSConstants.END_OF_CHAIN) {
    int blockOffset = blockStore.getBlockOffset(nextBlock);
    processSector(blockOffset);
    nextBlock = blockStore.getNextBlock(nextBlock); // get next block in the chain
  }

  populatePropertyTree((DirectoryProperty) properties.get(0));
}
 
Example 2
Source File: BlockStoreInputStream.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
BlockStoreInputStream(final XlsInputStream inputStream, final BlockStore blockStore, final int startBlock) {
  this.inputStream = Preconditions.checkNotNull(inputStream, "input stream should not be null");
  this.blockStore = Preconditions.checkNotNull(blockStore, "block store should not be null");
  nextBlock = startBlock;
  blockSize = blockStore.getBlockSize();

  Preconditions.checkState(startBlock != POIFSConstants.END_OF_CHAIN, "startBlock cannot be END_OF_CHAIN");

  // count number of blocks that are part of the stream chain, including current block!
  remainingBlocks = 0;
  int block = nextBlock;
  while (block != POIFSConstants.END_OF_CHAIN) {
    remainingBlocks++;
    block = blockStore.getNextBlock(block);
  }

  // move to the beginning of the first block in the chain
  inputStream.seek(blockStore.getBlockOffset(nextBlock));
}
 
Example 3
Source File: MiniStore.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public int getBlockOffset(int miniBlock) {
  // we want to read mini block with index = miniBlock

  // first we need to figure out which DIFAT block the mini block is in
  int byteOffset = miniBlock * POIFSConstants.SMALL_BLOCK_SIZE; // offset from beginning of SBAT
  int difatBlockNumber = byteOffset / difats.getBlockSize();
  int offsetInDifatBlock = byteOffset % difats.getBlockSize();

  // Now locate the data block for it, starting from the 1st block of the mini-FAT
  int nextBlock = root.getStartBlock(); // first sector in mini-FAT chain
  int idx = 0;
  while (nextBlock != POIFSConstants.END_OF_CHAIN && idx < difatBlockNumber) {
    nextBlock = difats.getNextBlock(nextBlock); // get next block in the chain
    idx++;
  }

  Preconditions.checkState(idx == difatBlockNumber, "DIFAT block " + difatBlockNumber + " outside stream chain");

  int difatBlockOffset = difats.getBlockOffset(nextBlock);

  return difatBlockOffset + offsetInDifatBlock;
}
 
Example 4
Source File: POIFSHeaderDumper.java    From lams with GNU General Public License v2.0 6 votes vote down vote up
public static void displayBATReader(String type, BlockAllocationTableReader batReader) throws Exception {
    System.out.println("Sectors, as referenced from the "+type+" FAT:");
    IntList entries = batReader.getEntries();

    for(int i=0; i<entries.size(); i++) {
        int bn = entries.get(i);
        String bnS = Integer.toString(bn);
        if(bn == POIFSConstants.END_OF_CHAIN) {
            bnS = "End Of Chain";
        } else if(bn == POIFSConstants.DIFAT_SECTOR_BLOCK) {
            bnS = "DI Fat Block";
        } else if(bn == POIFSConstants.FAT_SECTOR_BLOCK) {
            bnS = "Normal Fat Block";
        } else if(bn == POIFSConstants.UNUSED_BLOCK) {
            bnS = "Block Not Used (Free)";
        }

        System.out.println("  Block  # " + i + " -> " + bnS);
    }

    System.out.println("");
}
 
Example 5
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
protected void createBlockIfNeeded() throws IOException {
    if (buffer != null && buffer.hasRemaining()) return;
    
    int thisBlock = nextBlock;
    
    // Allocate a block if needed, otherwise figure
    //  out what the next block will be
    if(thisBlock == POIFSConstants.END_OF_CHAIN) {
       thisBlock = blockStore.getFreeBlock();
       loopDetector.claim(thisBlock);
       
       // We're on the end of the chain
       nextBlock = POIFSConstants.END_OF_CHAIN;
       
       // Mark the previous block as carrying on to us if needed
       if(prevBlock != POIFSConstants.END_OF_CHAIN) {
          blockStore.setNextBlock(prevBlock, thisBlock);
       }
       blockStore.setNextBlock(thisBlock, POIFSConstants.END_OF_CHAIN);
       
       // If we've just written the first block on a 
       //  new stream, save the start block offset
       if(startBlock == POIFSConstants.END_OF_CHAIN) {
          startBlock = thisBlock;
       }
    } else {
       loopDetector.claim(thisBlock);
       nextBlock = blockStore.getNextBlock(thisBlock);
    }

    buffer = blockStore.createBlockIfNeeded(thisBlock);
    
    // Update pointers
    prevBlock = thisBlock;
}
 
Example 6
Source File: MiniStore.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
public MiniStore(final XlsInputStream is, DirectoryProperty root, HeaderBlock header, BlockStore difats) {
  super(is, header, POIFSConstants.SMALL_BLOCK_SIZE);
  this.root = root;
  this.difats = difats;

  // load all mini-FAT blocks
  int nextAt = header.getSBATStart();
  for(int i = 0; i < header.getSBATCount() && nextAt != POIFSConstants.END_OF_CHAIN; i++) {
    BATBlock sfat = BATBlock.createBATBlock(header.getBigBlockSize(), difats.getBlockBuffer(nextAt));
    sfat.setOurBlockIndex(nextAt);
    blocks.add(sfat);
    nextAt = difats.getNextBlock(nextAt);
  }
}
 
Example 7
Source File: BlockAllocationTableWriter.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * create a BlockAllocationTableWriter
 */
public BlockAllocationTableWriter(POIFSBigBlockSize bigBlockSize)
{
   _bigBlockSize = bigBlockSize; 
    _start_block  = POIFSConstants.END_OF_CHAIN;
    _entries      = new IntList();
    _blocks       = new BATBlock[ 0 ];
}
 
Example 8
Source File: BlockAllocationTableReader.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * walk the entries from a specified point and return the
 * associated blocks. The associated blocks are removed from the
 * block list
 *
 * @param startBlock the first block in the chain
 * @param blockList the raw data block list
 *
 * @return array of ListManagedBlocks, in their correct order
 *
 * @exception IOException if there is a problem acquiring the blocks
 */
ListManagedBlock[] fetchBlocks(int startBlock, int headerPropertiesStartBlock,
        BlockList blockList) throws IOException {
    List<ListManagedBlock> blocks = new ArrayList<ListManagedBlock>();
    int  currentBlock = startBlock;
    boolean firstPass = true;
    ListManagedBlock dataBlock = null;

    // Process the chain from the start to the end
    // Normally we have header, data, end
    // Sometimes we have data, header, end
    // For those cases, stop at the header, not the end
    while (currentBlock != POIFSConstants.END_OF_CHAIN) {
        try {
            // Grab the data at the current block offset
            dataBlock = blockList.remove(currentBlock);
            blocks.add(dataBlock);
            // Now figure out which block we go to next
            currentBlock = _entries.get(currentBlock);
            firstPass = false;
        } catch(IOException e) {
            if(currentBlock == headerPropertiesStartBlock) {
                // Special case where things are in the wrong order
                _logger.log(POILogger.WARN, "Warning, header block comes after data blocks in POIFS block listing");
                currentBlock = POIFSConstants.END_OF_CHAIN;
            } else if(currentBlock == 0 && firstPass) {
                // Special case where the termination isn't done right
                //  on an empty set
                _logger.log(POILogger.WARN, "Warning, incorrectly terminated empty data blocks in POIFS block listing (should end at -2, ended at 0)");
                currentBlock = POIFSConstants.END_OF_CHAIN;
            } else {
                // Ripple up
                throw e;
            }
        }
    }

    return blocks.toArray(new ListManagedBlock[blocks.size()]);
}
 
Example 9
Source File: HeaderBlock.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Create a single instance initialized with default values
 */
public HeaderBlock(POIFSBigBlockSize bigBlockSize)
{
   this.bigBlockSize = bigBlockSize;

   // Our data is always 512 big no matter what
   _data = new byte[ POIFSConstants.SMALLER_BIG_BLOCK_SIZE ];
   Arrays.fill(_data, _default_value);
   
   // Set all the default values
   new LongField(_signature_offset, _signature, _data);
   new IntegerField(0x08, 0, _data);
   new IntegerField(0x0c, 0, _data);
   new IntegerField(0x10, 0, _data);
   new IntegerField(0x14, 0, _data);
   new ShortField(0x18, ( short ) 0x3b, _data);
   new ShortField(0x1a, ( short ) 0x3, _data);
   new ShortField(0x1c, ( short ) -2, _data);
    
   new ShortField(0x1e, bigBlockSize.getHeaderValue(), _data);
   new IntegerField(0x20, 0x6, _data);
   new IntegerField(0x24, 0, _data);
   new IntegerField(0x28, 0, _data);
   new IntegerField(0x34, 0, _data);
   new IntegerField(0x38, 0x1000, _data);
   
   // Initialize the variables
   _bat_count = 0;
   _sbat_count = 0;
   _xbat_count = 0;
   _property_start = POIFSConstants.END_OF_CHAIN;
   _sbat_start = POIFSConstants.END_OF_CHAIN;
   _xbat_start = POIFSConstants.END_OF_CHAIN;
}
 
Example 10
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public void close() throws IOException {
    // If we're overwriting, free any remaining blocks
    NPOIFSStream toFree = new NPOIFSStream(blockStore, nextBlock);
    toFree.free(loopDetector);
    
    // Mark the end of the stream, if we have any data
    if (prevBlock != POIFSConstants.END_OF_CHAIN) {
        blockStore.setNextBlock(prevBlock, POIFSConstants.END_OF_CHAIN);
    }
}
 
Example 11
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public ByteBuffer next() {
   if(nextBlock == POIFSConstants.END_OF_CHAIN) {
      throw new IndexOutOfBoundsException("Can't read past the end of the stream");
   }
   
   try {
      loopDetector.claim(nextBlock);
      ByteBuffer data = blockStore.getBlockAt(nextBlock);
      nextBlock = blockStore.getNextBlock(nextBlock);
      return data;
   } catch(IOException e) {
      throw new RuntimeException(e);
   }
}
 
Example 12
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private void free(ChainLoopDetector loopDetector) {
   int nextBlock = startBlock;
   while(nextBlock != POIFSConstants.END_OF_CHAIN) {
      int thisBlock = nextBlock;
      loopDetector.claim(thisBlock);
      nextBlock = blockStore.getNextBlock(thisBlock);
      blockStore.setNextBlock(thisBlock, POIFSConstants.UNUSED_BLOCK);
   }
   this.startBlock = POIFSConstants.END_OF_CHAIN;
}
 
Example 13
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
public Iterator<ByteBuffer> getBlockIterator() {
   if(startBlock == POIFSConstants.END_OF_CHAIN) {
      throw new IllegalStateException(
            "Can't read from a new stream before it has been written to"
      );
   }
   return new StreamBlockByteBufferIterator(startBlock);
}
 
Example 14
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
protected StreamBlockByteBuffer() throws IOException {
    loopDetector = blockStore.getChainLoopDetector();
    prevBlock = POIFSConstants.END_OF_CHAIN;
    nextBlock = startBlock;
}
 
Example 15
Source File: BlockAllocationTableReader.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * create a BlockAllocationTableReader for an existing filesystem. Side
 * effect: when this method finishes, the BAT blocks will have
 * been removed from the raw block list, and any blocks labeled as
 * 'unused' in the block allocation table will also have been
 * removed from the raw block list.
 *
 * @param block_count the number of BAT blocks making up the block
 *                    allocation table
 * @param block_array the array of BAT block indices from the
 *                    filesystem's header
 * @param xbat_count the number of XBAT blocks
 * @param xbat_index the index of the first XBAT block
 * @param raw_block_list the list of RawDataBlocks
 *
 * @exception IOException if, in trying to create the table, we
 *            encounter logic errors
 */
public BlockAllocationTableReader(POIFSBigBlockSize bigBlockSize, int block_count, int [] block_array,
        int xbat_count, int xbat_index, BlockList raw_block_list) throws IOException {
    this(bigBlockSize);
    
    sanityCheckBlockCount(block_count);

    // We want to get the whole of the FAT table
    // To do this:
    //  * Work through raw_block_list, which points to the 
    //     first (up to) 109 BAT blocks
    //  * Jump to the XBAT offset, and read in XBATs which
    //     point to more BAT blocks
    int          limit    = Math.min(block_count, block_array.length);
    int          block_index;
    
    // This will hold all of the BAT blocks in order
    RawDataBlock blocks[] = new RawDataBlock[ block_count ];

    // Process the first (up to) 109 BAT blocks
    for (block_index = 0; block_index < limit; block_index++)
    {
        // Check that the sector number of the BAT block is a valid one
        int nextOffset = block_array[ block_index ];
        if(nextOffset > raw_block_list.blockCount()) {
           throw new IOException("Your file contains " + raw_block_list.blockCount() + 
                 " sectors, but the initial DIFAT array at index " + block_index +
                 " referenced block # " + nextOffset + ". This isn't allowed and " +
                 " your file is corrupt");
        }
        // Record the sector number of this BAT block 
        blocks[ block_index ] =
            ( RawDataBlock ) raw_block_list.remove(nextOffset);
    }
    
    // Process additional BAT blocks via the XBATs
    if (block_index < block_count)
    {

        // must have extended blocks
        if (xbat_index < 0)
        {
            throw new IOException(
                "BAT count exceeds limit, yet XBAT index indicates no valid entries");
        }
        int chain_index           = xbat_index;
        int max_entries_per_block = bigBlockSize.getXBATEntriesPerBlock(); 
        int chain_index_offset    = bigBlockSize.getNextXBATChainOffset(); 

        // Each XBAT block contains either:
        //  (maximum number of sector indexes) + index of next XBAT
        //  some sector indexes + FREE sectors to max # + EndOfChain
        for (int j = 0; j < xbat_count; j++)
        {
            limit = Math.min(block_count - block_index,
                             max_entries_per_block);
            byte[] data   = raw_block_list.remove(chain_index).getData();
            int    offset = 0;

            for (int k = 0; k < limit; k++)
            {
                blocks[ block_index++ ] =
                    ( RawDataBlock ) raw_block_list
                        .remove(LittleEndian.getInt(data, offset));
                offset                  += LittleEndianConsts.INT_SIZE;
            }
            chain_index = LittleEndian.getInt(data, chain_index_offset);
            if (chain_index == POIFSConstants.END_OF_CHAIN)
            {
                break;
            }
        }
    }
    if (block_index != block_count)
    {
        throw new IOException("Could not find all blocks");
    }

    // Now that we have all of the raw data blocks which make
    //  up the FAT, go through and create the indices
    setEntries(blocks, raw_block_list);
}
 
Example 16
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
public boolean hasNext() {
   if(nextBlock == POIFSConstants.END_OF_CHAIN) {
      return false;
   }
   return true;
}
 
Example 17
Source File: NPOIFSStream.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Constructor for a new stream. A start block won't
 *  be allocated until you begin writing to it.
 */
public NPOIFSStream(BlockStore blockStore) {
     this.blockStore = blockStore;
   this.startBlock = POIFSConstants.END_OF_CHAIN;
}
 
Example 18
Source File: NPOIFSMiniStore.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Finds a free block, and returns its offset.
 * This method will extend the file if needed, and if doing
 *  so, allocate new FAT blocks to address the extra space.
 */
protected int getFreeBlock() throws IOException {
   int sectorsPerSBAT = _filesystem.getBigBlockSizeDetails().getBATEntriesPerBlock();
   
   // First up, do we have any spare ones?
   int offset = 0;
   for(int i=0; i<_sbat_blocks.size(); i++) {
      // Check this one
      BATBlock sbat = _sbat_blocks.get(i);
      if(sbat.hasFreeSectors()) {
         // Claim one of them and return it
         for(int j=0; j<sectorsPerSBAT; j++) {
            int sbatValue = sbat.getValueAt(j);
            if(sbatValue == POIFSConstants.UNUSED_BLOCK) {
               // Bingo
               return offset + j;
            }
         }
      }
      
      // Move onto the next SBAT
      offset += sectorsPerSBAT;
   }
   
   // If we get here, then there aren't any
   //  free sectors in any of the SBATs
   // So, we need to extend the chain and add another
   
   // Create a new BATBlock
   BATBlock newSBAT = BATBlock.createEmptyBATBlock(_filesystem.getBigBlockSizeDetails(), false);
   int batForSBAT = _filesystem.getFreeBlock();
   newSBAT.setOurBlockIndex(batForSBAT);
   
   // Are we the first SBAT?
   if(_header.getSBATCount() == 0) {
      // Tell the header that we've got our first SBAT there
      _header.setSBATStart(batForSBAT);
      _header.setSBATBlockCount(1);
   } else {
      // Find the end of the SBAT stream, and add the sbat in there
      ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
      int batOffset = _header.getSBATStart();
      while(true) {
         loopDetector.claim(batOffset);
         int nextBat = _filesystem.getNextBlock(batOffset);
         if(nextBat == POIFSConstants.END_OF_CHAIN) {
            break;
         }
         batOffset = nextBat;
      }
      
      // Add it in at the end
      _filesystem.setNextBlock(batOffset, batForSBAT);
      
      // And update the count
      _header.setSBATBlockCount(
            _header.getSBATCount() + 1
      );
   }
   
   // Finish allocating
   _filesystem.setNextBlock(batForSBAT, POIFSConstants.END_OF_CHAIN);
   _sbat_blocks.add(newSBAT);
   
   // Return our first spot
   return offset;
}
 
Example 19
Source File: NPOIFSMiniStore.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Load the block, extending the underlying stream if needed
 */
protected ByteBuffer createBlockIfNeeded(final int offset) throws IOException {
   boolean firstInStore = false;
   if (_mini_stream.getStartBlock() == POIFSConstants.END_OF_CHAIN) {
       firstInStore = true;
   }
   
   // Try to get it without extending the stream
   if (! firstInStore) {
       try {
          return getBlockAt(offset);
       } catch(IndexOutOfBoundsException e) {}
   }
   
   // Need to extend the stream
   // TODO Replace this with proper append support
   // For now, do the extending by hand...

   // Ask for another block
   int newBigBlock = _filesystem.getFreeBlock();
   _filesystem.createBlockIfNeeded(newBigBlock);
   
   // If we are the first block to be allocated, initialise the stream
   if (firstInStore) {
       _filesystem._get_property_table().getRoot().setStartBlock(newBigBlock);
       _mini_stream = new NPOIFSStream(_filesystem, newBigBlock);
   } else {
       // Tack it onto the end of our chain
       ChainLoopDetector loopDetector = _filesystem.getChainLoopDetector();
       int block = _mini_stream.getStartBlock();
       while(true) {
          loopDetector.claim(block);
          int next = _filesystem.getNextBlock(block);
          if(next == POIFSConstants.END_OF_CHAIN) {
             break;
          }
          block = next;
       }
       _filesystem.setNextBlock(block, newBigBlock);
   }
   
   // This is now the new end
   _filesystem.setNextBlock(newBigBlock, POIFSConstants.END_OF_CHAIN);

   // Now try again, to get the real small block
   return createBlockIfNeeded(offset);
}