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