Blob.java revision 417deb1db112103aff04231b6ca79772ff7d3a21
1package SQLite;
2
3import java.io.*;
4
5/**
6 * Internal class implementing java.io.InputStream on
7 * SQLite 3.4.0 incremental blob I/O interface.
8 */
9
10class BlobR extends InputStream {
11
12    /**
13     * Blob instance
14     */
15
16    private Blob blob;
17
18    /**
19     * Read position, file pointer.
20     */
21
22    private int pos;
23
24    /**
25     * Contruct InputStream from blob instance.
26     */
27
28    BlobR(Blob blob) {
29    this.blob = blob;
30    this.pos = 0;
31    }
32
33    /**
34     * Return number of available bytes for reading.
35     * @return available input bytes
36     */
37
38    public int available() throws IOException {
39    int ret = blob.size - pos;
40    return (ret < 0) ? 0 : ret;
41    }
42
43    /**
44     * Mark method; dummy to satisfy InputStream class.
45     */
46
47    public void mark(int limit) {
48    }
49
50    /**
51     * Reset method; dummy to satisfy InputStream class.
52     */
53
54    public void reset() throws IOException {
55    }
56
57    /**
58     * Mark support; not for this class.
59     * @return always false
60     */
61
62    public boolean markSupported() {
63    return false;
64    }
65
66    /**
67     * Close this blob InputStream.
68     */
69
70    public void close() throws IOException {
71        blob.close();
72    blob = null;
73    pos = 0;
74    }
75
76    /**
77     * Skip over blob data.
78     */
79
80    public long skip(long n) throws IOException {
81    long ret = pos + n;
82    if (ret < 0) {
83        ret = 0;
84        pos = 0;
85    } else if (ret > blob.size) {
86        ret = blob.size;
87        pos = blob.size;
88    } else {
89        pos = (int) ret;
90    }
91    return ret;
92    }
93
94    /**
95     * Read single byte from blob.
96     * @return byte read
97     */
98
99    public int read() throws IOException {
100    byte b[] = new byte[1];
101    int n = blob.read(b, 0, pos, b.length);
102    if (n > 0) {
103        pos += n;
104        return b[0];
105    }
106    return -1;
107    }
108
109    /**
110     * Read byte array from blob.
111     * @param b byte array to be filled
112     * @return number of bytes read
113     */
114
115    public int read(byte b[]) throws IOException {
116    int n = blob.read(b, 0, pos, b.length);
117    if (n > 0) {
118        pos += n;
119        return n;
120    }
121    return -1;
122    }
123
124    /**
125     * Read slice of byte array from blob.
126     * @param b byte array to be filled
127     * @param off offset into byte array
128     * @param len length to be read
129     * @return number of bytes read
130     */
131
132    public int read(byte b[], int off, int len) throws IOException {
133    if (off + len > b.length) {
134        len = b.length - off;
135    }
136    if (len < 0) {
137        return -1;
138    }
139    if (len == 0) {
140        return 0;
141    }
142    int n = blob.read(b, off, pos, len);
143    if (n > 0) {
144        pos += n;
145        return n;
146    }
147    return -1;
148    }
149}
150
151/**
152 * Internal class implementing java.io.OutputStream on
153 * SQLite 3.4.0 incremental blob I/O interface.
154 */
155
156class BlobW extends OutputStream {
157
158    /**
159     * Blob instance
160     */
161
162    private Blob blob;
163
164    /**
165     * Read position, file pointer.
166     */
167
168    private int pos;
169
170    /**
171     * Contruct OutputStream from blob instance.
172     */
173
174    BlobW(Blob blob) {
175    this.blob = blob;
176    this.pos = 0;
177    }
178
179    /**
180     * Flush blob; dummy to satisfy OutputStream class.
181     */
182
183    public void flush() throws IOException {
184    }
185
186    /**
187     * Close this blob OutputStream.
188     */
189
190    public void close() throws IOException {
191        blob.close();
192    blob = null;
193    pos = 0;
194    }
195
196    /**
197     * Write blob data.
198     * @param v byte to be written at current position.
199     */
200
201    public void write(int v) throws IOException {
202    byte b[] = new byte[1];
203    b[0] = (byte) v;
204    pos += blob.write(b, 0, pos, 1);
205    }
206
207    /**
208     * Write blob data.
209     * @param b byte array to be written at current position.
210     */
211
212    public void write(byte[] b) throws IOException {
213    if (b != null && b.length > 0) {
214        pos += blob.write(b, 0, pos, b.length);
215    }
216    }
217
218    /**
219     * Write blob data.
220     * @param b byte array to be written.
221     * @param off offset within byte array
222     * @param len length of data to be written
223     */
224
225    public void write(byte[] b, int off, int len) throws IOException {
226    if (b != null) {
227        if (off + len > b.length) {
228        len = b.length - off;
229        }
230        if (len <= 0) {
231        return;
232        }
233        pos += blob.write(b, off, pos, len);
234    }
235    }
236}
237
238/**
239 * Class to represent SQLite3 3.4.0 incremental blob I/O interface.
240 *
241 * Note, that all native methods of this class are
242 * not synchronized, i.e. it is up to the caller
243 * to ensure that only one thread is in these
244 * methods at any one time.
245 */
246
247public class Blob {
248
249    /**
250     * Internal handle for the SQLite3 blob.
251     */
252
253    private long handle = 0;
254
255    /**
256     * Cached size of blob, setup right after blob
257     * has been opened.
258     */
259
260    protected int size = 0;
261
262    /**
263     * Return InputStream for this blob
264     * @return InputStream
265     */
266
267    public InputStream getInputStream() {
268    return (InputStream) new BlobR(this);
269    }
270
271    /**
272     * Return OutputStream for this blob
273     * @return OutputStream
274     */
275
276    public OutputStream getOutputStream() {
277    return (OutputStream) new BlobW(this);
278    }
279
280    /**
281     * Close blob.
282     */
283
284    public native void close();
285
286    /**
287     * Internal blob write method.
288     * @param b byte array to be written
289     * @param off offset into byte array
290     * @param pos offset into blob
291     * @param len length to be written
292     * @return number of bytes written to blob
293     */
294
295    native int write(byte[] b, int off, int pos, int len) throws IOException;
296
297    /**
298     * Internal blob read method.
299     * @param b byte array to be written
300     * @param off offset into byte array
301     * @param pos offset into blob
302     * @param len length to be written
303     * @return number of bytes written to blob
304     */
305
306    native int read(byte[] b, int off, int pos, int len) throws IOException;
307
308    /**
309     * Destructor for object.
310     */
311
312    protected native void finalize();
313
314    /**
315     * Internal native initializer.
316     */
317
318    private static native void internal_init();
319
320    static {
321    internal_init();
322    }
323}
324