Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.file;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import com.gebauz.bauzoid.math.Matrix4;
import com.gebauz.bauzoid.math.Vector2;
import com.gebauz.bauzoid.math.Vector3;
import com.gebauz.bauzoid.math.Vector4;

/** File reader that supports interpreting various data types.
 *  
 * Extends the functionality of DataInputStream by the following features:
 * - More data types interpreted from stream
 * - Endianness handling
 *
 */

public class File
{
        private abstract class DataStreamAdapter
        {
                public abstract int read(byte[] buffer, int offset, int length) throws IOException;
                public abstract int read(byte[] buffer) throws IOException;
                public abstract boolean readBoolean() throws IOException;
                public abstract byte readByte() throws IOException;
                public abstract char readChar() throws IOException;
                public abstract double readDouble() throws IOException;
                public abstract float readFloat() throws IOException;
                public abstract void readFully(byte[] dst) throws IOException;
                public abstract void readFully(byte[] dst, int offset, int byteCount) throws IOException;
                public abstract int readInt() throws IOException;
                public abstract String readLine() throws IOException;
                public abstract long readLong() throws IOException;
                public abstract short readShort() throws IOException;
                public abstract String readUTF() throws IOException;
                public abstract int readUnsignedByte() throws IOException;
                public abstract int readUnsignedShort() throws IOException;
                public abstract int skipBytes(int count) throws IOException;
        };
       
        private class LittleEndianAdapter extends DataStreamAdapter
        {
                private LittleEndianDataInputStream mIS = null;
               
                public LittleEndianAdapter(InputStream is)
                {
                        mIS = new LittleEndianDataInputStream(is);
                }
               
                public int read(byte[] buffer, int offset, int length) throws IOException { return mIS.read(buffer, offset, length); }
                public int read(byte[] buffer) throws IOException { return mIS.read(buffer); }
                public boolean readBoolean() throws IOException { return mIS.readBoolean(); }
                public byte readByte() throws IOException { return mIS.readByte(); }
                public char readChar() throws IOException { return mIS.readChar(); }
                public double readDouble() throws IOException { return mIS.readDouble(); }
                public float readFloat() throws IOException { return mIS.readFloat(); }
                public void readFully(byte[] dst) throws IOException { mIS.readFully(dst); }
                public void readFully(byte[] dst, int offset, int byteCount) throws IOException {  mIS.readFully(dst, offset, byteCount); }
                public int readInt() throws IOException { return mIS.readInt(); }
                public String readLine() throws IOException { return mIS.readLine(); }
                public long readLong() throws IOException { return mIS.readLong(); }
                public short readShort() throws IOException { return mIS.readShort(); }
                public String readUTF() throws IOException { return mIS.readUTF(); }
                public int readUnsignedByte() throws IOException { return mIS.readUnsignedByte(); }
                public int readUnsignedShort() throws IOException { return mIS.readUnsignedShort(); }
                public int skipBytes(int count) throws IOException { return mIS.skipBytes(count); }
        }
       
        private class BigEndianAdapter extends DataStreamAdapter
        {
                private DataInputStream mIS = null;
               
                public BigEndianAdapter(InputStream is)
                {
                        mIS = new DataInputStream(is);
                }
               
                public int read(byte[] buffer, int offset, int length) throws IOException { return mIS.read(buffer, offset, length); }
                public int read(byte[] buffer) throws IOException { return mIS.read(buffer); }
                public boolean readBoolean() throws IOException { return mIS.readBoolean(); }
                public byte readByte() throws IOException { return mIS.readByte(); }
                public char readChar() throws IOException { return mIS.readChar(); }
                public double readDouble() throws IOException { return mIS.readDouble(); }
                public float readFloat() throws IOException { return mIS.readFloat(); }
                public void readFully(byte[] dst) throws IOException { mIS.readFully(dst); }
                public void readFully(byte[] dst, int offset, int byteCount) throws IOException {  mIS.readFully(dst, offset, byteCount); }
                public int readInt() throws IOException { return mIS.readInt(); }
                @SuppressWarnings("deprecation")
                public String readLine() throws IOException { return mIS.readLine(); }
                public long readLong() throws IOException { return mIS.readLong(); }
                public short readShort() throws IOException { return mIS.readShort(); }
                public String readUTF() throws IOException { return mIS.readUTF(); }
                public int readUnsignedByte() throws IOException { return mIS.readUnsignedByte(); }
                public int readUnsignedShort() throws IOException { return mIS.readUnsignedShort(); }
                public int skipBytes(int count) throws IOException { return mIS.skipBytes(count); }
        }
       
        private InputStream mInputStream = null;
        private LittleEndianAdapter mLittleEndian = null;
        private BigEndianAdapter mBigEndian = null;
        private DataStreamAdapter mIS = null;
        private Endianness mEndianness = Endianness.BIG_ENDIAN;
       
        public enum Endianness
        {
                LITTLE_ENDIAN,
                BIG_ENDIAN
        };
       
        /** Constructor. Takes an InputStream and claims responsibility for closing it. */
        public File(InputStream is)
        {
                mInputStream = is;
               
                mLittleEndian = new LittleEndianAdapter(mInputStream);
                mBigEndian = new BigEndianAdapter(mInputStream);
               
                mIS = mBigEndian;
        }
       
