| package SQLite; | |
| import java.io.*; | |
| /** | |
| * Internal class implementing java.io.InputStream on | |
| * SQLite 3.4.0 incremental blob I/O interface. | |
| */ | |
| class BlobR extends InputStream { | |
| /** | |
| * Blob instance | |
| */ | |
| private Blob blob; | |
| /** | |
| * Read position, file pointer. | |
| */ | |
| private int pos; | |
| /** | |
| * Contruct InputStream from blob instance. | |
| */ | |
| BlobR(Blob blob) { | |
| this.blob = blob; | |
| this.pos = 0; | |
| } | |
| /** | |
| * Return number of available bytes for reading. | |
| * @return available input bytes | |
| */ | |
| public int available() throws IOException { | |
| int ret = blob.size - pos; | |
| return (ret < 0) ? 0 : ret; | |
| } | |
| /** | |
| * Mark method; dummy to satisfy InputStream class. | |
| */ | |
| public void mark(int limit) { | |
| } | |
| /** | |
| * Reset method; dummy to satisfy InputStream class. | |
| */ | |
| public void reset() throws IOException { | |
| } | |
| /** | |
| * Mark support; not for this class. | |
| * @return always false | |
| */ | |
| public boolean markSupported() { | |
| return false; | |
| } | |
| /** | |
| * Close this blob InputStream. | |
| */ | |
| public void close() throws IOException { | |
| blob.close(); | |
| blob = null; | |
| pos = 0; | |
| } | |
| /** | |
| * Skip over blob data. | |
| */ | |
| public long skip(long n) throws IOException { | |
| long ret = pos + n; | |
| if (ret < 0) { | |
| ret = 0; | |
| pos = 0; | |
| } else if (ret > blob.size) { | |
| ret = blob.size; | |
| pos = blob.size; | |
| } else { | |
| pos = (int) ret; | |
| } | |
| return ret; | |
| } | |
| /** | |
| * Read single byte from blob. | |
| * @return byte read | |
| */ | |
| public int read() throws IOException { | |
| byte b[] = new byte[1]; | |
| int n = blob.read(b, 0, pos, b.length); | |
| if (n > 0) { | |
| pos += n; | |
| return b[0]; | |
| } | |
| return -1; | |
| } | |
| /** | |
| * Read byte array from blob. | |
| * @param b byte array to be filled | |
| * @return number of bytes read | |
| */ | |
| public int read(byte b[]) throws IOException { | |
| int n = blob.read(b, 0, pos, b.length); | |
| if (n > 0) { | |
| pos += n; | |
| return n; | |
| } | |
| return -1; | |
| } | |
| /** | |
| * Read slice of byte array from blob. | |
| * @param b byte array to be filled | |
| * @param off offset into byte array | |
| * @param len length to be read | |
| * @return number of bytes read | |
| */ | |
| public int read(byte b[], int off, int len) throws IOException { | |
| if (off + len > b.length) { | |
| len = b.length - off; | |
| } | |
| if (len < 0) { | |
| return -1; | |
| } | |
| if (len == 0) { | |
| return 0; | |
| } | |
| int n = blob.read(b, off, pos, len); | |
| if (n > 0) { | |
| pos += n; | |
| return n; | |
| } | |
| return -1; | |
| } | |
| } | |
| /** | |
| * Internal class implementing java.io.OutputStream on | |
| * SQLite 3.4.0 incremental blob I/O interface. | |
| */ | |
| class BlobW extends OutputStream { | |
| /** | |
| * Blob instance | |
| */ | |
| private Blob blob; | |
| /** | |
| * Read position, file pointer. | |
| */ | |
| private int pos; | |
| /** | |
| * Contruct OutputStream from blob instance. | |
| */ | |
| BlobW(Blob blob) { | |
| this.blob = blob; | |
| this.pos = 0; | |
| } | |
| /** | |
| * Flush blob; dummy to satisfy OutputStream class. | |
| */ | |
| public void flush() throws IOException { | |
| } | |
| /** | |
| * Close this blob OutputStream. | |
| */ | |
| public void close() throws IOException { | |
| blob.close(); | |
| blob = null; | |
| pos = 0; | |
| } | |
| /** | |
| * Write blob data. | |
| * @param v byte to be written at current position. | |
| */ | |
| public void write(int v) throws IOException { | |
| byte b[] = new byte[1]; | |
| b[0] = (byte) v; | |
| pos += blob.write(b, 0, pos, 1); | |
| } | |
| /** | |
| * Write blob data. | |
| * @param b byte array to be written at current position. | |
| */ | |
| public void write(byte[] b) throws IOException { | |
| if (b != null && b.length > 0) { | |
| pos += blob.write(b, 0, pos, b.length); | |
| } | |
| } | |
| /** | |
| * Write blob data. | |
| * @param b byte array to be written. | |
| * @param off offset within byte array | |
| * @param len length of data to be written | |
| */ | |
| public void write(byte[] b, int off, int len) throws IOException { | |
| if (b != null) { | |
| if (off + len > b.length) { | |
| len = b.length - off; | |
| } | |
| if (len <= 0) { | |
| return; | |
| } | |
| pos += blob.write(b, off, pos, len); | |
| } | |
| } | |
| } | |
| /** | |
| * Class to represent SQLite3 3.4.0 incremental blob I/O interface. | |
| * | |
| * Note, that all native methods of this class are | |
| * not synchronized, i.e. it is up to the caller | |
| * to ensure that only one thread is in these | |
| * methods at any one time. | |
| */ | |
| public class Blob { | |
| /** | |
| * Internal handle for the SQLite3 blob. | |
| */ | |
| private long handle = 0; | |
| /** | |
| * Cached size of blob, setup right after blob | |
| * has been opened. | |
| */ | |
| protected int size = 0; | |
| /** | |
| * Return InputStream for this blob | |
| * @return InputStream | |
| */ | |
| public InputStream getInputStream() { | |
| return (InputStream) new BlobR(this); | |
| } | |
| /** | |
| * Return OutputStream for this blob | |
| * @return OutputStream | |
| */ | |
| public OutputStream getOutputStream() { | |
| return (OutputStream) new BlobW(this); | |
| } | |
| /** | |
| * Close blob. | |
| */ | |
| public native void close(); | |
| /** | |
| * Internal blob write method. | |
| * @param b byte array to be written | |
| * @param off offset into byte array | |
| * @param pos offset into blob | |
| * @param len length to be written | |
| * @return number of bytes written to blob | |
| */ | |
| native int write(byte[] b, int off, int pos, int len) throws IOException; | |
| /** | |
| * Internal blob read method. | |
| * @param b byte array to be written | |
| * @param off offset into byte array | |
| * @param pos offset into blob | |
| * @param len length to be written | |
| * @return number of bytes written to blob | |
| */ | |
| native int read(byte[] b, int off, int pos, int len) throws IOException; | |
| /** | |
| * Destructor for object. | |
| */ | |
| protected native void finalize(); | |
| /** | |
| * Internal native initializer. | |
| */ | |
| private static native void internal_init(); | |
| static { | |
| internal_init(); | |
| } | |
| } |