KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > persist > ScaledRAFileInJar


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb.persist;
33
34 import java.io.DataInputStream JavaDoc;
35 import java.io.FileNotFoundException JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.InputStream JavaDoc;
38
39 import org.hsqldb.Database;
40 import org.hsqldb.lib.HsqlByteArrayInputStream;
41
42 /**
43  * This class is a random access wrapper around a DataInputStream object and
44  * enables access to cached tables when a database is included in a jar.
45  *
46  * A proof-of-concept prototype was first contributed by winfriedthom@users.
47  *
48  * @author fredt@users
49  * @version 1.8.0
50  * @since 1.8.0
51  */

52 class ScaledRAFileInJar implements ScaledRAInterface {
53
54     DataInputStream JavaDoc file;
55     final String JavaDoc fileName;
56     long fileLength;
57     boolean bufferDirty = true;
58     byte[] buffer = new byte[4096];
59     HsqlByteArrayInputStream ba = new HsqlByteArrayInputStream(buffer);
60     long bufferOffset;
61
62     //
63
long seekPosition;
64     long realPosition;
65
66     ScaledRAFileInJar(String JavaDoc name) throws FileNotFoundException JavaDoc, IOException JavaDoc {
67
68         fileName = name;
69
70         resetStream();
71         file.skip(DataFileCache.LONG_FREE_POS_POS);
72
73         fileLength = file.readLong();
74
75         resetStream();
76     }
77
78     public long length() throws IOException JavaDoc {
79         return fileLength;
80     }
81
82     /**
83      * Some JVM's do not allow seek beyond end of file, so zeros are written
84      * first in that case. Reported by bohgammer@users in Open Disucssion
85      * Forum.
86      */

87     public void seek(long position) throws IOException JavaDoc {
88         seekPosition = position;
89     }
90
91     public long getFilePointer() throws IOException JavaDoc {
92         return seekPosition;
93     }
94
95     private void readIntoBuffer() throws IOException JavaDoc {
96
97         long filePos = seekPosition;
98
99         bufferDirty = false;
100
101         long subOffset = filePos % buffer.length;
102         long readLength = fileLength - (filePos - subOffset);
103
104         if (readLength <= 0) {
105             throw new IOException JavaDoc("read beyond end of file");
106         }
107
108         if (readLength > buffer.length) {
109             readLength = buffer.length;
110         }
111
112         fileSeek(filePos - subOffset);
113         file.readFully(buffer, 0, (int) readLength);
114
115         bufferOffset = filePos - subOffset;
116         realPosition = bufferOffset + readLength;
117     }
118
119     public int read() throws IOException JavaDoc {
120
121         if (seekPosition >= fileLength) {
122             return -1;
123         }
124
125         if (bufferDirty || seekPosition < bufferOffset
126                 || seekPosition >= bufferOffset + buffer.length) {
127             readIntoBuffer();
128         }
129
130         ba.reset();
131         ba.skip(seekPosition - bufferOffset);
132
133         int val = ba.read();
134
135         seekPosition++;
136
137         return val;
138     }
139
140     public long readLong() throws IOException JavaDoc {
141
142         long hi = readInt();
143         long lo = readInt();
144
145         return (hi << 32) + (lo & 0xffffffffL);
146     }
147
148     public int readInt() throws IOException JavaDoc {
149
150         if (bufferDirty || seekPosition < bufferOffset
151                 || seekPosition >= bufferOffset + buffer.length) {
152             readIntoBuffer();
153         }
154
155         ba.reset();
156         ba.skip(seekPosition - bufferOffset);
157
158         int val = ba.readInt();
159
160         seekPosition += 4;
161
162         return val;
163     }
164
165     public void read(byte[] b, int offset, int length) throws IOException JavaDoc {
166
167         if (bufferDirty || seekPosition < bufferOffset
168                 || seekPosition >= bufferOffset + buffer.length) {
169             readIntoBuffer();
170         }
171
172         ba.reset();
173         ba.skip(seekPosition - bufferOffset);
174
175         int bytesRead = ba.read(b, offset, length);
176
177         seekPosition += bytesRead;
178
179         if (bytesRead < length) {
180             if (seekPosition != realPosition) {
181                 fileSeek(seekPosition);
182             }
183
184             file.readFully(b, offset + bytesRead, length - bytesRead);
185
186             seekPosition += (length - bytesRead);
187             realPosition = seekPosition;
188         }
189     }
190
191     public void write(byte[] b, int off, int len) throws IOException JavaDoc {}
192
193     public void writeInt(int i) throws IOException JavaDoc {}
194
195     public void writeLong(long i) throws IOException JavaDoc {}
196
197     public void close() throws IOException JavaDoc {
198         file.close();
199     }
200
201     public boolean isReadOnly() {
202         return true;
203     }
204
205     public boolean wasNio() {
206         return false;
207     }
208
209     private void resetStream() throws IOException JavaDoc {
210
211         if (file != null) {
212             file.close();
213         }
214
215         InputStream JavaDoc fis = getClass().getResourceAsStream(fileName);
216
217         file = new DataInputStream JavaDoc(fis);
218     }
219
220     private void fileSeek(long position) throws IOException JavaDoc {
221
222         long skipPosition = realPosition;
223
224         if (position < skipPosition) {
225             resetStream();
226
227             skipPosition = 0;
228         }
229
230         while (position > skipPosition) {
231             skipPosition += file.skip(position - skipPosition);
232         }
233     }
234
235     public boolean canAccess(int length) {
236         return false;
237     }
238
239     public boolean canSeek(long position) {
240         return false;
241     }
242
243     public Database getDatabase() {
244         return null;
245     }
246 }
247
Popular Tags