        /** Close the InputStream. */
        public void close() throws IOException
        {
                if (mInputStream != null)
                {
                        mInputStream.close();
                        mInputStream = null;
                       
                        mLittleEndian = null;
                        mBigEndian = null;
                        mIS = null;
                }
        }

        public final void setEndianness(Endianness endianness)
        {
                mEndianness = endianness;
               
                switch (endianness)
                {
                case LITTLE_ENDIAN:
                        mIS = mLittleEndian;
                        break;
                case BIG_ENDIAN:
                        mIS = mBigEndian;
                        break;
                }
        }
       
        public final Endianness getEndianness()
        {
                return mEndianness;
        }
       
        /** Reads n bytes to a String. */
        public final String readString(int n) throws IOException
        {
                byte[] buffer = new byte[n];
                mIS.read(buffer);
               
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                os.write(buffer);
                os.close();
                       
                return os.toString();
        }
       
        /** Reads an int for the length, then interprets the following length bytes as the String. */
        public final String readString() throws IOException
        {
                int length = mIS.readInt();
               
                return readString(length);
        }
       
        /** Read a 8-bit C-style bool value. */
        public final boolean readBool() throws IOException
        {
                byte result = readByte();
                return (result != 0);
        }
       
        /** Reads 3 float values and returns a Vector2. */
        public final Vector2 readVector2() throws IOException
        {
                Vector2 result = new Vector2();
                result.x = readFloat();
                result.y = readFloat();
                return result;
        }
       
        /** Reads 3 float values and returns a Vector3. */
        public final Vector3 readVector3() throws IOException
        {
                Vector3 result = new Vector3();
                result.x = readFloat();
                result.y = readFloat();
                result.z = readFloat();
                return result;
        }
       
        /** Reads 4 float values and returns a Vector4. */
        public final Vector4 readVector4() throws IOException
        {
                Vector4 result = new Vector4();
                result.x = readFloat();
                result.y = readFloat();
                result.z = readFloat();
                result.w = readFloat();
                return result;
        }
       
        /** Read a 4x4 matrix (16 floats). */
        public final Matrix4 readMatrix4() throws IOException
        {
                float[] matrix = new float[16];
                for (int i = 0; i < 16; i++)
                {
                        matrix[i] = readFloat();
                }
               
                return new Matrix4(matrix);
        }
       
        /** Read a bitmap. */
/*      public final Bitmap readBitmap() throws IOException
        {
                return BitmapFactory.decodeStream(mInputStream);
        }*/

       
        /** Get the internal input stream. */
        public final InputStream getInputStream()
        {
                return mInputStream;
        }
       
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
        public final int read(byte[] buffer, int offset, int length) throws IOException
        {
                return mIS.read(buffer, offset, length);               
        }
       
       
        /** Equivalent to read(buffer, 0, buffer.length).*/
        public final int read(byte[] buffer) throws IOException
        {
                return mIS.read(buffer);
        }
       
        /** Reads a Java boolean (32-bit single, 8-bit in arrays). */
        public final boolean readBoolean() throws IOException
        {
                return mIS.readBoolean();
        }
       
        /** Reads an 8-bit byte. */
        public final byte readByte() throws IOException
        {
                return mIS.readByte();
        }
       
        /** Reads a big-endian 16-bit character value. */
        public final char readChar() throws IOException
        {
                return mIS.readChar();
        }

        /** Reads a big-endian 64-bit double value. */
        public final double readDouble() throws IOException
        {
                return mIS.readDouble();
        }

        /** Reads a big-endian 32-bit float value. */
        public final float readFloat() throws IOException
        {
                return mIS.readFloat();
        }

        /** Equivalent to readFully(dst, 0, dst.length);. */
        public final void readFully(byte[] dst) throws IOException
        {
                mIS.readFully(dst);
        }

        /** Reads byteCount bytes from this stream and stores them in the byte array dst starting at offset. */
        public final void readFully(byte[] dst, int offset, int byteCount) throws IOException
        {
                mIS.readFully(dst, offset, byteCount);
        }

        /** Reads a big-endian 32-bit integer value. */
        public final int readInt() throws IOException
        {
                return mIS.readInt();
        }

        /** Returns a string containing the next line of text available from this stream. */
        public final String readLine() throws IOException
        {
                return mIS.readLine();
        }

        /** Reads a big-endian 64-bit long value. */
        public final long readLong() throws IOException
        {
                return mIS.readLong();
        }
       
        /** Reads a big-endian 16-bit short value. */
        public final short readShort() throws IOException
        {
                return mIS.readShort();
        }
       
        /** Reads a string encoded with modified UTF-8. */
        public final String readUTF() throws IOException
        {
                return mIS.readUTF();
        }

        /** Reads an unsigned 8-bit byte value and returns it as an int. */
        public final int readUnsignedByte() throws IOException
        {
                return mIS.readUnsignedByte();
        }
       
        /** Reads a big-endian 16-bit unsigned short value and returns it as an int. */
        public final int readUnsignedShort() throws IOException
        {
                return mIS.readUnsignedShort();
        }
       
        /** Skips count number of bytes in this stream. */
        public final int skipBytes(int count) throws IOException
        {
                return mIS.skipBytes(count);
        }      

}