
/* ====================================================================
 * 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);
    }
}
