change parse methods: the buffer must be passed on every call to simplify the parser lifetime

This commit is contained in:
lurchi 2016-09-04 13:47:37 +02:00
parent dd8cc059c5
commit f892d406f4
6 changed files with 403 additions and 447 deletions

View File

@ -68,12 +68,11 @@ pub struct PsycListParser {
state: PsycParseListState state: PsycParseListState
} }
pub struct PsycDictParser<'a> { //pub struct PsycDictParser<'b> {
state: PsycParseDictState, // state: PsycParseDictState,
parsed_key: Option<&'a [u8]>, // parsed_key: Option<&'b [u8]>,
buffer: Option<&'a [u8]>, // cursor: usize
cursor: usize //}
}
// //
//// TODO: What data structures does the index parser need? //// TODO: What data structures does the index parser need?
//pub struct PsycIndexParser { //pub struct PsycIndexParser {
@ -146,25 +145,25 @@ pub enum PsycListParserResult<'a> {
} }
} }
#[derive(Debug, PartialEq)] //#[derive(Debug, PartialEq)]
pub enum PsycDictParserResult<'a> { //pub enum PsycDictParserResult<'a> {
Complete, // Complete,
InsufficientData, // InsufficientData,
DictEntry { // DictEntry {
key: &'a [u8], // key: &'a [u8],
value: &'a [u8] // value: &'a [u8]
}, // },
DictEntryStart { // DictEntryStart {
key: &'a [u8], // key: &'a [u8],
value_part: &'a [u8] // value_part: &'a [u8]
}, // },
DictEntryCont { // DictEntryCont {
value_part: &'a [u8] // value_part: &'a [u8]
}, // },
DictEntryEnd { // DictEntryEnd {
value_part: &'a [u8] // value_part: &'a [u8]
} // }
} //}
#[repr(C)] #[repr(C)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -192,22 +191,22 @@ pub enum PsycListParserError {
GenericError = PsycParseListRC::PSYC_PARSE_LIST_ERROR as _, GenericError = PsycParseListRC::PSYC_PARSE_LIST_ERROR as _,
} }
#[repr(C)] //#[repr(C)]
#[derive(Debug, PartialEq)] //#[derive(Debug, PartialEq)]
pub enum PsycDictParserError { //pub enum PsycDictParserError {
InvalidValue = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE as _, // InvalidValue = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE as _,
InvalidValueLength = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE_LENGTH as _, // InvalidValueLength = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE_LENGTH as _,
InvalidValueType = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE_TYPE as _, // InvalidValueType = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE_TYPE as _,
InvalidValueStart = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE_START as _, // InvalidValueStart = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_VALUE_START as _,
InvalidKey = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_KEY as _, // InvalidKey = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_KEY as _,
InvalidKeyLength = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_KEY_LENGTH as _, // InvalidKeyLength = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_KEY_LENGTH as _,
InvalidKeyStart = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_KEY_START as _, // InvalidKeyStart = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_KEY_START as _,
InvalidKeyType = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_TYPE as _, // InvalidKeyType = PsycParseDictRC::PSYC_PARSE_DICT_ERROR_TYPE as _,
GenericError = PsycParseDictRC::PSYC_PARSE_DICT_ERROR as _, // GenericError = PsycParseDictRC::PSYC_PARSE_DICT_ERROR as _,
NoBuffer // NoBuffer
} //}
impl<'a> PsycParser { impl PsycParser {
/// Create a PsycParser /// Create a PsycParser
pub fn new() -> Self { pub fn new() -> Self {
let mut state: PsycParseState; let mut state: PsycParseState;
@ -223,12 +222,17 @@ impl<'a> PsycParser {
/// Parse the buffer previously set by set_buffer. Call repeatedly until the /// Parse the buffer previously set by set_buffer. Call repeatedly until the
/// result is PsycParserResult::Complete or a PsycParserError. /// result is PsycParserResult::Complete or a PsycParserError.
pub fn parse(&mut self) -> Result<PsycParserResult<'a>, PsycParserError> { pub fn parse<'a>(&mut self, buffer: &'a [u8]) -> Result<PsycParserResult<'a>, PsycParserError> {
let state_ptr = &mut self.state as *mut PsycParseState; let state_ptr = &mut self.state as *mut PsycParseState;
let buffer_ptr = buffer.as_ptr() as *const c_char;
let mut operator = '\0'; let mut operator = '\0';
let mut name: PsycString; let mut name: PsycString;
let mut value: PsycString; let mut value: PsycString;
unsafe { unsafe {
if buffer_ptr != self.state.buffer.data ||
buffer.len() != self.state.buffer.length {
psyc_parse_buffer_set(state_ptr, buffer_ptr, buffer.len())
}
name = mem::uninitialized(); name = mem::uninitialized();
value = mem::uninitialized(); value = mem::uninitialized();
let operator_ptr = &mut operator as *mut char as *mut c_char; let operator_ptr = &mut operator as *mut char as *mut c_char;
@ -324,15 +328,7 @@ impl<'a> PsycParser {
} }
} }
impl<'a> Parser<'a> for PsycParser { impl Parser for PsycParser {
fn set_buffer(&mut self, buffer: &'a [u8]) {
let state_ptr = &mut self.state as *mut PsycParseState;
let buffer_ptr = buffer.as_ptr() as *const c_char;
unsafe {
psyc_parse_buffer_set(state_ptr, buffer_ptr, buffer.len())
}
}
fn unparsed_position(&self) -> usize { fn unparsed_position(&self) -> usize {
unsafe { unsafe {
psyc_parse_cursor(&self.state as *const PsycParseState) psyc_parse_cursor(&self.state as *const PsycParseState)
@ -359,11 +355,16 @@ impl PsycListParser {
} }
} }
pub fn parse<'a>(&mut self) -> Result<PsycListParserResult<'a>, PsycListParserError> { pub fn parse<'a>(&mut self, buffer: &'a [u8]) -> Result<PsycListParserResult<'a>, PsycListParserError> {
let state_ptr = &mut self.state as *mut PsycParseListState; let state_ptr = &mut self.state as *mut PsycParseListState;
let buffer_ptr = buffer.as_ptr() as *const c_char;
let mut list_type: PsycString; let mut list_type: PsycString;
let mut element: PsycString; let mut element: PsycString;
unsafe { unsafe {
if buffer_ptr != self.state.buffer.data ||
buffer.len() != self.state.buffer.length {
psyc_parse_list_buffer_set(state_ptr, buffer_ptr, buffer.len())
}
list_type = mem::uninitialized(); list_type = mem::uninitialized();
element = mem::uninitialized(); element = mem::uninitialized();
let list_type_ptr = &mut list_type as *mut PsycString; let list_type_ptr = &mut list_type as *mut PsycString;
@ -408,19 +409,6 @@ impl PsycListParser {
return Ok(result) return Ok(result)
}, },
//PsycParseListRC::PSYC_PARSE_LIST_ELEM_LAST => {
// let result: PsycListParserResult;
// if ! self.finished {
// result = PsycListParserResult::ListElement {
// value: util::cstring_to_slice(element.data, element.length)
// };
// self.finished = true
// } else {
// result = PsycListParserResult::Complete
// }
// return Ok(result)
//},
PsycParseListRC::PSYC_PARSE_LIST_TYPE => (), PsycParseListRC::PSYC_PARSE_LIST_TYPE => (),
_error => { _error => {
@ -432,15 +420,7 @@ impl PsycListParser {
} }
} }
impl<'a> Parser<'a> for PsycListParser { impl Parser for PsycListParser {
fn set_buffer(&mut self, buffer: &'a [u8]) {
let state_ptr = &mut self.state as *mut PsycParseListState;
let buffer_ptr = buffer.as_ptr() as *const c_char;
unsafe {
psyc_parse_list_buffer_set(state_ptr, buffer_ptr, buffer.len())
}
}
fn unparsed_position(&self) -> usize { fn unparsed_position(&self) -> usize {
self.state.cursor self.state.cursor
} }
@ -450,162 +430,148 @@ impl<'a> Parser<'a> for PsycListParser {
} }
} }
impl<'a> PsycDictParser<'a> { //impl<'b> PsycDictParser<'b> {
/// Create a PsycDictParser // /// Create a PsycDictParser
pub fn new() -> Self { // pub fn new() -> Self {
let mut state: PsycParseDictState; // let mut state: PsycParseDictState;
unsafe { // unsafe {
state = mem::uninitialized(); // state = mem::uninitialized();
let state_ptr = &mut state as *mut PsycParseDictState; // let state_ptr = &mut state as *mut PsycParseDictState;
psyc_parse_dict_state_init(state_ptr) // psyc_parse_dict_state_init(state_ptr)
} // }
PsycDictParser { // PsycDictParser {
state: state, // state: state,
parsed_key: None, // parsed_key: None,
buffer: None, // cursor: 0
cursor: 0 // }
} // }
} //
// /// Parse the buffer previously set by set_buffer. Call repeatedly until the
/// Parse the buffer previously set by set_buffer. Call repeatedly until the // /// result is PsycDictParserResult::Complete or a PsycDictParserError
/// result is PsycDictParserResult::Complete or a PsycDictParserError // pub fn parse<'a>(&mut self, buffer: &'a [u8])
pub fn parse(&mut self) // -> Result<PsycDictParserResult<'a>, PsycDictParserError> {
-> Result<PsycDictParserResult<'a>, PsycDictParserError> { // let state_ptr = &mut self.state as *mut PsycParseDictState;
if self.buffer == None { // let buffer_ptr = buffer.as_ptr() as *const c_char;
return Err(PsycDictParserError::NoBuffer) // let mut list_type: PsycString;
} // let mut element: PsycString;
if self.buffer.unwrap().is_empty() { // unsafe {
return Ok(PsycDictParserResult::Complete); // if buffer_ptr != self.state.buffer.data ||
} // buffer.len() != self.state.buffer.length {
let state_ptr = &mut self.state as *mut PsycParseDictState; // psyc_parse_dict_buffer_set(state_ptr, buffer_ptr, buffer.len())
let mut list_type: PsycString; // }
let mut element: PsycString; // list_type = mem::uninitialized();
unsafe { // element = mem::uninitialized();
list_type = mem::uninitialized(); // let list_type_ptr = &mut list_type as *mut PsycString;
element = mem::uninitialized(); // let element_ptr = &mut element as *mut PsycString;
let list_type_ptr = &mut list_type as *mut PsycString; // loop {
let element_ptr = &mut element as *mut PsycString; // let parse_result = psyc_parse_dict(state_ptr, list_type_ptr, element_ptr);
loop { // println!("parse_result: {:?}", parse_result);
let parse_result = psyc_parse_dict(state_ptr, list_type_ptr, element_ptr); // println!("cursor: {}", self.state.cursor);
println!("parse_result: {:?}", parse_result); // self.cursor = self.state.cursor;
println!("cursor: {}", self.state.cursor); // match parse_result {
self.cursor = self.state.cursor; // PsycParseDictRC::PSYC_PARSE_DICT_END =>
match parse_result { // return Ok(PsycDictParserResult::Complete),
PsycParseDictRC::PSYC_PARSE_DICT_END => //
return Ok(PsycDictParserResult::Complete), // PsycParseDictRC::PSYC_PARSE_DICT_INSUFFICIENT =>
// return Ok(PsycDictParserResult::InsufficientData),
PsycParseDictRC::PSYC_PARSE_DICT_INSUFFICIENT => //
return Ok(PsycDictParserResult::InsufficientData), // PsycParseDictRC::PSYC_PARSE_DICT_KEY => {
// let key = util::cstring_to_slice(element.data, element.length);
PsycParseDictRC::PSYC_PARSE_DICT_KEY => { // self.parsed_key = Some(key)
let key = util::cstring_to_slice(element.data, element.length); // },
self.parsed_key = Some(key) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_KEY_START => {
// self.cursor = element.data as usize -
PsycParseDictRC::PSYC_PARSE_DICT_KEY_START => { // buffer_ptr as usize;
self.cursor = element.data as usize - // return Ok(PsycDictParserResult::InsufficientData)
self.buffer.unwrap().as_ptr() as usize; // },
return Ok(PsycDictParserResult::InsufficientData) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_KEY_CONT => {
// return Ok(PsycDictParserResult::InsufficientData)
PsycParseDictRC::PSYC_PARSE_DICT_KEY_CONT => { // },
return Ok(PsycDictParserResult::InsufficientData) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_KEY_END => {
// let end_index = self.cursor + element.length;
PsycParseDictRC::PSYC_PARSE_DICT_KEY_END => { // let key = &buffer[self.cursor .. end_index];
let end_index = self.cursor + element.length; // self.parsed_key = Some(key)
let key = &self.buffer.unwrap()[self.cursor .. end_index]; // },
self.parsed_key = Some(key) //
}, // //PsycParseDictRC::PSYC_PARSE_DICT_VALUE => {
// // let result = PsycDictParserResult::DictEntry {
//PsycParseDictRC::PSYC_PARSE_DICT_VALUE => { // // key: self.parsed_key.unwrap(),
// let result = PsycDictParserResult::DictEntry { // // value: util::cstring_to_slice(element.data, element.length)
// key: self.parsed_key.unwrap(), // // };
// value: util::cstring_to_slice(element.data, element.length) // // return Ok(result)
// }; // //},
// return Ok(result) //
//}, // PsycParseDictRC::PSYC_PARSE_DICT_VALUE |
// PsycParseDictRC::PSYC_PARSE_DICT_VALUE_LAST => {
PsycParseDictRC::PSYC_PARSE_DICT_VALUE | // //let result: PsycDictParserResult;
PsycParseDictRC::PSYC_PARSE_DICT_VALUE_LAST => { // //// FIXME: workaround
//let result: PsycDictParserResult; // //if ! self.finished {
//// FIXME: workaround // // result = PsycDictParserResult::DictEntry {
//if ! self.finished { // // key: self.parsed_key.unwrap(),
// result = PsycDictParserResult::DictEntry { // // value: util::cstring_to_slice(element.data, element.length)
// key: self.parsed_key.unwrap(), // // };
// value: util::cstring_to_slice(element.data, element.length) // // self.finished = true
// }; // //} else {
// self.finished = true // // result = PsycDictParserResult::Complete;
//} else { // //}
// result = PsycDictParserResult::Complete; // let result = PsycDictParserResult::DictEntry {
//} // key: self.parsed_key.unwrap(),
let result = PsycDictParserResult::DictEntry { // value: util::cstring_to_slice(element.data, element.length)
key: self.parsed_key.unwrap(), // };
value: util::cstring_to_slice(element.data, element.length) // return Ok(result)
}; // },
return Ok(result) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_VALUE_START => {
// let result = PsycDictParserResult::DictEntryStart {
PsycParseDictRC::PSYC_PARSE_DICT_VALUE_START => { // key: self.parsed_key.unwrap(),
let result = PsycDictParserResult::DictEntryStart { // value_part: util::cstring_to_slice(element.data, element.length)
key: self.parsed_key.unwrap(), // };
value_part: util::cstring_to_slice(element.data, element.length) // return Ok(result)
}; // },
return Ok(result) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_VALUE_CONT => {
// let result = PsycDictParserResult::DictEntryCont {
PsycParseDictRC::PSYC_PARSE_DICT_VALUE_CONT => { // value_part: util::cstring_to_slice(element.data, element.length)
let result = PsycDictParserResult::DictEntryCont { // };
value_part: util::cstring_to_slice(element.data, element.length) // return Ok(result)
}; // },
return Ok(result) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_VALUE_END => {
// let result = PsycDictParserResult::DictEntryEnd {
PsycParseDictRC::PSYC_PARSE_DICT_VALUE_END => { // value_part: util::cstring_to_slice(element.data, element.length)
let result = PsycDictParserResult::DictEntryEnd { // };
value_part: util::cstring_to_slice(element.data, element.length) // return Ok(result)
}; // },
return Ok(result) //
}, // PsycParseDictRC::PSYC_PARSE_DICT_TYPE => (),
//
PsycParseDictRC::PSYC_PARSE_DICT_TYPE => (), // _error => {
// return Err(mem::transmute(_error))
_error => { // },
return Err(mem::transmute(_error)) // }
}, // }
} // }
} // }
} //}
} //
} //impl<'a, 'b> Parser<'a> for PsycDictParser<'b> {
// fn unparsed_position(&self) -> usize {
impl<'a> Parser<'a> for PsycDictParser<'a> { // self.cursor
fn set_buffer(&mut self, buffer: &'a [u8]) { // }
self.buffer = Some(buffer); //
let state_ptr = &mut self.state as *mut PsycParseDictState; // fn unparsed_length(&self) -> usize {
let buffer_ptr = buffer.as_ptr() as *const c_char; // self.state.buffer.length - self.cursor
unsafe { // }
psyc_parse_dict_buffer_set(state_ptr, buffer_ptr, buffer.len()); //}
}
}
fn unparsed_position(&self) -> usize {
self.cursor
}
fn unparsed_length(&self) -> usize {
self.state.buffer.length - self.cursor
}
}
pub trait Parser<'a> {
/// Set a buffer of raw bytes for parsing
fn set_buffer(&mut self, buffer: &'a [u8]);
pub trait Parser {
/// copies the remaining unparsed bytes to the beginning of the given buffer. /// copies the remaining unparsed bytes to the beginning of the given buffer.
/// Returns the number of copied bytes. Must be called when parse() returned /// Returns the number of copied bytes. Must be called when parse() returned
/// InsufficientData as Result. /// InsufficientData as Result.
fn copy_unparsed_into_buffer(&self, buffer: &'a mut [u8]) -> usize { fn copy_unparsed_into_buffer<'a>(&self, buffer: &'a mut [u8]) -> usize {
let unparsed_pos = self.unparsed_position(); let unparsed_pos = self.unparsed_position();
let unparsed_len = self.unparsed_length(); let unparsed_len = self.unparsed_length();
if unparsed_pos != 0 { if unparsed_pos != 0 {

View File

@ -9,7 +9,7 @@ enum PsycUpdatePart { }
#[repr(C)] #[repr(C)]
pub struct PsycParseState { pub struct PsycParseState {
buffer: PsycString, pub buffer: PsycString,
cursor: usize, cursor: usize,
startc: usize, startc: usize,
routinglen: usize, routinglen: usize,

View File

@ -1,80 +1,57 @@
extern crate psyc; extern crate psyc;
use psyc::parser::*; use psyc::parser::*;
#[test]
fn test_parse() {
let test_data = "{foo1} bar1{foo2} bar2".to_string().into_bytes();
let expected1 = PsycDictParserResult::DictEntry{
key: b"foo1",
value: b"bar1"
};
let expected2 = PsycDictParserResult::DictEntry{
key: b"foo2",
value: b"bar2"
};
let expected3 = PsycDictParserResult::Complete;
let mut parser = PsycDictParser::new();
parser.set_buffer(&test_data);
assert_eq!(parser.parse().unwrap(), expected1);
assert_eq!(parser.parse().unwrap(), expected2);
assert_eq!(parser.parse().unwrap(), expected3);
}
#[test]
fn test_empty() {
let test_data = "".to_string().into_bytes();
let mut parser = PsycDictParser::new();
parser.set_buffer(&test_data);
assert_eq!(parser.parse().unwrap(), PsycDictParserResult::Complete);
}
#[test]
fn test_incomplete() {
let test_data1 = "{foo1}4 bar".to_string().into_bytes();
let test_data2 = "1{foo2} bar2".to_string().into_bytes();
let expected = vec![PsycDictParserResult::DictEntryStart {
key: b"foo1",
value_part: b"bar"
},
PsycDictParserResult::DictEntryEnd {
value_part: b"1"
},
PsycDictParserResult::DictEntry {
key: b"foo2",
value: b"bar2"
}];
let mut parser = PsycDictParser::new();
parser.set_buffer(&test_data1);
assert_eq!(parser.parse().unwrap(), expected[0]);
parser.set_buffer(&test_data2);
assert_eq!(parser.parse().unwrap(), expected[1]);
assert_eq!(parser.parse().unwrap(), expected[2]);
}
//#[test] //#[test]
//fn test_insufficient() { //fn test_parse() {
// let mut test_data1 = "{4 foo".to_string().into_bytes(); // let test_data = "{foo1} bar1{foo2} bar2".to_string().into_bytes();
// let mut test_data2 = "1} bar1".to_string().into_bytes();
// let mut test_data3 = "{4 foo1} bar1".to_string().into_bytes();
// //
// let expected = vec![PsycDictParserResult::InsufficientData, // let expected1 = PsycDictParserResult::DictEntry{
// PsycDictParserResult::DictEntry { // key: b"foo1",
// value: b"bar1"
// };
//
// let expected2 = PsycDictParserResult::DictEntry{
// key: b"foo2",
// value: b"bar2"
// };
//
// let expected3 = PsycDictParserResult::Complete;
//
// let mut parser = PsycDictParser::new();
//
// parser.set_buffer(&test_data);
//
// assert_eq!(parser.parse().unwrap(), expected1);
// assert_eq!(parser.parse().unwrap(), expected2);
// assert_eq!(parser.parse().unwrap(), expected3);
//}
//
//#[test]
//fn test_empty() {
// let test_data = "".to_string().into_bytes();
//
// let mut parser = PsycDictParser::new();
//
// parser.set_buffer(&test_data);
//
// assert_eq!(parser.parse().unwrap(), PsycDictParserResult::Complete);
//}
//
//#[test]
//fn test_incomplete() {
// let test_data1 = "{foo1}4 bar".to_string().into_bytes();
// let test_data2 = "1{foo2} bar2".to_string().into_bytes();
//
// let expected = vec![PsycDictParserResult::DictEntryStart {
// key: b"foo1", // key: b"foo1",
// value: b"bar1" // value_part: b"bar"
// },
// PsycDictParserResult::DictEntryEnd {
// value_part: b"1"
// },
// PsycDictParserResult::DictEntry {
// key: b"foo2",
// value: b"bar2"
// }]; // }];
// //
// let mut parser = PsycDictParser::new(); // let mut parser = PsycDictParser::new();
@ -82,9 +59,32 @@ fn test_incomplete() {
// parser.set_buffer(&test_data1); // parser.set_buffer(&test_data1);
// assert_eq!(parser.parse().unwrap(), expected[0]); // assert_eq!(parser.parse().unwrap(), expected[0]);
// //
// //let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1); // parser.set_buffer(&test_data2);
// //test_data1.resize(unparsed_length, 0);
// //test_data1.append(&mut test_data2);
// parser.set_buffer(&test_data3);
// assert_eq!(parser.parse().unwrap(), expected[1]); // assert_eq!(parser.parse().unwrap(), expected[1]);
//
// assert_eq!(parser.parse().unwrap(), expected[2]);
//} //}
//
////#[test]
////fn test_insufficient() {
//// let mut test_data1 = "{4 foo".to_string().into_bytes();
//// let mut test_data2 = "1} bar1".to_string().into_bytes();
//// let mut test_data3 = "{4 foo1} bar1".to_string().into_bytes();
////
//// let expected = vec![PsycDictParserResult::InsufficientData,
//// PsycDictParserResult::DictEntry {
//// key: b"foo1",
//// value: b"bar1"
//// }];
////
//// let mut parser = PsycDictParser::new();
////
//// parser.set_buffer(&test_data1);
//// assert_eq!(parser.parse().unwrap(), expected[0]);
////
//// //let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1);
//// //test_data1.resize(unparsed_length, 0);
//// //test_data1.append(&mut test_data2);
//// parser.set_buffer(&test_data3);
//// assert_eq!(parser.parse().unwrap(), expected[1]);
////}

View File

@ -21,12 +21,12 @@ fn test_parse() {
let mut parser = PsycListParser::new(); let mut parser = PsycListParser::new();
parser.set_buffer(&test_data); //parser.set_buffer(&test_data);
assert_eq!(parser.parse().unwrap(), expected1); assert_eq!(parser.parse(&test_data).unwrap(), expected1);
assert_eq!(parser.parse().unwrap(), expected2); assert_eq!(parser.parse(&test_data).unwrap(), expected2);
assert_eq!(parser.parse().unwrap(), expected3); assert_eq!(parser.parse(&test_data).unwrap(), expected3);
assert_eq!(parser.parse().unwrap(), expected4); assert_eq!(parser.parse(&test_data).unwrap(), expected4);
} }
#[test] #[test]
@ -35,9 +35,9 @@ fn test_empty() {
let mut parser = PsycListParser::new(); let mut parser = PsycListParser::new();
parser.set_buffer(&test_data); //parser.set_buffer(&test_data);
assert_eq!(parser.parse().unwrap(), PsycListParserResult::Complete); assert_eq!(parser.parse(&test_data).unwrap(), PsycListParserResult::Complete);
} }
#[test] #[test]
@ -57,13 +57,13 @@ fn test_incomplete() {
let mut parser = PsycListParser::new(); let mut parser = PsycListParser::new();
parser.set_buffer(&test_data1); //parser.set_buffer(&test_data1);
assert_eq!(parser.parse().unwrap(), expected[0]); assert_eq!(parser.parse(&test_data1).unwrap(), expected[0]);
parser.set_buffer(&test_data2); //parser.set_buffer(&test_data2);
assert_eq!(parser.parse().unwrap(), expected[1]); assert_eq!(parser.parse(&test_data2).unwrap(), expected[1]);
assert_eq!(parser.parse().unwrap(), expected[2]); assert_eq!(parser.parse(&test_data2).unwrap(), expected[2]);
} }
#[test] #[test]
@ -78,13 +78,13 @@ fn test_insufficient() {
let mut parser = PsycListParser::new(); let mut parser = PsycListParser::new();
parser.set_buffer(&test_data1); //parser.set_buffer(&test_data1);
assert_eq!(parser.parse().unwrap(), expected[0]); assert_eq!(parser.parse(&test_data1).unwrap(), expected[0]);
let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1); let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1);
test_data1.resize(unparsed_length, 0); test_data1.resize(unparsed_length, 0);
test_data1.append(&mut test_data2); test_data1.append(&mut test_data2);
parser.set_buffer(&test_data1); //parser.set_buffer(&test_data1);
assert_eq!(parser.parse().unwrap(), expected[1]); assert_eq!(parser.parse(&test_data1).unwrap(), expected[1]);
} }

View File

@ -14,11 +14,8 @@ fn test_parse() {
let mut parser = PsycParser::new(); let mut parser = PsycParser::new();
parser.set_buffer(&test_data); assert_eq!(parser.parse(&test_data).unwrap(), expected[0]);
assert_eq!(parser.parse(&test_data).unwrap(), expected[1]);
assert_eq!(parser.parse().unwrap(), expected[0]);
assert_eq!(parser.parse().unwrap(), expected[1]);
} }
#[test] #[test]
@ -27,10 +24,8 @@ fn test_empty() {
let mut parser = PsycParser::new(); let mut parser = PsycParser::new();
parser.set_buffer(&test_data);
// FIXME: InsufficientData or Complete? // FIXME: InsufficientData or Complete?
assert_eq!(parser.parse().unwrap(), PsycParserResult::InsufficientData); assert_eq!(parser.parse(&test_data).unwrap(), PsycParserResult::InsufficientData);
} }
#[test] #[test]
@ -50,12 +45,10 @@ fn test_incomplete() {
let mut parser = PsycParser::new(); let mut parser = PsycParser::new();
parser.set_buffer(&test_data1); let _ = parser.parse(&test_data1);
let _ = parser.parse(); assert_eq!(parser.parse(&test_data1).unwrap(), expected[0]);
assert_eq!(parser.parse().unwrap(), expected[0]);
parser.set_buffer(&test_data2); assert_eq!(parser.parse(&test_data2).unwrap(), expected[1]);
assert_eq!(parser.parse().unwrap(), expected[1]);
} }
#[test] #[test]
@ -79,21 +72,17 @@ fn test_insufficient() {
let mut parser = PsycParser::new(); let mut parser = PsycParser::new();
parser.set_buffer(&test_data1[.. 1]); assert_eq!(parser.parse(&test_data1[.. 1]).unwrap(), expected[0]);
assert_eq!(parser.parse().unwrap(), expected[0]);
let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1); let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1);
assert_eq!(unparsed_length, 1); assert_eq!(unparsed_length, 1);
parser.set_buffer(&test_data1[.. 44]); assert_eq!(parser.parse(&test_data1[.. 44]).unwrap(), expected[1]);
assert_eq!(parser.parse().unwrap(), expected[1]);
assert_eq!(parser.parse(&test_data1[.. 44]).unwrap(), expected[2]);
assert_eq!(parser.parse().unwrap(), expected[2]);
let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1); let unparsed_length = parser.copy_unparsed_into_buffer(&mut test_data1);
test_data1.resize(unparsed_length, 0); test_data1.resize(unparsed_length, 0);
test_data1.append(&mut test_data2); test_data1.append(&mut test_data2);
parser.set_buffer(&test_data1); assert_eq!(parser.parse(&test_data1).unwrap(), expected[3]);
assert_eq!(parser.parse().unwrap(), expected[3]); assert_eq!(parser.parse(&test_data1).unwrap(), expected[4]);
assert_eq!(parser.parse().unwrap(), expected[4]);
} }

View File

@ -1094,127 +1094,128 @@ psyc_parse_update (PsycParseUpdateState *state, char *oper, PsycString *value)
{ {
PsycParseIndexRC ret; PsycParseIndexRC ret;
if (state->cursor >= state->buffer.length) if (state->cursor >= state->buffer.length) {
return PSYC_PARSE_UPDATE_END; return PSYC_PARSE_UPDATE_END;
}
state->startc = state->cursor; state->startc = state->cursor;
switch (state->part) { switch (state->part) {
case PSYC_UPDATE_PART_START: case PSYC_UPDATE_PART_START:
value->length = 0; value->length = 0;
value->data = NULL; value->data = NULL;
// fall thru // fall thru
case PSYC_INDEX_PART_TYPE: case PSYC_INDEX_PART_TYPE:
case PSYC_INDEX_PART_LIST: case PSYC_INDEX_PART_LIST:
case PSYC_INDEX_PART_STRUCT: case PSYC_INDEX_PART_STRUCT:
case PSYC_INDEX_PART_DICT_LENGTH: case PSYC_INDEX_PART_DICT_LENGTH:
case PSYC_INDEX_PART_DICT: case PSYC_INDEX_PART_DICT:
ret = psyc_parse_index((PsycParseIndexState*)state, value); ret = psyc_parse_index((PsycParseIndexState*)state, value);
switch (ret) { switch (ret) {
case PSYC_PARSE_INDEX_INSUFFICIENT: case PSYC_PARSE_INDEX_INSUFFICIENT:
case PSYC_PARSE_INDEX_LIST_LAST: case PSYC_PARSE_INDEX_LIST_LAST:
case PSYC_PARSE_INDEX_STRUCT_LAST: case PSYC_PARSE_INDEX_STRUCT_LAST:
case PSYC_PARSE_INDEX_END: case PSYC_PARSE_INDEX_END:
return PSYC_PARSE_UPDATE_INSUFFICIENT; return PSYC_PARSE_UPDATE_INSUFFICIENT;
case PSYC_PARSE_INDEX_ERROR_TYPE: case PSYC_PARSE_INDEX_ERROR_TYPE:
if (state->buffer.data[state->cursor] != ' ') if (state->buffer.data[state->cursor] != ' ')
return ret; return ret;
state->part = PSYC_PARSE_UPDATE_TYPE; state->part = PSYC_PARSE_UPDATE_TYPE;
value->length = 0; value->length = 0;
value->data = NULL; value->data = NULL;
ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT); ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT);
break; break;
default: default:
return ret; return ret;
} }
case PSYC_UPDATE_PART_TYPE: case PSYC_UPDATE_PART_TYPE:
if (!psyc_is_oper(state->buffer.data[state->cursor])) if (!psyc_is_oper(state->buffer.data[state->cursor]))
return PSYC_PARSE_UPDATE_ERROR_OPER; return PSYC_PARSE_UPDATE_ERROR_OPER;
*oper = state->buffer.data[state->cursor]; *oper = state->buffer.data[state->cursor];
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_UPDATE_END); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_UPDATE_END);
switch (parse_keyword((ParseState*)state, value)) { switch (parse_keyword((ParseState*)state, value)) {
case PARSE_SUCCESS: // end of keyword case PARSE_SUCCESS: // end of keyword
case PARSE_ERROR: // no keyword case PARSE_ERROR: // no keyword
switch (state->buffer.data[state->cursor]) { switch (state->buffer.data[state->cursor]) {
case ':': case ':':
state->part = PSYC_UPDATE_PART_LENGTH; state->part = PSYC_UPDATE_PART_LENGTH;
break; break;
case ' ': case ' ':
state->part = PSYC_UPDATE_PART_VALUE; state->part = PSYC_UPDATE_PART_VALUE;
break; break;
default: default:
return PSYC_PARSE_UPDATE_ERROR_TYPE; return PSYC_PARSE_UPDATE_ERROR_TYPE;
} }
state->cursor++; state->cursor++;
return PSYC_PARSE_UPDATE_TYPE; return PSYC_PARSE_UPDATE_TYPE;
break; break;
case PARSE_INSUFFICIENT: // end of buffer case PARSE_INSUFFICIENT: // end of buffer
return PSYC_PARSE_UPDATE_TYPE_END; return PSYC_PARSE_UPDATE_TYPE_END;
default: // should not be reached default: // should not be reached
return PSYC_PARSE_UPDATE_ERROR; return PSYC_PARSE_UPDATE_ERROR;
} }
break; break;
case PSYC_UPDATE_PART_LENGTH: case PSYC_UPDATE_PART_LENGTH:
switch (parse_length((ParseState*)state, &state->elemlen)) { switch (parse_length((ParseState*)state, &state->elemlen)) {
case PARSE_SUCCESS: // length is complete case PARSE_SUCCESS: // length is complete
state->elemlen_found = 1; state->elemlen_found = 1;
state->elem_parsed = 0; state->elem_parsed = 0;
value->length = state->elemlen; value->length = state->elemlen;
value->data = NULL; value->data = NULL;
if (state->buffer.data[state->cursor] != ' ') if (state->buffer.data[state->cursor] != ' ')
return PSYC_PARSE_UPDATE_ERROR_LENGTH; return PSYC_PARSE_UPDATE_ERROR_LENGTH;
state->part = PSYC_UPDATE_PART_VALUE; state->part = PSYC_UPDATE_PART_VALUE;
if (value->length == 0) if (value->length == 0)
return PSYC_PARSE_UPDATE_END; return PSYC_PARSE_UPDATE_END;
ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT); ADVANCE_STARTC_OR_RETURN(PSYC_PARSE_UPDATE_INSUFFICIENT);
break; break;
case PARSE_INSUFFICIENT: // length is incomplete case PARSE_INSUFFICIENT: // length is incomplete
if (value->length == 0) if (value->length == 0)
return PSYC_PARSE_UPDATE_END; return PSYC_PARSE_UPDATE_END;
return PSYC_PARSE_UPDATE_INSUFFICIENT; return PSYC_PARSE_UPDATE_INSUFFICIENT;
case PARSE_ERROR: // no length after : case PARSE_ERROR: // no length after :
return PSYC_PARSE_UPDATE_ERROR_LENGTH; return PSYC_PARSE_UPDATE_ERROR_LENGTH;
default: // should not be reached default: // should not be reached
return PSYC_PARSE_UPDATE_ERROR; return PSYC_PARSE_UPDATE_ERROR;
} }
// fall thru // fall thru
case PSYC_UPDATE_PART_VALUE: case PSYC_UPDATE_PART_VALUE:
if (state->elemlen_found) { if (state->elemlen_found) {
switch (parse_binary((ParseState*)state, state->elemlen, value, switch (parse_binary((ParseState*)state, state->elemlen, value,
&state->elem_parsed)) { &state->elem_parsed)) {
case PARSE_SUCCESS: case PARSE_SUCCESS:
if (value->length == state->elem_parsed) if (value->length == state->elem_parsed)
ret = PSYC_PARSE_UPDATE_VALUE; ret = PSYC_PARSE_UPDATE_VALUE;
else else
ret = PSYC_PARSE_UPDATE_VALUE_END; ret = PSYC_PARSE_UPDATE_VALUE_END;
break; break;
case PARSE_INCOMPLETE: case PARSE_INCOMPLETE:
if (value->length == state->elem_parsed) if (value->length == state->elem_parsed)
ret = PSYC_PARSE_UPDATE_VALUE_START; ret = PSYC_PARSE_UPDATE_VALUE_START;
else else
ret = PSYC_PARSE_UPDATE_VALUE_CONT; ret = PSYC_PARSE_UPDATE_VALUE_CONT;
break; break;
default: // should not be reached default: // should not be reached
return PSYC_PARSE_UPDATE_ERROR_VALUE; return PSYC_PARSE_UPDATE_ERROR_VALUE;
} }
} else { } else {
value->data = state->buffer.data + state->cursor; value->data = state->buffer.data + state->cursor;
value->length = state->buffer.length - state->cursor; value->length = state->buffer.length - state->cursor;
ret = PSYC_PARSE_UPDATE_VALUE; ret = PSYC_PARSE_UPDATE_VALUE;
} }
state->part = PSYC_INDEX_PART_TYPE; state->part = PSYC_INDEX_PART_TYPE;
state->cursor++; state->cursor++;
return ret; return ret;
} }
return PSYC_PARSE_INDEX_ERROR; // should not be reached return PSYC_PARSE_INDEX_ERROR; // should not be reached