Update for rust's std::c_str -> std::ffi

This commit is contained in:
John Gallagher 2015-01-07 14:05:36 -05:00
parent b69e3d083d
commit e02442c531
2 changed files with 31 additions and 22 deletions

View File

@ -56,7 +56,9 @@ use std::ptr;
use std::fmt; use std::fmt;
use std::rc::{Rc}; use std::rc::{Rc};
use std::cell::{RefCell, Cell}; use std::cell::{RefCell, Cell};
use std::c_str::{CString, ToCStr}; use std::ffi::{CString};
use std::ffi as std_ffi;
use std::str;
use libc::{c_int, c_void, c_char}; use libc::{c_int, c_void, c_char};
use types::{ToSql, FromSql}; use types::{ToSql, FromSql};
@ -77,8 +79,9 @@ mod transaction;
pub type SqliteResult<T> = Result<T, SqliteError>; pub type SqliteResult<T> = Result<T, SqliteError>;
unsafe fn errmsg_to_string(errmsg: *const c_char) -> String { unsafe fn errmsg_to_string(errmsg: *const c_char) -> String {
let c_str = CString::new(errmsg, false); let c_slice = std_ffi::c_str_to_bytes(&errmsg);
c_str.as_str().unwrap_or("Invalid error message encoding").to_string() let utf8_str = str::from_utf8(c_slice);
utf8_str.unwrap_or("Invalid string encoding").to_string()
} }
/// Encompasses an error result from a call to the SQLite C API. /// Encompasses an error result from a call to the SQLite C API.
@ -311,9 +314,10 @@ bitflags! {
impl InnerSqliteConnection { impl InnerSqliteConnection {
fn open_with_flags(path: &str, flags: SqliteOpenFlags) -> SqliteResult<InnerSqliteConnection> { fn open_with_flags(path: &str, flags: SqliteOpenFlags) -> SqliteResult<InnerSqliteConnection> {
path.with_c_str(|c_path| unsafe { let c_path = CString::from_slice(path.as_bytes());
unsafe {
let mut db: *mut ffi::sqlite3 = mem::uninitialized(); let mut db: *mut ffi::sqlite3 = mem::uninitialized();
let r = ffi::sqlite3_open_v2(c_path, &mut db, flags.bits(), ptr::null()); let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), ptr::null());
if r != ffi::SQLITE_OK { if r != ffi::SQLITE_OK {
let e = if db.is_null() { let e = if db.is_null() {
SqliteError{ code: r, SqliteError{ code: r,
@ -333,7 +337,7 @@ impl InnerSqliteConnection {
return Err(e); return Err(e);
} }
Ok(InnerSqliteConnection{ db: db }) Ok(InnerSqliteConnection{ db: db })
}) }
} }
fn decode_result(&mut self, code: c_int) -> SqliteResult<()> { fn decode_result(&mut self, code: c_int) -> SqliteResult<()> {
@ -351,9 +355,10 @@ impl InnerSqliteConnection {
} }
fn execute_batch(&mut self, sql: &str) -> SqliteResult<()> { fn execute_batch(&mut self, sql: &str) -> SqliteResult<()> {
sql.with_c_str(|c_sql| unsafe { let c_sql = CString::from_slice(sql.as_bytes());
unsafe {
let mut errmsg: *mut c_char = mem::uninitialized(); let mut errmsg: *mut c_char = mem::uninitialized();
let r = ffi::sqlite3_exec(self.db, c_sql, None, ptr::null_mut(), &mut errmsg); let r = ffi::sqlite3_exec(self.db, c_sql.as_ptr(), None, ptr::null_mut(), &mut errmsg);
if r == ffi::SQLITE_OK { if r == ffi::SQLITE_OK {
Ok(()) Ok(())
} else { } else {
@ -361,7 +366,7 @@ impl InnerSqliteConnection {
ffi::sqlite3_free(errmsg as *mut c_void); ffi::sqlite3_free(errmsg as *mut c_void);
Err(SqliteError{ code: r, message: message }) Err(SqliteError{ code: r, message: message })
} }
}) }
} }
fn last_insert_rowid(&self) -> i64 { fn last_insert_rowid(&self) -> i64 {
@ -374,10 +379,12 @@ impl InnerSqliteConnection {
conn: &'a SqliteConnection, conn: &'a SqliteConnection,
sql: &str) -> SqliteResult<SqliteStatement<'a>> { sql: &str) -> SqliteResult<SqliteStatement<'a>> {
let mut c_stmt: *mut ffi::sqlite3_stmt = unsafe { mem::uninitialized() }; let mut c_stmt: *mut ffi::sqlite3_stmt = unsafe { mem::uninitialized() };
let r = sql.with_c_str(|c_sql| unsafe { let c_sql = CString::from_slice(sql.as_bytes());
let r = unsafe {
let len_with_nul = (sql.len() + 1) as c_int; let len_with_nul = (sql.len() + 1) as c_int;
ffi::sqlite3_prepare_v2(self.db, c_sql, len_with_nul, &mut c_stmt, ptr::null_mut()) ffi::sqlite3_prepare_v2(self.db, c_sql.as_ptr(), len_with_nul, &mut c_stmt,
}); ptr::null_mut())
};
self.decode_result(r).map(|_| { self.decode_result(r).map(|_| {
SqliteStatement::new(conn, c_stmt) SqliteStatement::new(conn, c_stmt)
}) })

View File

@ -54,9 +54,11 @@
extern crate time; extern crate time;
use libc::{c_int, c_double}; use libc::{c_int, c_double, c_char};
use std::c_str::{CString, ToCStr}; use std::ffi as std_ffi;
use std::ffi::{CString};
use std::mem; use std::mem;
use std::str;
use super::ffi; use super::ffi;
use super::{SqliteResult, SqliteError}; use super::{SqliteResult, SqliteError};
@ -88,9 +90,8 @@ raw_to_impl!(c_double, sqlite3_bind_double);
impl<'a> ToSql for &'a str { impl<'a> ToSql for &'a str {
unsafe fn bind_parameter(&self, stmt: *mut ffi::sqlite3_stmt, col: c_int) -> c_int { unsafe fn bind_parameter(&self, stmt: *mut ffi::sqlite3_stmt, col: c_int) -> c_int {
self.with_c_str(|c_str| { let c_str = CString::from_slice(self.as_bytes());
ffi::sqlite3_bind_text(stmt, col, c_str, -1, Some(ffi::SQLITE_TRANSIENT())) ffi::sqlite3_bind_text(stmt, col, c_str.as_ptr(), -1, Some(ffi::SQLITE_TRANSIENT()))
})
} }
} }
@ -170,11 +171,12 @@ impl FromSql for String {
if c_text.is_null() { if c_text.is_null() {
Ok("".to_string()) Ok("".to_string())
} else { } else {
match CString::new(mem::transmute(c_text), false).as_str() { let c_text = c_text as *const c_char;
Some(s) => Ok(s.to_string()), let c_slice = std_ffi::c_str_to_bytes(&c_text);
None => Err(SqliteError{ code: ffi::SQLITE_MISMATCH, let utf8_str = str::from_utf8(c_slice);
message: "Could not convert text to UTF-8".to_string() }) utf8_str
} .map(|s| { s.to_string() })
.map_err(|e| { SqliteError{code: 0, message: e.to_string()} })
} }
} }
} }