You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HeaderBlockWriter.java 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.poifs.storage;
  16. import java.io.ByteArrayOutputStream;
  17. import java.io.IOException;
  18. import java.io.OutputStream;
  19. import java.nio.ByteBuffer;
  20. import org.apache.poi.poifs.common.POIFSBigBlockSize;
  21. import org.apache.poi.poifs.common.POIFSConstants;
  22. /**
  23. * The block containing the archive header
  24. *
  25. * @author Marc Johnson (mjohnson at apache dot org)
  26. */
  27. public class HeaderBlockWriter implements HeaderBlockConstants, BlockWritable
  28. {
  29. private final HeaderBlock _header_block;
  30. /**
  31. * Create a single instance initialized with default values
  32. */
  33. public HeaderBlockWriter(POIFSBigBlockSize bigBlockSize)
  34. {
  35. _header_block = new HeaderBlock(bigBlockSize);
  36. }
  37. /**
  38. * Create a single instance initialized with the specified
  39. * existing values
  40. */
  41. public HeaderBlockWriter(HeaderBlock headerBlock)
  42. {
  43. _header_block = headerBlock;
  44. }
  45. /**
  46. * Set BAT block parameters. Assumes that all BAT blocks are
  47. * contiguous. Will construct XBAT blocks if necessary and return
  48. * the array of newly constructed XBAT blocks.
  49. *
  50. * @param blockCount count of BAT blocks
  51. * @param startBlock index of first BAT block
  52. *
  53. * @return array of XBAT blocks; may be zero length, will not be
  54. * null
  55. */
  56. public BATBlock [] setBATBlocks(final int blockCount,
  57. final int startBlock)
  58. {
  59. BATBlock[] rvalue;
  60. POIFSBigBlockSize bigBlockSize = _header_block.getBigBlockSize();
  61. _header_block.setBATCount(blockCount);
  62. // Set the BAT locations
  63. int limit = Math.min(blockCount, _max_bats_in_header);
  64. int[] bat_blocks = new int[limit];
  65. for (int j = 0; j < limit; j++) {
  66. bat_blocks[j] = startBlock + j;
  67. }
  68. _header_block.setBATArray(bat_blocks);
  69. // Now do the XBATs
  70. if (blockCount > _max_bats_in_header)
  71. {
  72. int excess_blocks = blockCount - _max_bats_in_header;
  73. int[] excess_block_array = new int[ excess_blocks ];
  74. for (int j = 0; j < excess_blocks; j++)
  75. {
  76. excess_block_array[ j ] = startBlock + j
  77. + _max_bats_in_header;
  78. }
  79. rvalue = BATBlock.createXBATBlocks(bigBlockSize, excess_block_array,
  80. startBlock + blockCount);
  81. _header_block.setXBATStart(startBlock + blockCount);
  82. }
  83. else
  84. {
  85. rvalue = BATBlock.createXBATBlocks(bigBlockSize, new int[ 0 ], 0);
  86. _header_block.setXBATStart(POIFSConstants.END_OF_CHAIN);
  87. }
  88. _header_block.setXBATCount(rvalue.length);
  89. return rvalue;
  90. }
  91. /**
  92. * Set start of Property Table
  93. *
  94. * @param startBlock the index of the first block of the Property
  95. * Table
  96. */
  97. public void setPropertyStart(final int startBlock)
  98. {
  99. _header_block.setPropertyStart(startBlock);
  100. }
  101. /**
  102. * Set start of small block allocation table
  103. *
  104. * @param startBlock the index of the first big block of the small
  105. * block allocation table
  106. */
  107. public void setSBATStart(final int startBlock)
  108. {
  109. _header_block.setSBATStart(startBlock);
  110. }
  111. /**
  112. * Set count of SBAT blocks
  113. *
  114. * @param count the number of SBAT blocks
  115. */
  116. public void setSBATBlockCount(final int count)
  117. {
  118. _header_block.setSBATBlockCount(count);
  119. }
  120. /**
  121. * For a given number of BAT blocks, calculate how many XBAT
  122. * blocks will be needed
  123. *
  124. * @param blockCount number of BAT blocks
  125. *
  126. * @return number of XBAT blocks needed
  127. */
  128. static int calculateXBATStorageRequirements(POIFSBigBlockSize bigBlockSize, final int blockCount)
  129. {
  130. return (blockCount > _max_bats_in_header)
  131. ? BATBlock.calculateXBATStorageRequirements(
  132. bigBlockSize, blockCount - _max_bats_in_header)
  133. : 0;
  134. }
  135. /* ********** START extension of BigBlock ********** */
  136. /**
  137. * Write the block's data to an OutputStream
  138. *
  139. * @param stream the OutputStream to which the stored data should
  140. * be written
  141. *
  142. * @exception IOException on problems writing to the specified
  143. * stream
  144. */
  145. public void writeBlocks(final OutputStream stream)
  146. throws IOException
  147. {
  148. _header_block.writeData(stream);
  149. }
  150. /**
  151. * Write the block's data to an existing block
  152. *
  153. * @param block the ByteBuffer of the block to which the
  154. * stored data should be written
  155. *
  156. * @exception IOException on problems writing to the block
  157. */
  158. public void writeBlock(ByteBuffer block)
  159. throws IOException
  160. {
  161. ByteArrayOutputStream baos = new ByteArrayOutputStream(
  162. _header_block.getBigBlockSize().getBigBlockSize()
  163. );
  164. _header_block.writeData(baos);
  165. block.put(baos.toByteArray());
  166. }
  167. /* ********** END extension of BigBlock ********** */
  168. } // end public class HeaderBlockWriter