blob: 2e9fd02822e0b6272635a087b2f3ee7aa5b359aa [file] [log] [blame]
/* ====================================================================
* 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" and
* "Apache POI" 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",
* "Apache POI", 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
* <http://www.apache.org/>.
*/
package org.apache.poi.poifs.filesystem;
import java.io.*;
import java.util.*;
import junit.framework.*;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.poifs.property.DocumentProperty;
import org.apache.poi.poifs.storage.RawDataBlock;
import org.apache.poi.poifs.storage.SmallDocumentBlock;
/**
* Class to test POIFSDocument functionality
*
* @author Marc Johnson
*/
public class TestDocument
extends TestCase
{
/**
* Constructor TestDocument
*
* @param name
*/
public TestDocument(String name)
{
super(name);
}
/**
* Integration test -- really about all we can do
*
* @exception IOException
*/
public void testPOIFSDocument()
throws IOException
{
// verify correct number of blocks get created for document
// that is exact multituple of block size
POIFSDocument document;
byte[] array = new byte[ 4096 ];
for (int j = 0; j < array.length; j++)
{
array[ j ] = ( byte ) j;
}
document = new POIFSDocument("foo", new SlowInputStream(new ByteArrayInputStream(array)));
checkDocument(document, array);
// verify correct number of blocks get created for document
// that is not an exact multiple of block size
array = new byte[ 4097 ];
for (int j = 0; j < array.length; j++)
{
array[ j ] = ( byte ) j;
}
document = new POIFSDocument("bar", new ByteArrayInputStream(array));
checkDocument(document, array);
// verify correct number of blocks get created for document
// that is small
array = new byte[ 4095 ];
for (int j = 0; j < array.length; j++)
{
array[ j ] = ( byte ) j;
}
document = new POIFSDocument("_bar", new ByteArrayInputStream(array));
checkDocument(document, array);
// verify correct number of blocks get created for document
// that is rather small
array = new byte[ 199 ];
for (int j = 0; j < array.length; j++)
{
array[ j ] = ( byte ) j;
}
document = new POIFSDocument("_bar2",
new ByteArrayInputStream(array));
checkDocument(document, array);
// verify that output is correct
array = new byte[ 4097 ];
for (int j = 0; j < array.length; j++)
{
array[ j ] = ( byte ) j;
}
document = new POIFSDocument("foobar",
new ByteArrayInputStream(array));
checkDocument(document, array);
document.setStartBlock(0x12345678); // what a big file!!
DocumentProperty property = document.getDocumentProperty();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
property.writeData(stream);
byte[] output = stream.toByteArray();
byte[] array2 =
{
( byte ) 'f', ( byte ) 0, ( byte ) 'o', ( byte ) 0, ( byte ) 'o',
( byte ) 0, ( byte ) 'b', ( byte ) 0, ( byte ) 'a', ( byte ) 0,
( byte ) 'r', ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 14,
( byte ) 0, ( byte ) 2, ( byte ) 1, ( byte ) -1, ( byte ) -1,
( byte ) -1, ( byte ) -1, ( byte ) -1, ( byte ) -1, ( byte ) -1,
( byte ) -1, ( byte ) -1, ( byte ) -1, ( byte ) -1, ( byte ) -1,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0x78, ( byte ) 0x56, ( byte ) 0x34,
( byte ) 0x12, ( byte ) 1, ( byte ) 16, ( byte ) 0, ( byte ) 0,
( byte ) 0, ( byte ) 0, ( byte ) 0, ( byte ) 0
};
assertEquals(array2.length, output.length);
for (int j = 0; j < output.length; j++)
{
assertEquals("Checking property offset " + j, array2[ j ],
output[ j ]);
}
}
private POIFSDocument makeCopy(POIFSDocument document, byte [] input,
byte [] data)
throws IOException
{
POIFSDocument copy = null;
if (input.length >= 4096)
{
RawDataBlock[] blocks =
new RawDataBlock[ (input.length + 511) / 512 ];
ByteArrayInputStream stream = new ByteArrayInputStream(data);
int index = 0;
while (true)
{
RawDataBlock block = new RawDataBlock(stream);
if (block.eof())
{
break;
}
blocks[ index++ ] = block;
}
copy = new POIFSDocument("test" + input.length, blocks,
input.length);
}
else
{
copy = new POIFSDocument(
"test" + input.length,
( SmallDocumentBlock [] ) document.getSmallBlocks(),
input.length);
}
return copy;
}
private void checkDocument(final POIFSDocument document,
final byte [] input)
throws IOException
{
int big_blocks = 0;
int small_blocks = 0;
int total_output = 0;
if (input.length >= 4096)
{
big_blocks = (input.length + 511) / 512;
total_output = big_blocks * 512;
}
else
{
small_blocks = (input.length + 63) / 64;
total_output = 0;
}
checkValues(
big_blocks, small_blocks, total_output,
makeCopy(
document, input,
checkValues(
big_blocks, small_blocks, total_output, document,
input)), input);
}
private byte [] checkValues(int big_blocks, int small_blocks,
int total_output, POIFSDocument document,
byte [] input)
throws IOException
{
assertEquals(document, document.getDocumentProperty().getDocument());
int increment = ( int ) Math.sqrt(input.length);
for (int j = 1; j <= input.length; j += increment)
{
byte[] buffer = new byte[ j ];
int offset = 0;
for (int k = 0; k < (input.length / j); k++)
{
document.read(buffer, offset);
for (int n = 0; n < buffer.length; n++)
{
assertEquals("checking byte " + (k * j) + n,
input[ (k * j) + n ], buffer[ n ]);
}
offset += j;
}
}
assertEquals(big_blocks, document.countBlocks());
assertEquals(small_blocks, document.getSmallBlocks().length);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
document.writeBlocks(stream);
byte[] output = stream.toByteArray();
assertEquals(total_output, output.length);
int limit = Math.min(total_output, input.length);
for (int j = 0; j < limit; j++)
{
assertEquals("Checking document offset " + j, input[ j ],
output[ j ]);
}
for (int j = limit; j < output.length; j++)
{
assertEquals("Checking document offset " + j, ( byte ) -1,
output[ j ]);
}
return output;
}
/**
* main method to run the unit tests
*
* @param ignored_args
*/
public static void main(String [] ignored_args)
{
System.out
.println("Testing org.apache.poi.poifs.filesystem.POIFSDocument");
junit.textui.TestRunner.run(TestDocument.class);
}
}