corrade-vassal – Rev 1
?pathlinks?
/*
* CVS Identifier:
*
* $Id: BufferedRandomAccessFile.java,v 1.21 2001/04/15 14:34:29 grosbois Exp $
*
* Interface: RandomAccessIO.java
*
* Description: Abstract class for buffered random access I/O.
*
*
*
* COPYRIGHT:
*
* This software module was originally developed by Raphaël Grosbois and
* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
* Centre France S.A) in the course of development of the JPEG2000
* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
* software module is an implementation of a part of the JPEG 2000
* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
* Systems AB and Canon Research Centre France S.A (collectively JJ2000
* Partners) agree not to assert against ISO/IEC and users of the JPEG
* 2000 Standard (Users) any of their rights under the copyright, not
* including other intellectual property rights, for this software module
* with respect to the usage by ISO/IEC and Users of this software module
* or modifications thereof for use in hardware or software products
* claiming conformance to the JPEG 2000 Standard. Those intending to use
* this software module in hardware or software products are advised that
* their use may infringe existing patents. The original developers of
* this software module, JJ2000 Partners and ISO/IEC assume no liability
* for use of this software module or modifications thereof. No license
* or right to this software module is granted for non JPEG 2000 Standard
* conforming products. JJ2000 Partners have full right to use this
* software module for his/her own purpose, assign or donate this
* software module to any third party and to inhibit third parties from
* using this software module for non JPEG 2000 Standard conforming
* products. This copyright notice must be included in all copies or
* derivative works of this software module.
*
* Copyright (c) 1999/2000 JJ2000 Partners.
* */
using System;
namespace CSJ2K.j2k.io
{
/// <summary> This class defines a Buffered Random Access File. It implements the
/// <tt>BinaryDataInput</tt> and <tt>BinaryDataOutput</tt> interfaces so that
/// binary data input/output can be performed. This class is abstract since no
/// assumption is done about the byte ordering type (little Endian, big
/// Endian). So subclasses will have to implement methods like
/// <tt>readShort()</tt>, <tt>writeShort()</tt>, <tt>readFloat()</tt>, ...
///
/// <P><tt>BufferedRandomAccessFile</tt> (BRAF for short) is a
/// <tt>RandomAccessFile</tt> containing an extra buffer. When the BRAF is
/// accessed, it checks if the requested part of the file is in the buffer or
/// not. If that is the case, the read/write is done on the buffer. If not, the
/// file is uppdated to reflect the current status of the buffer and the file
/// is then accessed for a new buffer containing the requested byte/bit.
///
/// </summary>
/// <seealso cref="RandomAccessIO">
/// </seealso>
/// <seealso cref="BinaryDataOutput">
/// </seealso>
/// <seealso cref="BinaryDataInput">
/// </seealso>
/// <seealso cref="BEBufferedRandomAccessFile">
///
/// </seealso>
public abstract class BufferedRandomAccessFile : RandomAccessIO, EndianType
{
/// <summary> Returns the current offset in the file
///
/// </summary>
virtual public int Pos
{
get
{
return (offset + position);
}
}
/// <summary> Returns the endianess (i.e., byte ordering) of the implementing
/// class. Note that an implementing class may implement only one
/// type of endianness or both, which would be decided at creation
/// time.
///
/// </summary>
/// <returns> Either <tt>EndianType.BIG_ENDIAN</tt> or
/// <tt>EndianType.LITTLE_ENDIAN</tt>
///
/// </returns>
/// <seealso cref="EndianType">
///
/// </seealso>
virtual public int ByteOrdering
{
get
{
return byte_Ordering;
}
}
/// <summary>The name of the current file </summary>
private System.String fileName;
/// <summary> Whether the opened file is read only or not (defined by the constructor
/// arguments)
///
/// </summary>
private bool isReadOnly = true;
/// <summary> The RandomAccessFile associated with the buffer
///
/// </summary>
//UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'"
private System.IO.FileStream theFile;
/// <summary> Buffer of bytes containing the part of the file that is currently being
/// accessed
///
/// </summary>
protected internal byte[] byteBuffer;
/// <summary> Boolean keeping track of whether the byte buffer has been changed since
/// it was read.
///
/// </summary>
protected internal bool byteBufferChanged;
/// <summary> The current offset of the buffer (which will differ from the offset of
/// the file)
///
/// </summary>
protected internal int offset;
/// <summary> The current position in the byte-buffer
///
/// </summary>
protected internal int position;
/// <summary> The maximum number of bytes that can be read from the buffer
///
/// </summary>
protected internal int maxByte;
/// <summary> Whether the end of the file is in the current buffer or not
///
/// </summary>
protected internal bool isEOFInBuffer;
/* The endianess of the class */
protected internal int byte_Ordering;
/// <summary> Constructor. Always needs a size for the buffer.
///
/// </summary>
/// <param name="file">The file associated with the buffer
///
/// </param>
/// <param name="mode">"r" for read, "rw" or "rw+" for read and write mode ("rw+"
/// opens the file for update whereas "rw" removes it
/// before. So the 2 modes are different only if the file
/// already exists).
///
/// </param>
/// <param name="bufferSize">The number of bytes to buffer
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.String mode, int bufferSize)
{
fileName = file.Name;
if (mode.Equals("rw") || mode.Equals("rw+"))
{
// mode read / write
isReadOnly = false;
if (mode.Equals("rw"))
{
// mode read / (over)write
bool tmpBool;
if (System.IO.File.Exists(file.FullName))
tmpBool = true;
else
tmpBool = System.IO.Directory.Exists(file.FullName);
if (tmpBool)
// Output file already exists
{
bool tmpBool2;
if (System.IO.File.Exists(file.FullName))
{
System.IO.File.Delete(file.FullName);
tmpBool2 = true;
}
else if (System.IO.Directory.Exists(file.FullName))
{
System.IO.Directory.Delete(file.FullName);
tmpBool2 = true;
}
else
tmpBool2 = false;
bool generatedAux = tmpBool2;
}
}
mode = "rw";
}
theFile = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, mode);
byteBuffer = new byte[bufferSize];
readNewBuffer(0);
}
/// <summary> Constructor. Uses the default value for the byte-buffer
/// size (512 bytes).
///
/// </summary>
/// <param name="file">The file associated with the buffer
///
/// </param>
/// <param name="mode">"r" for read, "rw" or "rw+" for read and write mode
/// ("rw+" opens the file for update whereas "rw" removes
/// it before. So the 2 modes are different only if the
/// file already exists).
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
protected internal BufferedRandomAccessFile(System.IO.FileInfo file, System.String mode):this(file, mode, 512)
{
}
/// <summary> Constructor. Always needs a size for the buffer.
///
/// </summary>
/// <param name="name">The name of the file associated with the buffer
///
/// </param>
/// <param name="mode">"r" for read, "rw" or "rw+" for read and write mode
/// ("rw+" opens the file for update whereas "rw" removes
/// it before. So the 2 modes are different only if the
/// file already exists).
///
/// </param>
/// <param name="bufferSize">The number of bytes to buffer
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
protected internal BufferedRandomAccessFile(System.String name, System.String mode, int bufferSize):this(new System.IO.FileInfo(name), mode, bufferSize)
{
}
/// <summary> Constructor. Uses the default value for the byte-buffer
/// size (512 bytes).
///
/// </summary>
/// <param name="name">The name of the file associated with the buffer
///
/// </param>
/// <param name="mode">"r" for read, "rw" or "rw+" for read and write mode
/// ("rw+" opens the file for update whereas "rw" removes
/// it before. So the 2 modes are different only if the
/// file already exists).
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
protected internal BufferedRandomAccessFile(System.String name, System.String mode):this(name, mode, 512)
{
}
/// <summary> Reads a new buffer from the file. If there has been any
/// changes made since the buffer was read, the buffer is
/// first written to the file.
///
/// </summary>
/// <param name="off">The offset where to move to.
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
protected internal void readNewBuffer(int off)
{
/* If the buffer have changed. We need to write it to
* the file before reading a new buffer.
*/
if (byteBufferChanged)
{
flush();
}
// Don't allow to seek beyond end of file if reading only
if (isReadOnly && off >= theFile.Length)
{
throw new System.IO.EndOfStreamException();
}
// Set new offset
offset = off;
theFile.Seek(offset, System.IO.SeekOrigin.Begin);
maxByte = theFile.Read(byteBuffer, 0, byteBuffer.Length);
position = 0;
if (maxByte < byteBuffer.Length)
{
// Not enough data in input file.
isEOFInBuffer = true;
if (maxByte == - 1)
{
maxByte++;
}
}
else
{
isEOFInBuffer = false;
}
}
/// <summary> Closes the buffered random access file
///
/// </summary>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public virtual void close()
{
/* If the buffer has been changed, it need to be saved before
* closing
*/
flush();
byteBuffer = null; // Release the byte-buffer reference
theFile.Close();
}
/// <summary> Returns the current length of the stream, in bytes, taking into
/// account any buffering.
///
/// </summary>
/// <returns> The length of the stream, in bytes.
///
/// </returns>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public virtual int length()
{
int len;
len = (int) theFile.Length;
// If the position in the buffer is not past the end of the file,
// the length of theFile is the length of the stream
if ((offset + maxByte) <= len)
{
return (len);
}
else
{
// If not, the file is extended due to the buffering
return (offset + maxByte);
}
}
/// <summary> Moves the current position to the given offset at which the
/// next read or write occurs. The offset is measured from the
/// beginning of the stream.
///
/// </summary>
/// <param name="off">The offset where to move to.
///
/// </param>
/// <exception cref="EOFException">If in read-only and seeking beyond EOF.
///
/// </exception>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public virtual void seek(int off)
{
/* If the new offset is within the buffer, only the pos value needs
* to be modified. Else, the buffer must be moved. */
if ((off >= offset) && (off < (offset + byteBuffer.Length)))
{
if (isReadOnly && isEOFInBuffer && off > offset + maxByte)
{
// We are seeking beyond EOF in read-only mode!
throw new System.IO.EndOfStreamException();
}
position = off - offset;
}
else
{
readNewBuffer(off);
}
}
/// <summary> Reads an unsigned byte of data from the stream. Prior to reading, the
/// stream is realigned at the byte level.
///
/// </summary>
/// <returns> The byte read.
///
/// </returns>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
/// <exception cref="java.io.EOFException">If the end of file was reached
///
/// </exception>
public byte readByte() { return read(); }
public byte readUnsignedByte() { return read(); }
public byte read()
{
if (position < maxByte)
{
// The byte can be read from the buffer
// In Java, the bytes are always signed.
return (byteBuffer[position++]);
}
else if (isEOFInBuffer)
{
// EOF is reached
position = maxByte + 1; // Set position to EOF
throw new System.IO.EndOfStreamException();
}
else
{
// End of the buffer is reached
readNewBuffer(offset + position);
return read();
}
}
/// <summary> Reads up to len bytes of data from this file into an array of
/// bytes. This method reads repeatedly from the stream until all the bytes
/// are read. This method blocks until all the bytes are read, the end of
/// the stream is detected, or an exception is thrown.
///
/// </summary>
/// <param name="b">The buffer into which the data is to be read. It must be long
/// enough.
///
/// </param>
/// <param name="off">The index in 'b' where to place the first byte read.
///
/// </param>
/// <param name="len">The number of bytes to read.
///
/// </param>
/// <exception cref="EOFException">If the end-of file was reached before
/// getting all the necessary data.
///
/// </exception>
/// <exception cref="IOException">If an I/O error ocurred.
///
/// </exception>
public void readFully(byte[] b, int off, int len)
{
int clen; // current length to read
while (len > 0)
{
// There still is some data to read
if (position < maxByte)
{
// We can read some data from buffer
clen = maxByte - position;
if (clen > len)
clen = len;
Array.Copy(byteBuffer, position, b, off, clen);
position += clen;
off += clen;
len -= clen;
}
else if (isEOFInBuffer)
{
position = maxByte + 1; // Set position to EOF
throw new System.IO.EndOfStreamException();
}
else
{
// Buffer empty => get more data
readNewBuffer(offset + position);
}
}
}
/// <summary> Writes a byte to the stream. Prior to writing, the stream is
/// realigned at the byte level.
///
/// </summary>
/// <param name="b">The byte to write. The lower 8 bits of <tt>b</tt> are
/// written.
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public void write(int b)
{
// As long as pos is less than the length of the buffer we can write
// to the buffer. If the position is after the buffer a new buffer is
// needed
if (position < byteBuffer.Length)
{
if (isReadOnly)
throw new System.IO.IOException("File is read only");
byteBuffer[position] = (byte) b;
if (position >= maxByte)
{
maxByte = position + 1;
}
position++;
byteBufferChanged = true;
}
else
{
readNewBuffer(offset + position);
write(b);
}
}
/// <summary> Writes a byte to the stream. Prior to writing, the stream is
/// realigned at the byte level.
///
/// </summary>
/// <param name="b">The byte to write.
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public void write(byte b)
{
// As long as pos is less than the length of the buffer we can write
// to the buffer. If the position is after the buffer a new buffer is
// needed
if (position < byteBuffer.Length)
{
if (isReadOnly)
throw new System.IO.IOException("File is read only");
byteBuffer[position] = b;
if (position >= maxByte)
{
maxByte = position + 1;
}
position++;
byteBufferChanged = true;
}
else
{
readNewBuffer(offset + position);
write(b);
}
}
/// <summary> Writes aan array of bytes to the stream. Prior to writing, the stream is
/// realigned at the byte level.
///
/// </summary>
/// <param name="b">The array of bytes to write.
///
/// </param>
/// <param name="offset">The first byte in b to write
///
/// </param>
/// <param name="length">The number of bytes from b to write
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public void write(byte[] b, int offset, int length)
{
int i, stop;
stop = offset + length;
if (stop > b.Length)
throw new System. IndexOutOfRangeException("Index of bound " + b.Length);
for (i = offset; i < stop; i++)
{
write(b[i]);
}
}
/// <summary> Writes the byte value of <tt>v</tt> (i.e., 8 least
/// significant bits) to the output. Prior to writing, the output
/// should be realigned at the byte level.
///
/// <P>Signed or unsigned data can be written. To write a signed
/// value just pass the <tt>byte</tt> value as an argument. To
/// write unsigned data pass the <tt>int</tt> value as an argument
/// (it will be automatically casted, and only the 8 least
/// significant bits will be written).
///
/// </summary>
/// <param name="v">The value to write to the output
///
/// </param>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public void writeByte(int v)
{
write(v);
}
/// <summary> Any data that has been buffered must be written (including
/// buffering at the bit level), and the stream should be realigned
/// at the byte level.
///
/// </summary>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public void flush()
{
if (byteBufferChanged)
{
theFile.Seek(offset, System.IO.SeekOrigin.Begin);
theFile.Write(byteBuffer, 0, maxByte);
byteBufferChanged = false;
}
}
/*
/// <summary> Reads a signed byte (i.e., 8 bit) from the input. Prior to
/// reading, the input should be realigned at the byte level.
///
/// </summary>
/// <returns> The next byte-aligned signed byte (8 bit) from the
/// input.
///
/// </returns>
/// <exception cref="java.io.EOFException">If the end-of file was reached before
/// getting all the necessary data.
///
/// </exception>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public byte readByte()
{
if (pos < maxByte)
{
// The byte can be read from the buffer
// In Java, the bytes are always signed.
return byteBuffer[pos++];
}
else if (isEOFInBuffer)
{
// EOF is reached
pos = maxByte + 1; // Set position to EOF
throw new System.IO.EndOfStreamException();
}
else
{
// End of the buffer is reached
readNewBuffer(offset + pos);
return readByte();
}
}
/// <summary> Reads an unsigned byte (i.e., 8 bit) from the input. It is
/// returned as an <tt>int</tt> since Java does not have an
/// unsigned byte type. Prior to reading, the input should be
/// realigned at the byte level.
///
/// </summary>
/// <returns> The next byte-aligned unsigned byte (8 bit) from the
/// input, as an <tt>int</tt>.
///
/// </returns>
/// <exception cref="java.io.EOFException">If the end-of file was reached before
/// getting all the necessary data.
///
/// </exception>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public int readUnsignedByte()
{
return read();
}
*/
/// <summary> Skips <tt>n</tt> bytes from the input. Prior to skipping, the
/// input should be realigned at the byte level.
///
/// </summary>
/// <param name="n">The number of bytes to skip
///
/// </param>
/// <exception cref="java.io.EOFException">If the end-of file was reached before
/// all the bytes could be skipped.
///
/// </exception>
/// <exception cref="java.io.IOException">If an I/O error ocurred.
///
/// </exception>
public virtual int skipBytes(int n)
{
if (n < 0)
throw new System.ArgumentException("Can not skip negative number " + "of bytes");
if (n <= (maxByte - position))
{
position += n;
return n;
}
else
{
seek(offset + position + n);
return n;
}
}
/// <summary> Returns a string of information about the file
///
/// </summary>
public override System.String ToString()
{
return "BufferedRandomAccessFile: " + fileName + " (" + ((isReadOnly)?"read only":"read/write") + ")";
}
public abstract int readUnsignedShort();
public abstract void writeLong(long param1);
public abstract void writeShort(int param1);
public abstract float readFloat();
public abstract short readShort();
public abstract double readDouble();
public abstract int readInt();
public abstract long readLong();
public abstract long readUnsignedInt();
public abstract void writeDouble(double param1);
public abstract void writeFloat(float param1);
public abstract void writeInt(int param1);
}
}
Generated by GNU Enscript 1.6.5.90.