Issues with nom 6 error type
This commit is contained in:
@@ -21,6 +21,9 @@ tracing = "0.1.25"
|
||||
fs2 = "0.4.3"
|
||||
libc = "0.2.93"
|
||||
hex = "0.4.3"
|
||||
nom = "6.1.2"
|
||||
num-traits = "0.2"
|
||||
num-derive = "0.3"
|
||||
tiny-keccak = { version = "2.0", features = ["sha3"] }
|
||||
err = { path = "../err" }
|
||||
taskrun = { path = "../taskrun" }
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use crate::{BadError, Error};
|
||||
use err::Error;
|
||||
use nom::error::{ErrorKind, VerboseError};
|
||||
use nom::number::complete::{be_i16, be_i32, be_i64, be_i8, be_u8};
|
||||
use nom::Needed;
|
||||
#[allow(unused_imports)]
|
||||
use nom::{
|
||||
bytes::complete::{tag, take, take_while_m_n},
|
||||
@@ -9,7 +11,9 @@ use nom::{
|
||||
};
|
||||
use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::ToPrimitive;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[allow(unused_imports)]
|
||||
use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
#[derive(Debug, FromPrimitive, ToPrimitive, Serialize, Deserialize)]
|
||||
pub enum DType {
|
||||
@@ -85,35 +89,44 @@ pub struct Config {
|
||||
pub entries: Vec<ConfigEntry>,
|
||||
}
|
||||
|
||||
fn parseShortString(inp: &[u8]) -> Result<(&[u8], Option<String>), Error> {
|
||||
fn parse_short_string(inp: &[u8]) -> IResult<&[u8], Option<String>> {
|
||||
let (inp, len1) = be_i32(inp)?;
|
||||
if len1 == -1 {
|
||||
return Ok((inp, None));
|
||||
}
|
||||
if len1 < 4 {
|
||||
return BadError(format!("bad string len {}", len1));
|
||||
error!("bad string len {}", len1);
|
||||
let err = nom::error::make_error(inp, ErrorKind::Verify);
|
||||
return Err(nom::Err::Error(err));
|
||||
}
|
||||
if len1 > 500 {
|
||||
return BadError(format!("large string len {}", len1));
|
||||
error!("large string len {}", len1);
|
||||
let err = nom::error::make_error(inp, ErrorKind::Verify);
|
||||
return Err(nom::Err::Error(err));
|
||||
}
|
||||
let (inp, snb) = take((len1 - 4) as usize)(inp)?;
|
||||
let s1 = String::from_utf8(snb.to_vec())?;
|
||||
Ok((inp, Some(s1)))
|
||||
match String::from_utf8(snb.to_vec()) {
|
||||
Ok(s1) => Ok((inp, Some(s1))),
|
||||
Err(e) => {
|
||||
let err = nom::error::make_error(inp, ErrorKind::Verify);
|
||||
Err(nom::Err::Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Parse a single configuration entry.
|
||||
*/
|
||||
pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
let (inp, len1) = be_i32(inp)?;
|
||||
pub fn parse_entry(inp: &[u8]) -> IResult<&[u8], Option<ConfigEntry>> {
|
||||
let t = be_i32(inp);
|
||||
let (inp, len1) = t?;
|
||||
if len1 < 0 || len1 > 4000 {
|
||||
return BadError(format!("ConfigEntry bad len1 {}", len1));
|
||||
return Err(nom::Err::Error(nom::error::Error::new(inp, ErrorKind::Verify)));
|
||||
//return Err(format!("ConfigEntry bad len1 {}", len1).into());
|
||||
}
|
||||
if inp.len() == 0 {
|
||||
return Ok((inp, None));
|
||||
}
|
||||
if inp.len() < len1 as usize - 4 {
|
||||
return BadError(format!("incomplete input"));
|
||||
return Err(nom::Err::Incomplete(Needed::new(len1 as usize - 4)));
|
||||
//return Err(format!("incomplete input").into());
|
||||
}
|
||||
let inpE = &inp[(len1 - 8) as usize..];
|
||||
let (inp, ts) = be_i64(inp)?;
|
||||
@@ -128,7 +141,9 @@ pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
let (inp, precision) = be_i16(inp)?;
|
||||
let (inp, dtlen) = be_i32(inp)?;
|
||||
if dtlen > 100 {
|
||||
return BadError(format!("unexpected data type len {}", dtlen));
|
||||
error!("unexpected data type len {}", dtlen);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
//return Err(format!("unexpected data type len {}", dtlen).into());
|
||||
}
|
||||
let (inp, dtmask) = be_u8(inp)?;
|
||||
let isCompressed = dtmask & 0x80 != 0;
|
||||
@@ -137,11 +152,15 @@ pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
let isShaped = dtmask & 0x10 != 0;
|
||||
let (inp, dtype) = be_i8(inp)?;
|
||||
if dtype > 13 {
|
||||
return BadError(format!("unexpected data type {}", dtype));
|
||||
error!("unexpected data type {}", dtype);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
let dtype = match num_traits::FromPrimitive::from_i8(dtype) {
|
||||
Some(k) => k,
|
||||
None => return BadError(format!("Can not convert {} to DType", dtype)),
|
||||
None => {
|
||||
error!("Can not convert {} to DType", dtype);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
};
|
||||
let (inp, compressionMethod) = match isCompressed {
|
||||
false => (inp, None),
|
||||
@@ -149,7 +168,10 @@ pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
let (inp, cm) = be_u8(inp)?;
|
||||
match num_traits::FromPrimitive::from_u8(cm) {
|
||||
Some(k) => (inp, Some(k)),
|
||||
None => return BadError("unknown compression"),
|
||||
None => {
|
||||
error!("unknown compression");
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -158,7 +180,8 @@ pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
true => {
|
||||
let (mut inp, dim) = be_u8(inp)?;
|
||||
if dim > 4 {
|
||||
return BadError(format!("unexpected number of dimensions: {}", dim));
|
||||
error!("unexpected number of dimensions: {}", dim);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
let mut shape = vec![];
|
||||
for _ in 0..dim {
|
||||
@@ -169,15 +192,16 @@ pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
(inp, Some(shape))
|
||||
}
|
||||
};
|
||||
let (inp, sourceName) = parseShortString(inp)?;
|
||||
let (inp, unit) = parseShortString(inp)?;
|
||||
let (inp, description) = parseShortString(inp)?;
|
||||
let (inp, optionalFields) = parseShortString(inp)?;
|
||||
let (inp, valueConverter) = parseShortString(inp)?;
|
||||
let (inp, sourceName) = parse_short_string(inp)?;
|
||||
let (inp, unit) = parse_short_string(inp)?;
|
||||
let (inp, description) = parse_short_string(inp)?;
|
||||
let (inp, optionalFields) = parse_short_string(inp)?;
|
||||
let (inp, valueConverter) = parse_short_string(inp)?;
|
||||
assert_eq!(inp.len(), inpE.len());
|
||||
let (inpE, len2) = be_i32(inpE)?;
|
||||
if len1 != len2 {
|
||||
return BadError(format!("mismatch len1 {} len2 {}", len1, len2));
|
||||
error!("mismatch len1 {} len2 {}", len1, len2);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
Ok((
|
||||
inpE,
|
||||
@@ -211,32 +235,42 @@ pub fn parseEntry(inp: &[u8]) -> Result<(&[u8], Option<ConfigEntry>), Error> {
|
||||
/*
|
||||
Parse the full configuration file.
|
||||
*/
|
||||
pub fn parseConfig(inp: &[u8]) -> Result<Config, Error> {
|
||||
pub fn parseConfig(inp: &[u8]) -> IResult<&[u8], Config> {
|
||||
let (inp, ver) = be_i16(inp)?;
|
||||
let (inp, len1) = be_i32(inp)?;
|
||||
if len1 <= 8 || len1 > 500 {
|
||||
return BadError(format!("no channel name. len1 {}", len1));
|
||||
error!("no channel name. len1 {}", len1);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
let (inp, chn) = take((len1 - 8) as usize)(inp)?;
|
||||
let (inp, len2) = be_i32(inp)?;
|
||||
if len1 != len2 {
|
||||
return BadError(format!("Mismatch len1 {} len2 {}", len1, len2));
|
||||
error!("Mismatch len1 {} len2 {}", len1, len2);
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
let mut entries = vec![];
|
||||
let mut inpA = inp;
|
||||
while inpA.len() > 0 {
|
||||
let inp = inpA;
|
||||
let (inp, e) = parseEntry(inp)?;
|
||||
let (inp, e) = parse_entry(inp)?;
|
||||
if let Some(e) = e {
|
||||
entries.push(e);
|
||||
}
|
||||
inpA = inp;
|
||||
}
|
||||
Ok(Config {
|
||||
let channelName = match String::from_utf8(chn.to_vec()) {
|
||||
Ok(k) => k,
|
||||
Err(e) => {
|
||||
error!("channelName utf8 error");
|
||||
return Err(nom::Err::Error(nom::error::make_error(inp, ErrorKind::Verify)));
|
||||
}
|
||||
};
|
||||
let ret = Config {
|
||||
formatVersion: ver,
|
||||
channelName: String::from_utf8(chn.to_vec())?,
|
||||
channelName,
|
||||
entries: entries,
|
||||
})
|
||||
};
|
||||
Ok((inp, ret))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -252,13 +286,13 @@ fn read_data() -> Vec<u8> {
|
||||
#[test]
|
||||
fn parse_dummy() {
|
||||
let config = parseConfig(&[0, 0, 0, 0, 0, 11, 0x61, 0x62, 0x63, 0, 0, 0, 11, 0, 0, 0, 1]).unwrap();
|
||||
assert_eq!(0, config.formatVersion);
|
||||
assert_eq!("abc", config.channelName);
|
||||
assert_eq!(0, config.1.formatVersion);
|
||||
assert_eq!("abc", config.1.channelName);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_file() {
|
||||
let config = parseConfig(&readData()).unwrap();
|
||||
let config = parseConfig(&read_data()).unwrap().1;
|
||||
assert_eq!(0, config.formatVersion);
|
||||
assert_eq!(9, config.entries.len());
|
||||
for e in &config.entries {
|
||||
|
||||
Reference in New Issue
Block a user