Remove support for PropList data nodes.
This type of PropList entry appears to be completely unused, so let's be rid of it. This can be reversed in the future if we do want more complete support for property lists, but for now it's code that we don't need.
This commit is contained in:
@@ -732,10 +732,6 @@ WMPropList* WMCreatePLArray(WMPropList *elem, ...);
|
||||
|
||||
WMPropList* WMCreatePLString(const char *str);
|
||||
|
||||
WMPropList* WMCreatePLData(WMData *data);
|
||||
|
||||
WMPropList* WMCreatePLDataWithBytes(const unsigned char *bytes, unsigned int length);
|
||||
|
||||
WMPropList* WMCreatePLArrayFromSlice(WMPropList *elems, unsigned int length);
|
||||
|
||||
WMPropList* WMCreateEmptyPLArray();
|
||||
@@ -780,8 +776,6 @@ int WMGetPropListItemCount(WMPropList *plist);
|
||||
|
||||
Bool WMIsPLString(WMPropList *plist);
|
||||
|
||||
Bool WMIsPLData(WMPropList *plist);
|
||||
|
||||
Bool WMIsPLArray(WMPropList *plist);
|
||||
|
||||
Bool WMIsPLDictionary(WMPropList *plist);
|
||||
|
||||
@@ -49,8 +49,6 @@ pub enum Node {
|
||||
/// It would be better for this to be a `String`, but the C interface
|
||||
/// requires borrows of C-style strings.
|
||||
String(CString),
|
||||
/// Binary data.
|
||||
Data(Vec<u8>),
|
||||
/// Array of child `PropList`s.
|
||||
Array(Vec<PropList>),
|
||||
/// `PropList`-keyed table of child `PropList`s. Keys should only have
|
||||
@@ -63,7 +61,6 @@ impl hash::Hash for Node {
|
||||
fn hash<H: hash::Hasher>(&self, h: &mut H) {
|
||||
match self {
|
||||
Node::String(s) => s.hash(h),
|
||||
Node::Data(d) => d.hash(h),
|
||||
Node::Array(a) => {
|
||||
for p in a {
|
||||
p.hash(h);
|
||||
@@ -313,7 +310,6 @@ impl PropList {
|
||||
pub fn deep_clone(&self) -> Self {
|
||||
match &*self.0.borrow() {
|
||||
Node::String(s) => PropList::new(Node::String(s.clone())),
|
||||
Node::Data(d) => PropList::new(Node::Data(d.clone())),
|
||||
Node::Array(items) => {
|
||||
PropList::new(Node::Array(items.iter().map(|x| x.deep_clone()).collect()))
|
||||
}
|
||||
@@ -357,14 +353,14 @@ impl PropList {
|
||||
}
|
||||
|
||||
pub mod ffi {
|
||||
use crate::{data::Data, find_file::path_from_cstr, memory};
|
||||
use crate::{find_file::path_from_cstr, memory};
|
||||
|
||||
use super::{
|
||||
merge_deep, merge_shallow, parser, subtract_deep, subtract_shallow, Node, PropList,
|
||||
};
|
||||
|
||||
use std::{
|
||||
collections::HashMap, ffi::{c_char, c_int, c_uchar, c_uint, CStr, CString, OsString}, ptr, str::FromStr
|
||||
collections::HashMap, ffi::{c_char, c_int, c_uint, CStr, CString, OsString}, ptr, str::FromStr
|
||||
};
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -376,27 +372,6 @@ pub mod ffi {
|
||||
Box::leak(Box::new(PropList::new(Node::String(s.into()))))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn WMCreatePLData(data: *mut Data) -> *mut PropList {
|
||||
if data.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
let data = unsafe { &*data };
|
||||
data.with_bytes(|b| Box::leak(Box::new(PropList::new(Node::Data(Vec::from(b))))))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn WMCreatePLDataWithBytes(
|
||||
bytes: *const c_uchar,
|
||||
length: c_uint,
|
||||
) -> *mut PropList {
|
||||
if bytes.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
let bytes = unsafe { &*ptr::slice_from_raw_parts(bytes.cast::<u8>(), length as usize) };
|
||||
Box::leak(Box::new(PropList::new(Node::Data(Vec::from(bytes)))))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn WMCreatePLArrayFromSlice(
|
||||
elems: *mut PropList,
|
||||
@@ -630,18 +605,6 @@ pub mod ffi {
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn WMIsPLData(plist: *mut PropList) -> c_int {
|
||||
if plist.is_null() {
|
||||
return 0;
|
||||
}
|
||||
let plist = unsafe { &*plist };
|
||||
match &*plist.0.borrow() {
|
||||
Node::Data(_) => 1,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn WMIsPLArray(plist: *mut PropList) -> c_int {
|
||||
if plist.is_null() {
|
||||
|
||||
@@ -20,7 +20,7 @@ use nom::{
|
||||
character::complete::{char, multispace0, none_of, satisfy},
|
||||
combinator::{cut, eof, fail, map, map_res, opt},
|
||||
error::context,
|
||||
multi::{fold_many0, many0, many1, many_m_n, separated_list0},
|
||||
multi::{fold_many0, many1, many_m_n, separated_list0},
|
||||
sequence::{delimited, preceded, terminated},
|
||||
AsChar, Finish, IResult, Input, Parser,
|
||||
};
|
||||
@@ -32,7 +32,7 @@ fn read_dictionary_key<I: Input<Item: AsChar>>(input: I) -> IResult<I, PropList,
|
||||
preceded(
|
||||
multispace0,
|
||||
terminated(
|
||||
alt((read_data, read_string)),
|
||||
read_string,
|
||||
cut(context(
|
||||
"looking for '=' after dictionary key",
|
||||
(multispace0, char('='), multispace0),
|
||||
@@ -113,48 +113,6 @@ fn read_array<I: Input<Item: AsChar>>(input: I) -> IResult<I, PropList, VerboseE
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
fn read_data_byte<I: Input<Item: AsChar>>(input: I) -> IResult<I, u8, VerboseError<I>> {
|
||||
map(
|
||||
delimited(
|
||||
multispace0,
|
||||
(
|
||||
context(
|
||||
"looking for first hex value",
|
||||
satisfy(|c: char| c.is_ascii_hexdigit()),
|
||||
),
|
||||
cut(context(
|
||||
"looking for second hex value",
|
||||
satisfy(|c: char| c.is_ascii_hexdigit()),
|
||||
)),
|
||||
),
|
||||
multispace0,
|
||||
),
|
||||
|(upper, lower)| {
|
||||
let s = &[upper as u8, lower as u8];
|
||||
// Safety: upper and lower are ASCII hexdigits, so they
|
||||
// should fit into a str without validation and provide
|
||||
// exactly 8 bits of value.
|
||||
u8::from_str_radix(unsafe { str::from_utf8_unchecked(s) }, 16).unwrap()
|
||||
},
|
||||
)
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
fn read_data<I: Input<Item: AsChar>>(input: I) -> IResult<I, PropList, VerboseError<I>> {
|
||||
map(
|
||||
delimited(
|
||||
(multispace0, char('<')),
|
||||
many0(read_data_byte),
|
||||
cut(context(
|
||||
"looking for data to end with '>'",
|
||||
(multispace0, char('>')),
|
||||
)),
|
||||
),
|
||||
|bytes: Vec<u8>| PropList::new(Node::Data(bytes)),
|
||||
)
|
||||
.parse(input)
|
||||
}
|
||||
|
||||
fn unescape_character(c: char) -> char {
|
||||
match c {
|
||||
'\\' => '\\',
|
||||
@@ -300,7 +258,7 @@ fn read_string<I: Input<Item: AsChar>>(input: I) -> IResult<I, PropList, Verbose
|
||||
fn read_prop_list<I: Input<Item: AsChar>>(input: I) -> IResult<I, PropList, VerboseError<I>> {
|
||||
delimited(
|
||||
multispace0,
|
||||
alt((read_array, read_data, read_dictionary, read_string)),
|
||||
alt((read_array, read_dictionary, read_string)),
|
||||
multispace0,
|
||||
)
|
||||
.parse(input)
|
||||
@@ -363,60 +321,6 @@ mod test {
|
||||
PropList::new(Node::String(CString::new(s.as_bytes()).unwrap()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_data() {
|
||||
let plist = from_str("<deadbeef>").unwrap();
|
||||
assert_eq!(
|
||||
plist,
|
||||
PropList::new(Node::Data(vec![0xde, 0xad, 0xbe, 0xef]))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_unclosed_data() {
|
||||
let e = from_str("<deadbeef").unwrap_err();
|
||||
assert_eq!(
|
||||
e,
|
||||
r#"0: at line 1, in looking for data to end with '>':
|
||||
<deadbeef
|
||||
^
|
||||
|
||||
"#
|
||||
);
|
||||
|
||||
let e = from_str(
|
||||
r#"(
|
||||
<deadbeef
|
||||
,
|
||||
{
|
||||
hello = world;
|
||||
},
|
||||
)"#,
|
||||
)
|
||||
.unwrap_err();
|
||||
assert_eq!(
|
||||
e,
|
||||
r#"0: at line 3, in looking for data to end with '>':
|
||||
,
|
||||
^
|
||||
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error_incomplete_data_byte() {
|
||||
let e = from_str("<deadb").unwrap_err();
|
||||
assert_eq!(
|
||||
e,
|
||||
r#"0: at line 1, in looking for second hex value:
|
||||
<deadb
|
||||
^
|
||||
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_string() {
|
||||
let plist = from_str("foobar").unwrap();
|
||||
|
||||
@@ -49,30 +49,6 @@ pub(crate) struct Display<N: Deref<Target = Node>> {
|
||||
pub(crate) node: N,
|
||||
}
|
||||
|
||||
/// Quick and dirty single-branch lookup mapping `b` to a hex character. Only
|
||||
/// valid for `b` in `[0, 15]`.
|
||||
fn byte_char(b: u8) -> char {
|
||||
match b {
|
||||
0 => '0',
|
||||
1 => '1',
|
||||
2 => '2',
|
||||
3 => '3',
|
||||
4 => '4',
|
||||
5 => '5',
|
||||
6 => '6',
|
||||
7 => '7',
|
||||
8 => '8',
|
||||
9 => '9',
|
||||
10 => 'a',
|
||||
11 => 'b',
|
||||
12 => 'c',
|
||||
13 => 'd',
|
||||
14 => 'e',
|
||||
15 => 'f',
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Deref<Target = Node>> Display<N> {
|
||||
/// Writes whitespace to `f` for the current level of indentation.
|
||||
fn write_indent(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -83,32 +59,6 @@ impl<N: Deref<Target = Node>> Display<N> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a hexadecimal representation of `bytes` to `f`, splitting `bytes` up
|
||||
/// into space-delimited 32-bit quartets for readability.
|
||||
fn write_data_bytes(bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn write(b: u8, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let upper = (b >> 3) as u8;
|
||||
let lower = (b & 0x0F) as u8;
|
||||
write!(f, "{}", byte_char(upper))?;
|
||||
write!(f, "{}", byte_char(lower))
|
||||
}
|
||||
|
||||
let mut chunks = bytes.chunks(4);
|
||||
if let Some(first) = chunks.next() {
|
||||
for b in first {
|
||||
write(*b, f)?;
|
||||
}
|
||||
}
|
||||
for seg in chunks {
|
||||
f.write_char(' ')?;
|
||||
for b in seg {
|
||||
write(*b, f)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes `s` to `f`, backslash-escaping special characters as appropriate for
|
||||
/// a quoted property list string.
|
||||
fn write_escaped_string(s: &str, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -218,11 +168,6 @@ impl<N: Deref<Target = Node>> fmt::Display for Display<N> {
|
||||
self.write_indent(f)?;
|
||||
f.write_char(')')?;
|
||||
}
|
||||
Node::Data(bytes) => {
|
||||
write!(f, "<")?;
|
||||
write_data_bytes(bytes, f)?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
Node::Dictionary(items) if items.is_empty() => write!(f, "{{}}")?,
|
||||
Node::Dictionary(items) if self.inline != Inline::No => {
|
||||
// Try to fit everything in one line.
|
||||
|
||||
Reference in New Issue
Block a user