/*******************************************************************************
 * Copyright (c) 2004, 2005 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.data.engine.olap.data.util;

import java.io.IOException;

/**
 * A List class providing the service of reading/writing objects from one file
 * when cache is not enough . It makes the reading/writing objects transparent.
 */

public class StructureDiskArray extends BaseDiskArray
{

	private IStructureCreator creator;
	private ObjectWriter[] fieldWriters;
	private ObjectReader[] fieldReaders;

	/**
	 * @throws IOException 
	 * 
	 * 
	 */
	public StructureDiskArray( IStructureCreator creator ) throws IOException
	{
		super( );
		this.creator = creator;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.data.engine.cache.BasicCachedList#writeObject(java.io.DataOutputStream,
	 *      java.lang.Object)
	 */
	protected void writeObject( Object object ) throws IOException
	{
		if ( object == null )
		{
			randomAccessFile.writeShort( NULL_VALUE );
			return;
		}
		IStructure cachedObject = (IStructure) object;
		Object[] objects = cachedObject.getFieldValues( );
		randomAccessFile.writeShort( (short) objects.length );
		if ( fieldWriters == null || fieldWriters.length < objects.length )
		{
			createReadersAndWriters( objects.length );
		}
		for ( int i = 0; i < objects.length; i++ )
		{
			if( i >= fieldWriters.length )
			{
				fieldWriters[fieldWriters.length-1].write( randomAccessFile, objects[i] );
			}
			else
			{
				fieldWriters[i].write( randomAccessFile, objects[i] );
			}
		}
	}

	/**
	 * 
	 * @param size
	 */
	private void createReadersAndWriters( int size )
	{
		fieldWriters = new ObjectWriter[size];
		fieldReaders = new ObjectReader[size];
		for ( int i = 0; i < size; i++ )
		{
			fieldWriters[i] = new ObjectWriter( );
			fieldReaders[i] = new ObjectReader( );
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.birt.data.engine.cache.BasicCachedList#readObject(java.io.DataInputStream)
	 */
	protected Object readObject( ) throws IOException
	{
		short fieldCount = randomAccessFile.readShort( );
		if ( fieldCount == NULL_VALUE )
		{
			return null;
		}
		Object[] objects = new Object[fieldCount];
		for ( int i = 0; i < objects.length; i++ )
		{
			if ( i < fieldReaders.length && fieldReaders[i].getDataType( ) != fieldWriters[i].getDataType( ) )
				fieldReaders[i].setDataType( fieldWriters[i].getDataType( ) );
			if( i >= fieldReaders.length )
			{
				objects[i] = fieldReaders[fieldReaders.length-1].read( randomAccessFile );
			}
			else
			{
				objects[i] = fieldReaders[i].read( randomAccessFile );
			}
		}
		return creator.createInstance( objects );
	}
	
	public void clear( ) throws IOException
	{
		fieldWriters = null;
		fieldReaders = null;
		super.clear();
	}

}
@@ -611,16 +611,41 @@
 ception;
+%0Aimport java.util.Arrays;
 %0A%0A/**%0A *
@@ -2074,24 +2074,83 @@
 t size )%0A%09%7B%0A
+%09%09if ( fieldWriters == null && fieldReaders == null )%0A%09%09%7B%0A%09
 %09%09fieldWrite
@@ -2178,16 +2178,17 @@
 %5Bsize%5D;%0A
+%09
 %09%09fieldR
@@ -2220,16 +2220,17 @@
 %5Bsize%5D;%0A
+%09
 %09%09for ( 
@@ -2254,26 +2254,28 @@
 ze; i++ )%0A%09%09
+%09
 %7B%0A
+%09
 %09%09%09fieldWrit
@@ -2304,16 +2304,17 @@
 ter( );%0A
+%09
 %09%09%09field
@@ -2343,24 +2343,324 @@
 tReader( );%0A
+%09%09%09%7D%0A%09%09%7D%0A%09%09else%0A%09%09%7B%0A%09%09%09int i = fieldWriters.length;%0A%09%09%09fieldReaders = Arrays.copyOf( fieldReaders, size );%0A%09%09%09fieldWriters = Arrays.copyOf( fieldWriters, size );%0A%09%09%09for ( ; i %3C fieldReaders.length; i++ )%0A%09%09%09%7B%0A%09%09%09%09fieldWriters%5Bi%5D = new ObjectWriter( );%0A%09%09%09%09fieldReaders%5Bi%5D = new ObjectReader( );%0A%09%09%09%7D%0A
 %09%09%7D%0A%09%7D%0A%09%0A%09/*

Fix NPE of reading objects from StructureDiskArray while number of fields enlarged.[41945]