mirror of
https://github.com/encounter/rust-sdl2.git
synced 2026-07-10 21:18:41 -07:00
Fix up CString interop
Working with `*const c_char` now works as follows: * Call `c_str_to_bytes(*const char)` helper function to get a slice of data w/o the null terminator. (`&'a [u8]`) * Use that slice of data to construct a standard `String` using the checked, unchecked, or lossy UTF-8 conversion methods. --- CString now only exists to go the other way (from String -> CString). It simply adds the invariants that the string contains no interior NULL bytes and has a null-terminator.
This commit is contained in:
+11
-11
@@ -1,7 +1,7 @@
|
||||
//! Audio Functions
|
||||
use std::ptr;
|
||||
use std::mem;
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
use std::borrow::ToOwned;
|
||||
use std::num::FromPrimitive;
|
||||
use libc;
|
||||
@@ -50,8 +50,8 @@ pub fn get_num_audio_drivers() -> int {
|
||||
|
||||
pub fn get_audio_driver(index: int) -> String {
|
||||
unsafe {
|
||||
let buf = ll::SDL_GetAudioDriver(index as c_int);
|
||||
CString::new(buf, false).as_str().unwrap().to_owned()
|
||||
let driver = ll::SDL_GetAudioDriver(index as c_int);
|
||||
String::from_utf8_lossy(c_str_to_bytes(&driver)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,15 +61,15 @@ pub fn get_num_audio_devices(iscapture: int) -> int {
|
||||
|
||||
pub fn get_audio_device_name(index: int, iscapture: int) -> String {
|
||||
unsafe {
|
||||
let buf = ll::SDL_GetAudioDeviceName(index as c_int, iscapture as c_int);
|
||||
CString::new(buf, false).as_str().unwrap().to_owned()
|
||||
let dev_name = ll::SDL_GetAudioDeviceName(index as c_int, iscapture as c_int);
|
||||
String::from_utf8_lossy(c_str_to_bytes(&dev_name)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn audio_init(name: &str) -> SdlResult<()> {
|
||||
let ret = name.with_c_str(|buf| {
|
||||
unsafe { ll::SDL_AudioInit(buf) }
|
||||
});
|
||||
let buf = CString::from_slice(name.as_bytes()).as_ptr();
|
||||
let ret = unsafe { ll::SDL_AudioInit(buf) };
|
||||
|
||||
if ret == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
@@ -83,8 +83,8 @@ pub fn audio_quit() {
|
||||
|
||||
pub fn get_current_audio_driver() -> String {
|
||||
unsafe {
|
||||
let buf = ll::SDL_GetCurrentAudioDriver();
|
||||
CString::new(buf, false).as_str().unwrap().to_owned()
|
||||
let driver = ll::SDL_GetCurrentAudioDriver();
|
||||
String::from_utf8_lossy(c_str_to_bytes(&driver)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ impl<T: AudioFormatNum<T>, CB: AudioCallback<T>> AudioSpecDesired<T, CB> {
|
||||
unsafe {
|
||||
let device_cstr: Option<CString> = match device {
|
||||
None => None,
|
||||
Some(d) => Some(d.to_c_str())
|
||||
Some(d) => Some(CString::from_slice(d.as_bytes()))
|
||||
};
|
||||
let device_cstr_ptr: *const c_char = match device_cstr {
|
||||
None => null(),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::ffi::CString;
|
||||
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
use SdlResult;
|
||||
use get_error;
|
||||
|
||||
@@ -7,9 +6,8 @@ pub use sys::clipboard as ll;
|
||||
|
||||
pub fn set_clipboard_text(text: &String) -> SdlResult<()> {
|
||||
unsafe {
|
||||
let result = text.with_c_str(|buff| {
|
||||
ll::SDL_SetClipboardText(buff)
|
||||
});
|
||||
let buff = CString::from_slice(text.as_slice().as_bytes());
|
||||
let result = ll::SDL_SetClipboardText(buff.as_ptr());
|
||||
|
||||
if result == 0 {
|
||||
Err(get_error())
|
||||
@@ -21,8 +19,8 @@ pub fn set_clipboard_text(text: &String) -> SdlResult<()> {
|
||||
|
||||
pub fn get_clipboard_text() -> SdlResult<String> {
|
||||
let result = unsafe {
|
||||
let cstr = ll::SDL_GetClipboardText() as *const u8;
|
||||
String::from_raw_buf(cstr)
|
||||
let buf = ll::SDL_GetClipboardText();
|
||||
String::from_utf8_lossy(c_str_to_bytes(&buf)).to_string()
|
||||
};
|
||||
|
||||
if result.len() == 0 {
|
||||
|
||||
+3
-1
@@ -2,6 +2,7 @@
|
||||
Event Handling
|
||||
*/
|
||||
|
||||
use std::ffi::{c_str_to_bytes};
|
||||
use std::mem;
|
||||
use libc::{c_int, c_void, uint32_t};
|
||||
use std::num::FromPrimitive;
|
||||
@@ -592,7 +593,8 @@ impl Event {
|
||||
EventType::DropFile => {
|
||||
let ref event = *raw.drop();
|
||||
|
||||
let text = String::from_raw_buf(event.file as *const u8);
|
||||
let buf = c_str_to_bytes(&event.file);
|
||||
let text = String::from_utf8_lossy(buf).to_string();
|
||||
ll::SDL_free(event.file as *const c_void);
|
||||
|
||||
Event::DropFile(event.timestamp as uint, text)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
use SdlResult;
|
||||
use get_error;
|
||||
|
||||
@@ -6,8 +6,8 @@ pub use sys::filesystem as ll;
|
||||
|
||||
pub fn get_base_path() -> SdlResult<String> {
|
||||
let result = unsafe {
|
||||
let cstr = ll::SDL_GetBasePath();
|
||||
String::from_raw_buf(cstr as *const u8)
|
||||
let buf = ll::SDL_GetBasePath();
|
||||
String::from_utf8_lossy(c_str_to_bytes(&buf)).to_string()
|
||||
};
|
||||
|
||||
if result.len() == 0 {
|
||||
@@ -19,12 +19,10 @@ pub fn get_base_path() -> SdlResult<String> {
|
||||
|
||||
pub fn get_pref_path(org: &str, app: &str) -> SdlResult<String> {
|
||||
let result = unsafe {
|
||||
let cstr =
|
||||
org.with_c_str(|org_cstr| {
|
||||
app.with_c_str(|app_cstr| {
|
||||
ll::SDL_GetPrefPath(org_cstr, app_cstr)
|
||||
})});
|
||||
String::from_raw_buf(cstr as *const u8)
|
||||
let org_cstr = CString::from_slice(org.as_bytes()).as_ptr();
|
||||
let app_cstr = CString::from_slice(app.as_bytes()).as_ptr();
|
||||
let buf = ll::SDL_GetPrefPath(org_cstr, app_cstr);
|
||||
String::from_utf8_lossy(c_str_to_bytes(&buf)).to_string()
|
||||
};
|
||||
|
||||
if result.len() == 0 {
|
||||
|
||||
+10
-12
@@ -1,5 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
use std::num::FromPrimitive;
|
||||
use std::ptr;
|
||||
|
||||
@@ -80,32 +80,30 @@ pub fn get_scancode_from_key(key: KeyCode) -> ScanCode {
|
||||
pub fn get_scancode_name(scancode: ScanCode) -> String {
|
||||
unsafe {
|
||||
let scancode_name = ll::SDL_GetScancodeName(scancode as u32);
|
||||
String::from_raw_buf(scancode_name as *const u8)
|
||||
String::from_utf8_lossy(c_str_to_bytes(&scancode_name)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_scancode_from_name(name: &str) -> ScanCode {
|
||||
unsafe {
|
||||
name.with_c_str(|name| {
|
||||
FromPrimitive::from_int(ll::SDL_GetScancodeFromName(name) as int)
|
||||
.unwrap_or(ScanCode::Unknown)
|
||||
})
|
||||
}
|
||||
let name = CString::from_slice(name.as_bytes()).as_ptr();
|
||||
FromPrimitive::from_int(ll::SDL_GetScancodeFromName(name) as int)
|
||||
.unwrap_or(ScanCode::Unknown)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_key_name(key: KeyCode) -> String {
|
||||
unsafe {
|
||||
let key_name = ll::SDL_GetKeyName(key as i32);
|
||||
String::from_raw_buf(key_name as *const u8)
|
||||
String::from_utf8_lossy(c_str_to_bytes(&key_name)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_key_from_name(name: &str) -> KeyCode {
|
||||
unsafe {
|
||||
name.with_c_str(|name| {
|
||||
FromPrimitive::from_int(ll::SDL_GetKeyFromName(name) as int)
|
||||
.unwrap_or(KeyCode::Unknown)
|
||||
})
|
||||
let name = CString::from_slice(name.as_bytes()).as_ptr();
|
||||
FromPrimitive::from_int(ll::SDL_GetKeyFromName(name) as int)
|
||||
.unwrap_or(KeyCode::Unknown)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,12 @@ bitflags! {
|
||||
|
||||
pub fn show_simple_message_box(flags: MessageBoxFlag, title: &str, message: &str, window: Option<&Window>) -> SdlResult<()> {
|
||||
let result = unsafe {
|
||||
title.with_c_str(|title_cstr| {
|
||||
message.with_c_str(|message_cstr| {
|
||||
ll::SDL_ShowSimpleMessageBox(flags.bits(), title_cstr, message_cstr, window.map_or(ptr::null(), |win| win.raw()))
|
||||
})
|
||||
})
|
||||
let title_cstr = CString::from_slice(title.as_bytes()).as_ptr();
|
||||
let message_cstr = CString::from_slice(message.as_bytes()).as_ptr();
|
||||
ll::SDL_ShowSimpleMessageBox(flags.bits(),
|
||||
title_cstr,
|
||||
message_cstr,
|
||||
window.map_or(ptr::null(), |win| win.raw()))
|
||||
} == 0;
|
||||
|
||||
if result {
|
||||
|
||||
+3
-1
@@ -8,8 +8,10 @@ use SdlResult;
|
||||
use std::ptr;
|
||||
use libc;
|
||||
use libc::{c_int, uint32_t, c_float, c_double, c_void, size_t};
|
||||
use ::c_vec::CVec;
|
||||
use rect::Point;
|
||||
use rect::Rect;
|
||||
use std::ffi::c_str_to_bytes;
|
||||
use std::num::FromPrimitive;
|
||||
use std::vec::Vec;
|
||||
use std::borrow::ToOwned;
|
||||
@@ -72,7 +74,7 @@ impl RendererInfo {
|
||||
}).collect();
|
||||
|
||||
RendererInfo {
|
||||
name: String::from_raw_buf(info.name as *const _),
|
||||
name: String::from_utf8_lossy(c_str_to_bytes(&info.name)).to_string(),
|
||||
flags: actual_flags,
|
||||
texture_formats: texture_formats,
|
||||
max_texture_width: info.max_texture_width as int,
|
||||
|
||||
+3
-1
@@ -20,7 +20,9 @@ impl_owned_accessors!(RWops, close_on_drop);
|
||||
impl RWops {
|
||||
pub fn from_file(path: &Path, mode: &str) -> SdlResult<RWops> {
|
||||
let raw = unsafe {
|
||||
ll::SDL_RWFromFile(CString::from_slice(path), CString::from_slice(mode))
|
||||
let path_c = CString::from_slice(path.as_vec()).as_ptr();
|
||||
let mode_c = CString::from_slice(mode.as_bytes()).as_ptr();
|
||||
ll::SDL_RWFromFile(path_c, mode_c)
|
||||
};
|
||||
if raw.is_null() { Err(get_error()) }
|
||||
else { Ok(RWops{raw: raw, close_on_drop: true}) }
|
||||
|
||||
+5
-7
@@ -1,5 +1,4 @@
|
||||
use std::borrow::ToOwned;
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
|
||||
use sys::sdl as ll;
|
||||
|
||||
@@ -57,15 +56,14 @@ pub fn was_inited(flags: InitFlag) -> InitFlag {
|
||||
|
||||
pub fn get_error() -> String {
|
||||
unsafe {
|
||||
let cstr = CString::new(ll::SDL_GetError(), false);
|
||||
cstr.as_str().unwrap().to_owned()
|
||||
let err = ll::SDL_GetError();
|
||||
String::from_utf8_lossy(c_str_to_bytes(&err)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_error(err: &str) {
|
||||
err.with_c_str(|buf| {
|
||||
unsafe { ll::SDL_SetError(buf); }
|
||||
})
|
||||
let buf = CString::from_slice(err.as_bytes()).as_ptr();
|
||||
unsafe { ll::SDL_SetError(buf); }
|
||||
}
|
||||
|
||||
pub fn set_error_from_code(err: Error) {
|
||||
|
||||
+3
-4
@@ -2,9 +2,8 @@
|
||||
Querying SDL Version
|
||||
*/
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::ffi::c_str_to_bytes;
|
||||
use std::fmt;
|
||||
use std::borrow::ToOwned;
|
||||
|
||||
pub use sys::version as ll;
|
||||
|
||||
@@ -47,8 +46,8 @@ pub fn get_version() -> Version {
|
||||
/// Get the code revision of SDL that is linked against your program.
|
||||
pub fn get_revision() -> String {
|
||||
unsafe {
|
||||
let ret = ll::SDL_GetRevision();
|
||||
CString::new(ret, false).as_str().unwrap().to_owned()
|
||||
let rev = ll::SDL_GetRevision();
|
||||
String::from_utf8_lossy(c_str_to_bytes(&rev)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-32
@@ -1,5 +1,5 @@
|
||||
use libc::{c_int, c_float, uint32_t};
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{c_str_to_bytes, CString};
|
||||
use std::ptr;
|
||||
use std::vec::Vec;
|
||||
|
||||
@@ -190,16 +190,15 @@ impl Drop for Window {
|
||||
impl Window {
|
||||
pub fn new(title: &str, x: WindowPos, y: WindowPos, width: int, height: int, window_flags: WindowFlags) -> SdlResult<Window> {
|
||||
unsafe {
|
||||
let raw = title.with_c_str(|buff| {
|
||||
ll::SDL_CreateWindow(
|
||||
let buff = CString::from_slice(title.as_bytes()).as_ptr();
|
||||
let raw = ll::SDL_CreateWindow(
|
||||
buff,
|
||||
unwrap_windowpos(x),
|
||||
unwrap_windowpos(y),
|
||||
width as c_int,
|
||||
height as c_int,
|
||||
window_flags.bits()
|
||||
)
|
||||
});
|
||||
);
|
||||
|
||||
if raw == ptr::null() {
|
||||
Err(get_error())
|
||||
@@ -272,15 +271,14 @@ impl Window {
|
||||
}
|
||||
|
||||
pub fn set_title(&self, title: &str) {
|
||||
title.with_c_str(|buff| {
|
||||
unsafe { ll::SDL_SetWindowTitle(self.raw, buff) }
|
||||
})
|
||||
let buff = CString::from_slice(title.as_bytes()).as_ptr();
|
||||
unsafe { ll::SDL_SetWindowTitle(self.raw, buff) }
|
||||
}
|
||||
|
||||
pub fn get_title(&self) -> String {
|
||||
unsafe {
|
||||
let cstr = ll::SDL_GetWindowTitle(self.raw);
|
||||
String::from_raw_buf(cstr as *const _)
|
||||
let buf = ll::SDL_GetWindowTitle(self.raw);
|
||||
String::from_utf8_lossy(c_str_to_bytes(&buf)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,15 +465,14 @@ pub fn get_num_video_drivers() -> SdlResult<int> {
|
||||
|
||||
pub fn get_video_driver(id: int) -> String {
|
||||
unsafe {
|
||||
let cstr = ll::SDL_GetVideoDriver(id as c_int);
|
||||
String::from_raw_buf(cstr as *const _)
|
||||
let buf = ll::SDL_GetVideoDriver(id as c_int);
|
||||
String::from_utf8_lossy(c_str_to_bytes(&buf)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn video_init(name: &str) -> bool {
|
||||
name.with_c_str(|buf| {
|
||||
unsafe { ll::SDL_VideoInit(buf) == 0 }
|
||||
})
|
||||
let buf = CString::from_slice(name.as_bytes()).as_ptr();
|
||||
unsafe { ll::SDL_VideoInit(buf) == 0 }
|
||||
}
|
||||
|
||||
pub fn video_quit() {
|
||||
@@ -484,8 +481,8 @@ pub fn video_quit() {
|
||||
|
||||
pub fn get_current_video_driver() -> String {
|
||||
unsafe {
|
||||
let cstr = ll::SDL_GetCurrentVideoDriver();
|
||||
String::from_raw_buf(cstr as *const _)
|
||||
let video = ll::SDL_GetCurrentVideoDriver();
|
||||
String::from_utf8_lossy(c_str_to_bytes(&video)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,8 +497,8 @@ pub fn get_num_video_displays() -> SdlResult<int> {
|
||||
|
||||
pub fn get_display_name(display_index: int) -> String {
|
||||
unsafe {
|
||||
let cstr = ll::SDL_GetDisplayName(display_index as c_int);
|
||||
String::from_raw_buf(cstr as *const _)
|
||||
let display = ll::SDL_GetDisplayName(display_index as c_int);
|
||||
String::from_utf8_lossy(c_str_to_bytes(&display)).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,13 +582,13 @@ pub fn disable_screen_saver() {
|
||||
|
||||
pub fn gl_load_library(path: &str) -> SdlResult<()> {
|
||||
unsafe {
|
||||
path.with_c_str(|path| {
|
||||
if ll::SDL_GL_LoadLibrary(path) == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(get_error())
|
||||
}
|
||||
})
|
||||
let path = CString::from_slice(path.as_bytes()).as_ptr();
|
||||
|
||||
if ll::SDL_GL_LoadLibrary(path) == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(get_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,16 +598,14 @@ pub fn gl_unload_library() {
|
||||
|
||||
pub fn gl_get_proc_address(procname: &str) -> Option<extern "system" fn()> {
|
||||
unsafe {
|
||||
procname.with_c_str(|procname| {
|
||||
ll::SDL_GL_GetProcAddress(procname)
|
||||
})
|
||||
let procname = CString::from_slice(procname.as_bytes()).as_ptr();
|
||||
ll::SDL_GL_GetProcAddress(procname)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gl_extension_supported(extension: &str) -> bool {
|
||||
extension.with_c_str(|buff| {
|
||||
unsafe { ll::SDL_GL_ExtensionSupported(buff) == 1 }
|
||||
})
|
||||
let buff = CString::from_slice(extension.as_bytes()).as_ptr();
|
||||
unsafe { ll::SDL_GL_ExtensionSupported(buff) == 1 }
|
||||
}
|
||||
|
||||
pub fn gl_set_attribute(attr: GLAttr, value: int) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user