Implement LuaPlainString for non-UTF-8

Fix #135
master
Michael Pankov 2017-04-15 19:36:05 +03:00
parent 449e3c0b4b
commit 81fcd670c9
2 changed files with 42 additions and 2 deletions

View File

@ -13,6 +13,7 @@ use Void;
#[derive(Clone, Debug, PartialEq)]
pub enum AnyLuaValue {
LuaString(String),
LuaPlainString(Vec<u8>),
LuaNumber(f64),
LuaBoolean(bool),
LuaArray(Vec<(AnyLuaValue, AnyLuaValue)>),
@ -33,6 +34,7 @@ impl<'lua, L> Push<L> for AnyLuaValue
let raw_lua = lua.as_lua();
match self {
AnyLuaValue::LuaString(val) => val.push_to_lua(lua),
AnyLuaValue::LuaPlainString(val) => val.push_to_lua(lua),
AnyLuaValue::LuaNumber(val) => val.push_to_lua(lua),
AnyLuaValue::LuaBoolean(val) => val.push_to_lua(lua),
AnyLuaValue::LuaArray(val) => {
@ -89,6 +91,11 @@ impl<'lua, L> LuaRead<L> for AnyLuaValue
Err(lua) => lua,
};
let lua = match LuaRead::lua_read_at_position(&lua, index) {
Ok(v) => return Ok(AnyLuaValue::LuaPlainString(v)),
Err(lua) => lua,
};
if unsafe { ffi::lua_isnil(lua.as_lua().0, index) } {
return Ok(AnyLuaValue::LuaNil);
}
@ -194,4 +201,17 @@ mod tests {
"x is a Some value when it should be a None value. X: {:?}",
x);
}
#[test]
fn non_utf_8_string() {
let mut lua = Lua::new();
let a = lua.execute::<AnyLuaValue>(r"return '\xff\xfe\xff\xfe'").unwrap();
match a {
AnyLuaValue::LuaPlainString(v) => {
assert_eq!(Vec::from(&b"\xff\xfe\xff\xfe"[..]), v);
},
_ => panic!("Decoded to wrong variant"),
}
}
}

View File

@ -153,9 +153,29 @@ impl<'lua, L> LuaRead<L> for String
}
let c_str = unsafe { CStr::from_ptr(c_str_raw) };
let c_str = String::from_utf8(c_str.to_bytes().to_vec()).unwrap();
let maybe_string = String::from_utf8(c_str.to_bytes().to_vec());
match maybe_string {
Ok(string) => Ok(string),
Err(_) => Err(lua),
}
}
}
Ok(c_str)
impl<'lua, L> LuaRead<L> for Vec<u8>
where L: AsLua<'lua>
{
#[inline]
fn lua_read_at_position(lua: L, index: i32) -> Result<Vec<u8>, L> {
let mut size: libc::size_t = unsafe { mem::uninitialized() };
let c_str_raw = unsafe { ffi::lua_tolstring(lua.as_lua().0, index, &mut size) };
if c_str_raw.is_null() {
return Err(lua);
}
let c_str = unsafe { CStr::from_ptr(c_str_raw) };
let c_string = c_str.to_bytes().to_vec();
Ok(c_string)
}
}