| 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(); |
| } |
| } |