123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You 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.property;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
-
- import org.apache.poi.poifs.common.POIFSBigBlockSize;
- import org.apache.poi.poifs.common.POIFSConstants;
- import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
- import org.apache.poi.poifs.filesystem.NPOIFSStream;
- import org.apache.poi.poifs.storage.HeaderBlock;
- import org.apache.poi.util.POILogFactory;
- import org.apache.poi.util.POILogger;
-
- /**
- * This class embodies the Property Table for a {@link NPOIFSFileSystem};
- * this is basically the directory for all of the documents in the
- * filesystem.
- */
- public final class NPropertyTable extends PropertyTableBase {
- private static final POILogger _logger =
- POILogFactory.getLogger(NPropertyTable.class);
- private POIFSBigBlockSize _bigBigBlockSize;
-
- public NPropertyTable(HeaderBlock headerBlock)
- {
- super(headerBlock);
- _bigBigBlockSize = headerBlock.getBigBlockSize();
- }
-
- /**
- * reading constructor (used when we've read in a file and we want
- * to extract the property table from it). Populates the
- * properties thoroughly
- *
- * @param headerBlock the header block of the file
- * @param filesystem the filesystem to read from
- *
- * @exception IOException if anything goes wrong (which should be
- * a result of the input being NFG)
- */
- public NPropertyTable(final HeaderBlock headerBlock,
- final NPOIFSFileSystem filesystem)
- throws IOException
- {
- super(
- headerBlock,
- buildProperties(
- (new NPOIFSStream(filesystem, headerBlock.getPropertyStart())).iterator(),
- headerBlock.getBigBlockSize()
- )
- );
- _bigBigBlockSize = headerBlock.getBigBlockSize();
- }
-
- /**
- * Builds
- * @param startAt
- * @param filesystem
- * @return
- * @throws IOException
- */
- private static List<Property> buildProperties(final Iterator<ByteBuffer> dataSource,
- final POIFSBigBlockSize bigBlockSize) throws IOException
- {
- List<Property> properties = new ArrayList<Property>();
- while(dataSource.hasNext()) {
- ByteBuffer bb = dataSource.next();
-
- // Turn it into an array
- byte[] data;
- if(bb.hasArray() && bb.arrayOffset() == 0 &&
- bb.array().length == bigBlockSize.getBigBlockSize()) {
- data = bb.array();
- } else {
- data = new byte[bigBlockSize.getBigBlockSize()];
-
- int toRead = data.length;
- if (bb.remaining() < bigBlockSize.getBigBlockSize()) {
- // Looks to be a truncated block
- // This isn't allowed, but some third party created files
- // sometimes do this, and we can normally read anyway
- _logger.log(POILogger.WARN, "Short Property Block, ", bb.remaining(),
- " bytes instead of the expected " + bigBlockSize.getBigBlockSize());
- toRead = bb.remaining();
- }
-
- bb.get(data, 0, toRead);
- }
-
- PropertyFactory.convertToProperties(data, properties);
- }
- return properties;
- }
-
- /**
- * Return the number of BigBlock's this instance uses
- *
- * @return count of BigBlock instances
- */
- public int countBlocks()
- {
- int size = _properties.size() * POIFSConstants.PROPERTY_SIZE;
- return (int)Math.ceil(size / _bigBigBlockSize.getBigBlockSize());
- }
-
- /**
- * Writes the properties out into the given low-level stream
- */
- public void write(NPOIFSStream stream) throws IOException {
- // TODO - Use a streaming write
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- for(Property property : _properties) {
- if(property != null) {
- property.writeData(baos);
- }
- }
- stream.updateContents(baos.toByteArray());
-
- // Update the start position if needed
- if(getStartBlock() != stream.getStartBlock()) {
- setStartBlock(stream.getStartBlock());
- }
- }
- }
|