/*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
*
Adds writing support to the {@link PropertySet} class.
* *Please be aware that this class' functionality will be merged into the * {@link PropertySet} class at a later time, so the API will change.
* * @author Rainer Klute <klute@rainer-klute.de> * @version $Id$ * @since 2003-02-19 */ public class MutablePropertySet extends PropertySet { /** *Constructs a MutablePropertySet
instance. Its
* primary task is to initialize the immutable field with their proper
* values. It also sets fields that might change to reasonable defaults.
The length of the property set stream header.
*/ private final int OFFSET_HEADER = BYTE_ORDER_ASSERTION.length + /* Byte order */ FORMAT_ASSERTION.length + /* Format */ LittleEndianConsts.INT_SIZE + /* OS version */ ClassID.LENGTH + /* Class ID */ LittleEndianConsts.INT_SIZE; /* Section count */ /** *Sets the "byteOrder" property.
* * @param byteOrder the byteOrder value to set */ public void setByteOrder(final int byteOrder) { this.byteOrder = byteOrder; } /** *Sets the "format" property.
* * @param format the format value to set */ public void setFormat(final int format) { this.format = format; } /** *Sets the "osVersion" property.
* * @param osVersion the osVersion value to set */ public void setOSVersion(final int osVersion) { this.osVersion = osVersion; } /** *Sets the property set stream's low-level "class ID" * field.
* * @param classID The property set stream's low-level "class ID" field. * * @see #getClassID */ public void setClassID(final ClassID classID) { this.classID = classID; } /** *Removes all sections from this property set.
*/ public void clearSections() { sections = null; } /** *Adds a section to this property set.
* * @param section The {@link Section} to add. It will be appended * after any sections that are already present in the property set * and thus become the last section. */ public void addSection(final Section section) { if (sections == null) sections = new LinkedList(); sections.add(section); } /** *Writes the property set to an output stream.
* * @param out the output stream to write the section to * @exception IOException if an error when writing to the output stream * occurs * @exception WritingNotSupportedException if HPSF does not yet support * writing a property's variant type. */ public void write(final OutputStream out) throws WritingNotSupportedException, IOException { /* Write the number of sections in this property set stream. */ final int nrSections = sections.size(); int length = 0; /* Write the property set's header. */ length += TypeWriter.writeToStream(out, (short) getByteOrder()); length += TypeWriter.writeToStream(out, (short) getFormat()); length += TypeWriter.writeToStream(out, (int) getOSVersion()); length += TypeWriter.writeToStream(out, getClassID()); length += TypeWriter.writeToStream(out, (int) nrSections); int offset = OFFSET_HEADER; /* Write the section list, i.e. the references to the sections. Each * entry in the section list consist of a class ID and the offset to the * section's begin. */ offset += nrSections * (ClassID.LENGTH + LittleEndian.INT_SIZE); final int sectionsBegin = offset; for (final ListIterator i = sections.listIterator(); i.hasNext();) { final MutableSection s = (MutableSection) i.next(); length += TypeWriter.writeToStream(out, s.getFormatID()); length += TypeWriter.writeUIntToStream(out, offset); offset += s.getSize(); } /* Write the sections themselves. */ offset = sectionsBegin; for (final ListIterator i = sections.listIterator(); i.hasNext();) { final MutableSection s = (MutableSection) i.next(); offset = s.write(out, offset); } } /** *Returns the contents of this property set stream as an input stream. * The latter can be used for example to write the property set into a POIFS * document. The input stream represents a snapshot of the property set. * If the latter is modified while the input stream is still being * read, the modifications will not be reflected in the input stream but in * the {@link MutablePropertySet} only.
* * @return the contents of this property set stream * * @throws WritingNotSupportedException if HPSF does not yet support writing * of a property's variant type. * @throws IOException if an I/O exception occurs. */ public InputStream toInputStream() throws IOException, WritingNotSupportedException { final ByteArrayOutputStream psStream = new ByteArrayOutputStream(); write(psStream); psStream.close(); final byte[] streamData = psStream.toByteArray(); return new ByteArrayInputStream(streamData); } }