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