All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.birt.core.archive.RAFolderInputStream Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2004,2009 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.core.archive;

import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashSet;

import org.eclipse.birt.core.util.IOUtil;

/**
 * RAInputStream implementation for folder based report archive  
 */
public class RAFolderInputStream extends RAInputStream
{

	private HashSet manager;
	private String name;
	private RandomAccessFile randomFile;
	private byte buf[];
	private int bufLen;  // total bytes in the buffer 
	private int bufCur;  // the pointer in the buffer

	public RAFolderInputStream( File file ) throws IOException
	{
		this( null, file );
	}

	/**
	 * @param file
	 *            - a regular file (i.e. stream) in the folder
	 * @throws FileNotFoundException
	 */
	public RAFolderInputStream( HashSet manager, File file )
			throws IOException
	{
		this.manager = manager;
		this.name = file.getCanonicalPath( );
		this.randomFile = new RandomAccessFile( file, "r" ); //$NON-NLS-1$
		this.buf = new byte[IOUtil.RA_STREAM_BUFFER_LENGTH];
		this.bufLen = 0;
		this.bufCur = 0;
		if ( this.manager != null )
		{
			synchronized ( manager )
			{
				manager.add( this );
			}
		}
	}

	public String getName( )
	{
		return this.name;
	}

	public void refresh( ) throws IOException
	{
		bufLen = 0;
		bufCur = 0;
	}
	
	private void readToBuffer() throws IOException
	{
		bufLen = 0;
		bufCur = 0;
		long availableSize = randomFile.length() - randomFile.getFilePointer();
		if ( availableSize <= 0 )
			return;
		int len = (int) Math.min( buf.length, availableSize );
		bufLen = randomFile.read( buf, 0, len );
		return;
	}
	
    /**
     * The same behavior as InputStream.read().
* Reads the next byte of data from the input stream. The value byte is * returned as an int in the range 0 to * 255. If no byte is available because the end of the stream * has been reached, the value -1 is returned. This method * blocks until input data is available, the end of the stream is detected, * or an exception is thrown. * *

A subclass must provide an implementation of this method. * * @return the next byte of data, or -1 if the end of the * stream is reached. * @exception IOException if an I/O error occurs. */ public int read() throws IOException { if ( bufLen <= 0 || bufLen == bufCur ) readToBuffer(); if ( bufLen <= 0 ) return -1; return buf[ bufCur++ ] & 0xff; } /** * The same behavior as InputStream.read(byte b[], int off, int len ).
* Reads up to len bytes of data from the input stream into an array of bytes. * If no byte is available because the end of the stream has been reached, * the value -1 is returned. This method blocks until input data * is available, the end of the stream is detected, or an exception is thrown. * *

A subclass must provide an implementation of this method. * * @return the total number of bytes read into the buffer, or -1 * if there is no more data because the end of the stream has been reached * @exception IOException if an I/O error occurs. */ public int read( byte b[], int off, int len ) throws IOException { int n = 0; do { int count = this.read1(b, off + n, len - n); if (count < 0) break; n += count; } while (n < len); return (n > 0)? n : -1; } /** * Read the data in the buffer up to len to an array of bytes. * @param b * @param off * @param len * @return * @throws IOException */ private int read1( byte b[], int off, int len ) throws IOException { if ( bufLen <= 0 || bufLen == bufCur ) readToBuffer(); if ( bufLen <= 0 ) return -1; int availableSize = bufLen - bufCur; if ( len > availableSize ) len = availableSize; System.arraycopy( buf, bufCur, b, off, len ); bufCur += len; return len; } /** * Instead of calling randomAccessFile.readInt, we implement it in a better way (much better performace.) * The external behavior is the same as RandomAccessFile.readInt().
* Reads a signed 32-bit integer from this file. This method reads 4 * bytes from the file, starting at the current file pointer. * If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

     *     (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
     * 
*

* This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this stream, interpreted as an * int. * @exception EOFException if this stream reaches the end before reading * four bytes. * @exception IOException if an I/O error occurs. */ public int readInt() throws IOException { byte ch[] = new byte[4]; this.readFully(ch, 0, 4); int ret = 0; for ( int i = 0; i < ch.length; i++ ) ret = ((ret << 8) & 0xFFFFFF00) | (ch[i] & 0x000000FF); return ret; } /** * Reads a signed 64-bit integer from this file. This method reads eight * bytes from the file, starting at the current file pointer. * If the bytes read, in order, are * b1, b2, b3, * b4, b5, b6, * b7, and b8, where: *

     *     0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
     * 
*

* then the result is equal to: *

     *     ((long)b1 << 56) + ((long)b2 << 48)
     *     + ((long)b3 << 40) + ((long)b4 << 32)
     *     + ((long)b5 << 24) + ((long)b6 << 16)
     *     + ((long)b7 << 8) + b8
     * 
*

* This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this file, interpreted as a * long. * @exception EOFException if this file reaches the end before reading * eight bytes. * @exception IOException if an I/O error occurs. */ public long readLong() throws IOException { return ( (long) ( readInt( ) ) << 32 ) + ( readInt( ) & 0xFFFFFFFFL ); } /** * The same behavior as RandomAccessFile.readFully(byte b[], int off, int len) * Reads exactly len bytes from this file into the byte * array, starting at the current file pointer. This method reads * repeatedly from the file until the requested number of bytes are * read. This method blocks until the requested number of bytes are * read, the end of the stream is detected, or an exception is thrown. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the number of bytes to read. * @exception EOFException if this file reaches the end before reading * all the bytes. * @exception IOException if an I/O error occurs. */ public final void readFully(byte b[], int off, int len) throws IOException { int n = 0; do { int count = this.read(b, off + n, len - n); if (count < 0) throw new EOFException(); n += count; } while (n < len); } /** * @return the length of the stream * @throws IOException */ public long getStreamLength() throws IOException { return randomFile.length(); } /** * Move the file pointer to the new location in the stream * @param localPos - the new local postion in the stream. The localPos starts from 0. */ public void seek( long localPos ) throws IOException { if ( localPos > randomFile.getFilePointer() || localPos < randomFile.getFilePointer() - bufLen ) { randomFile.seek( localPos ); bufCur = 0; bufLen = 0; } else { bufCur = bufLen - (int)(randomFile.getFilePointer() - localPos); } } public long getOffset() throws IOException { return randomFile.getFilePointer( ) - bufLen + bufCur; } public long length() throws IOException { return getStreamLength(); } /** * Close the stream */ public void close( ) throws IOException { if ( manager != null ) { synchronized ( manager ) { manager.remove( this ); } } this.randomFile.close( ); // Since the the underlying random access file // is // created by us, we need to close it super.close( ); } public int available( ) throws IOException { long availableSize = randomFile.length( ) - randomFile.getFilePointer( ); if ( availableSize > Integer.MAX_VALUE ) { return Integer.MAX_VALUE; } else if ( availableSize < 0 ) { return -1; } else { return (int) availableSize; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy