001: /*
002: Copyright (c) 2006, Matthew Estes
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright
009: notice, this list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright
011: notice, this list of conditions and the following disclaimer in the
012: documentation and/or other materials provided with the distribution.
013: * Neither the name of Metanotion Software nor the names of its
014: contributors may be used to endorse or promote products derived from this
015: software without specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018: IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
019: THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
020: PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029: package net.metanotion.io;
030:
031: import java.io.DataInput;
032: import java.io.DataOutput;
033: import java.io.File;
034: import java.io.FileNotFoundException;
035: import java.io.IOException;
036: import java.io.RandomAccessFile;
037:
038: public class RAIFile implements RandomAccessInterface, DataInput,
039: DataOutput {
040: private File f;
041: private RandomAccessFile delegate;
042: private boolean r = false, w = false;
043:
044: public RAIFile(RandomAccessFile file) throws FileNotFoundException {
045: this .f = null;
046: this .delegate = file;
047: }
048:
049: public RAIFile(File file, boolean read, boolean write)
050: throws FileNotFoundException {
051: this .f = file;
052: this .r = read;
053: this .w = write;
054: String mode = "";
055: if (this .r) {
056: mode += "r";
057: }
058: if (this .w) {
059: mode += "w";
060: }
061: this .delegate = new RandomAccessFile(file, mode);
062: }
063:
064: public long getFilePointer() throws IOException {
065: return delegate.getFilePointer();
066: }
067:
068: public long length() throws IOException {
069: return delegate.length();
070: }
071:
072: public int read() throws IOException {
073: return delegate.read();
074: }
075:
076: public int read(byte[] b) throws IOException {
077: return delegate.read(b);
078: }
079:
080: public int read(byte[] b, int off, int len) throws IOException {
081: return delegate.read(b, off, len);
082: }
083:
084: public void seek(long pos) throws IOException {
085: delegate.seek(pos);
086: }
087:
088: public void setLength(long newLength) throws IOException {
089: delegate.setLength(newLength);
090: }
091:
092: // Closeable Methods
093: // TODO May need to change.
094: public void close() throws IOException {
095: delegate.close();
096: }
097:
098: // DataInput Methods
099: public boolean readBoolean() throws IOException {
100: return delegate.readBoolean();
101: }
102:
103: public byte readByte() throws IOException {
104: return delegate.readByte();
105: }
106:
107: public char readChar() throws IOException {
108: return delegate.readChar();
109: }
110:
111: public double readDouble() throws IOException {
112: return delegate.readDouble();
113: }
114:
115: public float readFloat() throws IOException {
116: return delegate.readFloat();
117: }
118:
119: public void readFully(byte[] b) throws IOException {
120: delegate.readFully(b);
121: }
122:
123: public void readFully(byte[] b, int off, int len)
124: throws IOException {
125: delegate.readFully(b, off, len);
126: }
127:
128: public int readInt() throws IOException {
129: return delegate.readInt();
130: }
131:
132: public String readLine() throws IOException {
133: return delegate.readLine();
134: }
135:
136: public long readLong() throws IOException {
137: return delegate.readLong();
138: }
139:
140: public short readShort() throws IOException {
141: return delegate.readShort();
142: }
143:
144: public int readUnsignedByte() throws IOException {
145: return delegate.readUnsignedByte();
146: }
147:
148: public int readUnsignedShort() throws IOException {
149: return delegate.readUnsignedShort();
150: }
151:
152: /** Read a UTF encoded string
153: I would delegate here. But Java's read/writeUTF combo suck.
154: A signed 2 byte length is not enough.
155: This reads a 4 byte length.
156: The upper byte MUST be zero, if its not, then its not this method and has used an
157: extensible length encoding.
158: This is followed by the bytes of the UTF encoded string, as
159: returned by String.getBytes("UTF-8");
160: */
161: public String readUTF() throws IOException {
162: int len = delegate.readInt();
163: if ((len < 0) || (len >= 16777216)) {
164: throw new IOException("Bad Length Encoding");
165: }
166: byte[] bytes = new byte[len];
167: int l = delegate.read(bytes);
168: if (l == -1) {
169: throw new IOException("EOF while reading String");
170: }
171: String s = new String(bytes, "UTF-8");
172: return s;
173: }
174:
175: public int skipBytes(int n) throws IOException {
176: return delegate.skipBytes(n);
177: }
178:
179: // DataOutput Methods
180: public void write(int b) throws IOException {
181: delegate.write(b);
182: }
183:
184: public void write(byte[] b) throws IOException {
185: delegate.write(b);
186: }
187:
188: public void write(byte[] b, int off, int len) throws IOException {
189: delegate.write(b, off, len);
190: }
191:
192: public void writeBoolean(boolean v) throws IOException {
193: delegate.writeBoolean(v);
194: }
195:
196: public void writeByte(int v) throws IOException {
197: delegate.writeByte(v);
198: }
199:
200: public void writeShort(int v) throws IOException {
201: delegate.writeShort(v);
202: }
203:
204: public void writeChar(int v) throws IOException {
205: delegate.writeChar(v);
206: }
207:
208: public void writeInt(int v) throws IOException {
209: delegate.writeInt(v);
210: }
211:
212: public void writeLong(long v) throws IOException {
213: delegate.writeLong(v);
214: }
215:
216: public void writeFloat(float v) throws IOException {
217: delegate.writeFloat(v);
218: }
219:
220: public void writeDouble(double v) throws IOException {
221: delegate.writeDouble(v);
222: }
223:
224: public void writeBytes(String s) throws IOException {
225: delegate.writeBytes(s);
226: }
227:
228: public void writeChars(String s) throws IOException {
229: delegate.writeChars(s);
230: }
231:
232: /** Write a UTF encoded string
233: I would delegate here. But Java's read/writeUTF combo suck.
234: A signed 2 byte length is not enough.
235: This writes a 4 byte length.
236: The upper byte MUST be zero, if its not, then its not this method and has used an
237: extensible length encoding.
238: This is followed by the bytes of the UTF encoded string, as
239: returned by String.getBytes("UTF-8");
240: */
241: public void writeUTF(String str) throws IOException {
242: byte[] string = str.getBytes("UTF-8");
243: if (string.length >= 16777216) {
244: throw new IOException("String to long for encoding type");
245: }
246: delegate.writeInt(string.length);
247: delegate.write(string);
248: }
249: }
|