/**************************************************************
 * 
 * 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 complex.storages;

import com.sun.star.uno.XInterface;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;

import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

import com.sun.star.io.XStream;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.io.XTruncate;
import com.sun.star.io.XSeekable;


public class BorderedStream
	implements XStream, XInputStream, XOutputStream, XTruncate, XSeekable
{
	int m_nMaxSize;
	int m_nCurSize;
	int m_nCurPos;
	byte m_pBytes[];

	public BorderedStream( int nMaxSize )
	{
		m_nMaxSize = nMaxSize;
		m_nCurSize = 0;
		m_nCurPos = 0;
		m_pBytes = new byte[m_nMaxSize];
	}

	//==============
	// XStream
	//==============

	// ----------------------------------------------------------
	public synchronized XInputStream getInputStream()
		throws com.sun.star.uno.RuntimeException
	{
		return (XInputStream)UnoRuntime.queryInterface( XInputStream.class, this );
	}
	
	// ----------------------------------------------------------
	public synchronized XOutputStream getOutputStream()
		throws com.sun.star.uno.RuntimeException
	{
		return (XOutputStream)UnoRuntime.queryInterface( XOutputStream.class, this );
	}

	//==============
	// XInputStream
	//==============

	// ----------------------------------------------------------
	public synchronized int readBytes( byte[][] aData, int nBytesToRead )
    	throws  com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		int nRead = 0;
		if ( m_pBytes != null && nBytesToRead > 0 )
		{
			int nAvailable = m_nCurSize - m_nCurPos;
			if ( nBytesToRead > nAvailable )
				nBytesToRead = nAvailable;

			aData[0] = new byte[nBytesToRead];
			for ( int nInd = 0; nInd < nBytesToRead; nInd++ )
				aData[0][nInd] = m_pBytes[m_nCurPos+nInd];

			nRead = nBytesToRead;
			m_nCurPos += nRead;
		}
		else
		{
			aData[0] = new byte[0];
		}
		
		return nRead;
	}

    // ----------------------------------------------------------
	public synchronized int readSomeBytes( byte[][] aData, int nMaxBytesToRead )
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		return readBytes( aData, nMaxBytesToRead );
	}

    // ----------------------------------------------------------
	public synchronized void skipBytes( int nBytesToSkip  )
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		if ( nBytesToSkip < 0 )
			throw new com.sun.star.io.IOException(); // illegal argument

		if ( m_nCurSize - m_nCurPos > nBytesToSkip )
			m_nCurPos += nBytesToSkip;
		else
			m_nCurPos = m_nCurSize;
	}

    // ----------------------------------------------------------
	public synchronized int available()
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		return 0;
	}

    // ----------------------------------------------------------
	public synchronized void closeInput()
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		// no need to do anything
	}


	//==============
	// XOutputStream
	//==============

    // ----------------------------------------------------------
	public synchronized void writeBytes( byte[] aData  )
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		if ( m_pBytes != null && aData.length > 0 )
		{
			if ( aData.length > m_nMaxSize - m_nCurPos )
				throw new com.sun.star.io.IOException();

			for ( int nInd = 0; nInd < aData.length; nInd++ )
				m_pBytes[m_nCurPos+nInd] = aData[nInd];

			m_nCurPos += aData.length;
			if ( m_nCurPos > m_nCurSize )
				m_nCurSize = m_nCurPos;
		}
	}

    // ----------------------------------------------------------
	public synchronized void flush()
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		// nothing to do
	}

    // ----------------------------------------------------------
	public synchronized void closeOutput()
		throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		// nothing to do
	}


	//==============
	// XTruncate
	//==============

    // ----------------------------------------------------------
	public synchronized void truncate()
		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		m_nCurSize = 0;
		m_nCurPos = 0;
	}


	//==============
	// XSeekable
	//==============

    // ----------------------------------------------------------
	public synchronized void seek( long location )
		throws com.sun.star.lang.IllegalArgumentException, com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		if ( location > (long)m_nCurSize )
			throw new com.sun.star.lang.IllegalArgumentException();

		m_nCurPos = (int)location;
	}

    // ----------------------------------------------------------
	public synchronized long getPosition()
		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		return (long)m_nCurPos;
	}

    // ----------------------------------------------------------
	public synchronized long getLength()
		throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException
	{
		return (long)m_nCurSize;
	}
};

