diff --git a/src/blob.rs b/src/blob.rs index 2227045..a344450 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -1,4 +1,5 @@ //! incremental BLOB I/O +use std::io; use std::mem; use std::ptr; @@ -81,35 +82,6 @@ impl<'conn> Blob<'conn> { unsafe { ffi::sqlite3_blob_bytes(self.blob) } } - /// Read data from a BLOB incrementally - /// - /// # Failure - /// - /// Will return `Err` if `buf` length > i32 max value or if the underlying SQLite read call fails. - pub fn read(&mut self, buf: &mut [u8]) -> Result { - if buf.len() > ::std::i32::MAX as usize { - return Err(Error { - code: ffi::SQLITE_TOOBIG, - message: "buffer too long".to_string(), - }); - } - let mut n = buf.len() as i32; - let size = self.size(); - if self.pos + n > size { - n = size - self.pos; - } - if n <= 0 { - return Ok(0); - } - let rc = unsafe { - ffi::sqlite3_blob_read(self.blob, mem::transmute(buf.as_ptr()), n, self.pos) - }; - self.conn.decode_result(rc).map(|_| { - self.pos += n; - n - }) - } - /// Write data into a BLOB incrementally /// /// This function may only modify the contents of the BLOB; it is not possible to increase the size of a BLOB using this API. @@ -170,6 +142,37 @@ impl<'conn> Blob<'conn> { } } +impl<'conn> io::Read for Blob<'conn> { + /// Read data from a BLOB incrementally + /// + /// # Failure + /// + /// Will return `Err` if `buf` length > i32 max value or if the underlying SQLite read call fails. + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if buf.len() > ::std::i32::MAX as usize { + return Err(io::Error::new(io::ErrorKind::InvalidInput, Error { + code: ffi::SQLITE_TOOBIG, + message: "buffer too long".to_string(), + })); + } + let mut n = buf.len() as i32; + let size = self.size(); + if self.pos + n > size { + n = size - self.pos; + } + if n <= 0 { + return Ok(0); + } + let rc = unsafe { + ffi::sqlite3_blob_read(self.blob, mem::transmute(buf.as_ptr()), n, self.pos) + }; + self.conn.decode_result(rc).map(|_| { + self.pos += n; + n as usize + }).map_err(|err| io::Error::new(io::ErrorKind::Other, err)) + } +} + #[allow(unused_must_use)] impl<'conn> Drop for Blob<'conn> { fn drop(&mut self) { @@ -179,6 +182,7 @@ impl<'conn> Drop for Blob<'conn> { #[cfg(test)] mod test { + use std::io::Read; use {Connection, DatabaseName}; #[test]