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.

NPropertyTable.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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.property;
  16. import java.io.ByteArrayOutputStream;
  17. import java.io.IOException;
  18. import java.nio.ByteBuffer;
  19. import java.util.ArrayList;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import org.apache.poi.poifs.common.POIFSBigBlockSize;
  23. import org.apache.poi.poifs.common.POIFSConstants;
  24. import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
  25. import org.apache.poi.poifs.filesystem.NPOIFSStream;
  26. import org.apache.poi.poifs.storage.HeaderBlock;
  27. import org.apache.poi.util.POILogFactory;
  28. import org.apache.poi.util.POILogger;
  29. /**
  30. * This class embodies the Property Table for a {@link NPOIFSFileSystem};
  31. * this is basically the directory for all of the documents in the
  32. * filesystem.
  33. */
  34. public final class NPropertyTable extends PropertyTableBase {
  35. private static final POILogger _logger =
  36. POILogFactory.getLogger(NPropertyTable.class);
  37. private POIFSBigBlockSize _bigBigBlockSize;
  38. public NPropertyTable(HeaderBlock headerBlock)
  39. {
  40. super(headerBlock);
  41. _bigBigBlockSize = headerBlock.getBigBlockSize();
  42. }
  43. /**
  44. * reading constructor (used when we've read in a file and we want
  45. * to extract the property table from it). Populates the
  46. * properties thoroughly
  47. *
  48. * @param headerBlock the header block of the file
  49. * @param filesystem the filesystem to read from
  50. *
  51. * @exception IOException if anything goes wrong (which should be
  52. * a result of the input being NFG)
  53. */
  54. public NPropertyTable(final HeaderBlock headerBlock,
  55. final NPOIFSFileSystem filesystem)
  56. throws IOException
  57. {
  58. super(
  59. headerBlock,
  60. buildProperties(
  61. (new NPOIFSStream(filesystem, headerBlock.getPropertyStart())).iterator(),
  62. headerBlock.getBigBlockSize()
  63. )
  64. );
  65. _bigBigBlockSize = headerBlock.getBigBlockSize();
  66. }
  67. /**
  68. * Builds
  69. * @param startAt
  70. * @param filesystem
  71. * @return
  72. * @throws IOException
  73. */
  74. private static List<Property> buildProperties(final Iterator<ByteBuffer> dataSource,
  75. final POIFSBigBlockSize bigBlockSize) throws IOException
  76. {
  77. List<Property> properties = new ArrayList<Property>();
  78. while(dataSource.hasNext()) {
  79. ByteBuffer bb = dataSource.next();
  80. // Turn it into an array
  81. byte[] data;
  82. if(bb.hasArray() && bb.arrayOffset() == 0 &&
  83. bb.array().length == bigBlockSize.getBigBlockSize()) {
  84. data = bb.array();
  85. } else {
  86. data = new byte[bigBlockSize.getBigBlockSize()];
  87. int toRead = data.length;
  88. if (bb.remaining() < bigBlockSize.getBigBlockSize()) {
  89. // Looks to be a truncated block
  90. // This isn't allowed, but some third party created files
  91. // sometimes do this, and we can normally read anyway
  92. _logger.log(POILogger.WARN, "Short Property Block, ", bb.remaining(),
  93. " bytes instead of the expected " + bigBlockSize.getBigBlockSize());
  94. toRead = bb.remaining();
  95. }
  96. bb.get(data, 0, toRead);
  97. }
  98. PropertyFactory.convertToProperties(data, properties);
  99. }
  100. return properties;
  101. }
  102. /**
  103. * Return the number of BigBlock's this instance uses
  104. *
  105. * @return count of BigBlock instances
  106. */
  107. public int countBlocks()
  108. {
  109. int size = _properties.size() * POIFSConstants.PROPERTY_SIZE;
  110. return (int)Math.ceil(size / _bigBigBlockSize.getBigBlockSize());
  111. }
  112. /**
  113. * Writes the properties out into the given low-level stream
  114. */
  115. public void write(NPOIFSStream stream) throws IOException {
  116. // TODO - Use a streaming write
  117. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  118. for(Property property : _properties) {
  119. if(property != null) {
  120. property.writeData(baos);
  121. }
  122. }
  123. stream.updateContents(baos.toByteArray());
  124. // Update the start position if needed
  125. if(getStartBlock() != stream.getStartBlock()) {
  126. setStartBlock(stream.getStartBlock());
  127. }
  128. }
  129. }