mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 13:58:55 +08:00 
			
		
		
		
	Move Blob's read to an impl of std::io::Read.
				
					
				
			This commit is contained in:
		
							
								
								
									
										62
									
								
								src/blob.rs
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								src/blob.rs
									
									
									
									
									
								
							| @@ -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] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user