Move Blob's read to an impl of std::io::Read.

This commit is contained in:
John Gallagher 2015-12-14 13:45:44 -05:00
parent 5ac5f3e9b5
commit f290ce11ab

View File

@ -1,4 +1,5 @@
//! incremental BLOB I/O //! incremental BLOB I/O
use std::io;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
@ -81,35 +82,6 @@ impl<'conn> Blob<'conn> {
unsafe { ffi::sqlite3_blob_bytes(self.blob) } 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<i32> {
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 /// 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. /// 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<usize> {
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)] #[allow(unused_must_use)]
impl<'conn> Drop for Blob<'conn> { impl<'conn> Drop for Blob<'conn> {
fn drop(&mut self) { fn drop(&mut self) {
@ -179,6 +182,7 @@ impl<'conn> Drop for Blob<'conn> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::io::Read;
use {Connection, DatabaseName}; use {Connection, DatabaseName};
#[test] #[test]