mirror of
https://github.com/Devolutions/IronRDP.git
synced 2025-07-07 17:45:01 +00:00
WIP
This commit is contained in:
parent
cd3973e0de
commit
c8a8891f20
4 changed files with 69 additions and 28 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -2638,6 +2638,9 @@ version = "0.0.0"
|
|||
[[package]]
|
||||
name = "ironrdp-propertyset"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ironrdp-rdcleanpath"
|
||||
|
|
|
@ -16,5 +16,8 @@ categories.workspace = true
|
|||
doctest = false
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
tracing = { version = "0.1", features = ["log"] }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
use core::fmt::Display;
|
||||
|
||||
use alloc::borrow::Cow;
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::string::String;
|
||||
|
@ -22,15 +27,31 @@ impl PropertySet {
|
|||
}
|
||||
|
||||
pub fn insert(&mut self, key: impl Into<Key>, value: impl Into<Value>) -> Option<Value> {
|
||||
self.inner.insert(key.into(), value.into())
|
||||
let (key, value) = (key.into(), value.into());
|
||||
debug!("PropertySet::insert({key}, {value})");
|
||||
self.inner.insert(key, value)
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: &str) -> Option<Value> {
|
||||
self.inner.remove(key)
|
||||
let value = self.inner.remove(key);
|
||||
|
||||
match &value {
|
||||
Some(value) => debug!("PropertySet::remove({key}) = {value}"),
|
||||
None => debug!("PropertySet::remove({key}) = None"),
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
pub fn get<'a, V: ExtractFrom<&'a Value>>(&'a self, key: &str) -> Option<V> {
|
||||
self.inner.get(key).and_then(|val| V::extract_from(val, private::Token))
|
||||
let value = self.inner.get(key);
|
||||
|
||||
match &value {
|
||||
Some(value) => debug!("PropertySet::get({key}) = {value}"),
|
||||
None => debug!("PropertySet::get({key}) = None"),
|
||||
}
|
||||
|
||||
value.and_then(|val| V::extract_from(val, private::Token))
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&Key, &Value)> {
|
||||
|
@ -67,7 +88,7 @@ pub trait ExtractFrom<Value>: Sized {
|
|||
}
|
||||
|
||||
/// Represents a value of any type of the .RDP file format.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Value {
|
||||
/// Numerical value.
|
||||
Int(i64),
|
||||
|
@ -93,6 +114,15 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for Value {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Value::Int(value) => write!(f, "{value}"),
|
||||
Value::Str(value) => write!(f, "\"{value}\""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_from!(String => Value::Str);
|
||||
impl_from!(&str => Value::Str);
|
||||
impl_from!(u8 => Value::Int);
|
||||
|
|
|
@ -16,7 +16,6 @@ pub enum ErrorKind {
|
|||
UnknownType { ty: String },
|
||||
InvalidValue { ty: String, value: String },
|
||||
MalformedLine { line: String },
|
||||
DuplicatedKey { key: String },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -37,28 +36,21 @@ impl fmt::Display for Error {
|
|||
write!(f, "invalid value at line {line_number} for type {ty} ({value})")
|
||||
}
|
||||
ErrorKind::MalformedLine { line } => write!(f, "malformed line at line {line_number} ({line})"),
|
||||
ErrorKind::DuplicatedKey { key } => write!(f, "duplicated key at line {line_number} ({key})"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ParseResult {
|
||||
pub store: PropertySet,
|
||||
pub errors: Vec<Error>,
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> ParseResult {
|
||||
let mut store = PropertySet::new();
|
||||
pub fn load(properties: &mut PropertySet, input: &str) -> Result<(), Vec<Error>> {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
for (idx, line) in input.lines().enumerate() {
|
||||
let mut split = line.splitn(2, ':');
|
||||
|
||||
if let (Some(key), Some(ty), Some(value)) = (split.next(), split.next(), split.next()) {
|
||||
let is_duplicated = match ty {
|
||||
match ty {
|
||||
"i" => {
|
||||
if let Ok(value) = value.parse::<i64>() {
|
||||
store.insert(key.to_owned(), value).is_some()
|
||||
properties.insert(key.to_owned(), value);
|
||||
} else {
|
||||
errors.push(Error {
|
||||
kind: ErrorKind::InvalidValue {
|
||||
|
@ -67,24 +59,17 @@ pub fn parse(input: &str) -> ParseResult {
|
|||
},
|
||||
line: idx,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
"s" => store.insert(key.to_owned(), value).is_some(),
|
||||
"s" => {
|
||||
properties.insert(key.to_owned(), value);
|
||||
}
|
||||
_ => {
|
||||
errors.push(Error {
|
||||
kind: ErrorKind::UnknownType { ty: ty.to_owned() },
|
||||
line: idx,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if is_duplicated {
|
||||
errors.push(Error {
|
||||
kind: ErrorKind::DuplicatedKey { key: key.to_owned() },
|
||||
line: idx,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
errors.push(Error {
|
||||
|
@ -94,13 +79,33 @@ pub fn parse(input: &str) -> ParseResult {
|
|||
}
|
||||
}
|
||||
|
||||
ParseResult { store, errors }
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(store: &PropertySet) -> String {
|
||||
pub struct ParseResult {
|
||||
pub properties: PropertySet,
|
||||
pub errors: Vec<Error>,
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> ParseResult {
|
||||
let mut properties = PropertySet::new();
|
||||
|
||||
let errors = match load(&mut properties, input) {
|
||||
Ok(()) => Vec::new(),
|
||||
Err(errors) => errors,
|
||||
};
|
||||
|
||||
ParseResult { properties, errors }
|
||||
}
|
||||
|
||||
pub fn write(properties: &PropertySet) -> String {
|
||||
let mut buf = String::new();
|
||||
|
||||
for (key, value) in store.iter() {
|
||||
for (key, value) in properties.iter() {
|
||||
buf.push_str(key);
|
||||
|
||||
match value {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue