summaryrefslogtreecommitdiffstats
path: root/sqlite-jdbc/src/main/java/SQLite/Blob.java
diff options
context:
space:
mode:
Diffstat (limited to 'sqlite-jdbc/src/main/java/SQLite/Blob.java')
-rw-r--r--sqlite-jdbc/src/main/java/SQLite/Blob.java323
1 files changed, 323 insertions, 0 deletions
diff --git a/sqlite-jdbc/src/main/java/SQLite/Blob.java b/sqlite-jdbc/src/main/java/SQLite/Blob.java
new file mode 100644
index 0000000..3de9f8a
--- /dev/null
+++ b/sqlite-jdbc/src/main/java/SQLite/Blob.java
@@ -0,0 +1,323 @@
+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();
+ }
+}