Repository: Geal/nom
Pull request #430 (2017-01-23 19:55:55)

Added be_u24 method
In TLS1.0+ there are payload fields who's length is set via a 24bit unsigned integer value.

Kind of a strange method I agree. I'm not sure if you prefer `usize` or `u32`


Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 57db293..1a815e9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,7 @@ stream = []
 verbose-errors = []
 
 [dependencies.regex]
-version = "^0.2"
+version = "^0.1.56"
 optional = true
 
 [dependencies.lazy_static]
diff --git a/src/macros.rs b/src/macros.rs
index 3c9c28d..b1456bc 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -159,31 +159,6 @@ macro_rules! named (
     );
 );
 
-/// Makes a function from a parser combination with arguments.
-#[macro_export]
-macro_rules! named_args {
-    (pub $func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        pub fn $func_name(input: &[u8], $( $arg : $typ ),*) -> IResult<&[u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-    (pub $func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        pub fn $func_name<'a>(input: &'a [u8], $( $arg : $typ ),*) -> IResult<&'a [u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-    ($func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        fn $func_name(input: &[u8], $( $arg : $typ ),*) -> IResult<&[u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-    ($func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
-        fn $func_name<'a>(input: &'a [u8], $( $arg : $typ ),*) -> IResult<&'a [u8], $return_type> {
-            $submac!(input, $($args)*)
-        }
-    };
-}
-
 /// Makes a function from a parser combination, with attributes
 ///
 /// The usage of this macro is almost identical to `named!`, except that
@@ -582,28 +557,8 @@ macro_rules! map_opt (
   );
 );
 
-/// `parse_to!(O) => I -> IResult<I, O>`
-/// uses the `parse` method from `std::str::FromStr` to convert the current
-/// input to the specified type
-///
-/// this will completely consume the input
-#[macro_export]
-macro_rules! parse_to (
-  ($i:expr, $t:ty ) => (
-    {
-      use $crate::ParseTo;
-      use $crate::InputLength;
-      match ($i).parse_to() {
-        ::std::option::Option::Some(output) => $crate::IResult::Done($i.slice(..$i.input_len()), output),
-        ::std::option::Option::None         => $crate::IResult::Error(error_position!($crate::ErrorKind::MapOpt, $i))
-      }
-    }
-  );
-);
-
 /// `verify!(I -> IResult<I,O>, O -> bool) => I -> IResult<I, O>`
 /// returns the result of the child parser if it satisfies a verifcation function
-///
 /// ```
 /// # #[macro_use] extern crate nom;
 /// # use nom::IResult::Done;
diff --git a/src/nom.rs b/src/nom.rs
index 2887bb6..769e8e8 100644
--- a/src/nom.rs
+++ b/src/nom.rs
@@ -340,6 +340,21 @@ pub fn be_u16(i: &[u8]) -> IResult<&[u8], u16> {
   }
 }
 
+/// Recognizes big endian unsigned 3 byte integer
+#[inline]
+pub fn be_u24(i: &[u8]) -> IResult<&[u8], u32> {
+  if i.len() < 3 {
+    Incomplete(Needed::Size(3))
+  } else {
+    let res = ((i[0] as u32) << 16) + ((i[1] as u32) << 8) + (i[2] as u32);
+    Done(&i[3..], res)
+  }
+}
+
+
+
+
+
 /// Recognizes big endian unsigned 4 bytes integer
 #[inline]
 pub fn be_u32(i: &[u8]) -> IResult<&[u8], u32> {
@@ -408,6 +423,17 @@ pub fn le_u16(i: &[u8]) -> IResult<&[u8], u16> {
   }
 }
 
+/// Recongnizes little endan unsigned 3 byte integer
+#[inline]
+pub fn le_u24(i: &[u8]) -> IResult<&[u8], u32> {
+  if i.len() < 3 {
+    Incomplete(Needed::Size(3))
+  } else {
+    let res = (i[0] as u32) + ((i[3] as u32) << 8) + ((i[2] as u32) << 16);
+    Done(&i[3..], res)
+  }
+}
+
 /// Recognizes little endian unsigned 4 bytes integer
 #[inline]
 pub fn le_u32(i: &[u8]) -> IResult<&[u8], u32> {
@@ -595,94 +621,6 @@ pub fn rest_s(input: &str) -> IResult<&str, &str> {
     IResult::Done(&input[input.len()..], input)
 }
 
-/// Recognizes floating point number in a byte string and returs a f32
-pub fn float(input: &[u8]) -> IResult<&[u8],f32> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f32)
-  )
-}
-
-/// Recognizes floating point number in a string and returs a f32
-pub fn float_s(input: &str) -> IResult<&str,f32> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f32)
-  )
-}
-
-/// Recognizes floating point number in a byte string and returs a f64
-pub fn double(input: &[u8]) -> IResult<&[u8],f64> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f64)
-  )
-}
-
-/// Recognizes floating point number in a string and returs a f64
-pub fn double_s(input: &str) -> IResult<&str,f64> {
-  flat_map!(input,
-    recognize!(
-      tuple!(
-        opt!(alt!(tag!("+") | tag!("-"))),
-        alt!(
-          delimited!(digit, tag!("."), opt!(digit))
-          | delimited!(opt!(digit), tag!("."), digit)
-        ),
-        opt!(complete!(tuple!(
-          alt!(tag!("e") | tag!("E")),
-          opt!(alt!(tag!("+") | tag!("-"))),
-          digit
-          )
-        ))
-      )
-    ),
-    parse_to!(f64)
-  )
-}
-
 #[cfg(test)]
 mod tests {
   use super::*;
@@ -879,6 +817,13 @@ mod tests {
     assert_eq!(be_i16(&[0xff, 0xff]), Done(&b""[..], -1));
     assert_eq!(be_i16(&[0x80, 0x00]), Done(&b""[..], -32768_i16));
   }
+  
+  #[test]
+  fn u24_tests() {
+    assert_eq!(be_u24(&[0x00, 0x00, 0x00]), Done(&b""[..], 0));
+    assert_eq!(be_u24(&[0x00, 0xFF, 0xFF]), Done(&b""[..], 65535_u32));
+    assert_eq!(be_u24(&[0x12, 0x34, 0x56]), Done(&b""[..], 1193046_u32));
+  }
 
   #[test]
   fn i32_tests() {
@@ -1130,17 +1075,4 @@ mod tests {
     assert_eq!(eol("\r"),    Incomplete(Needed::Size(2)));
     assert_eq!(eol("\ra"),   Error(error_position!(ErrorKind::CrLf, "\ra")));
   }
-
-  #[test]
-  fn float_test() {
-    assert_eq!(float(&b"+3.14"[..]),   Done(&b""[..], 3.14));
-    assert_eq!(float_s(&"3.14"[..]),   Done(&""[..], 3.14));
-    assert_eq!(double(&b"3.14"[..]),   Done(&b""[..], 3.14));
-    assert_eq!(double_s(&"3.14"[..]),   Done(&""[..], 3.14));
-
-    assert_eq!(float(&b"-1.234E-12"[..]),   Done(&b""[..], -1.234E-12));
-    assert_eq!(float_s(&"-1.234E-12"[..]),   Done(&""[..], -1.234E-12));
-    assert_eq!(double(&b"-1.234E-12"[..]),   Done(&b""[..], -1.234E-12));
-    assert_eq!(double_s(&"-1.234E-12"[..]),   Done(&""[..], -1.234E-12));
-  }
 }
diff --git a/src/regexp.rs b/src/regexp.rs
index 87ac566..d312524 100644
--- a/src/regexp.rs
+++ b/src/regexp.rs
@@ -23,18 +23,6 @@ macro_rules! regex_bytes (
 /// Returns the whole input if a match is found
 ///
 /// requires the `regexp` feature
-///
-/// ```
-/// # #[macro_use] extern crate nom;
-/// # use nom::IResult::{Done,Error};
-/// # fn main() {
-/// named!(rm< &str,Vec<&str> >, re_matches_static!(r"\d{4}-\d{2}-\d{2}"));
-/// assert_eq!(rm("2015-09-07"), Done("", vec!["2015-09-07"]));
-/// assert_eq!(rm("blah"), Error(error_code!(ErrorKind::RegexpMatches)));
-/// assert_eq!(rm("aaa2015-09-07blah2015-09-09pouet"), Done("pouet", vec!["2015-09-07", "2015-09-09"]));
-/// # }
-/// ```
-///
 #[macro_export]
 macro_rules! re_match (
   ($i:expr, $re:expr) => (
diff --git a/src/traits.rs b/src/traits.rs
index a728f08..2bba693 100644
--- a/src/traits.rs
+++ b/src/traits.rs
@@ -7,10 +7,6 @@ use std::iter::Enumerate;
 use std::str::Chars;
 #[cfg(not(feature = "core"))]
 use std::str::CharIndices;
-#[cfg(not(feature = "core"))]
-use std::str::FromStr;
-#[cfg(not(feature = "core"))]
-use std::str::from_utf8;
 
 
 /// abstract method to calculate the input length
@@ -452,26 +448,6 @@ impl<'a,'b> FindSubstring<&'b str> for &'a str {
   }
 }
 
-/// abstract method to calculate the input length
-#[cfg(not(feature = "core"))]
-pub trait ParseTo<R> {
-  fn parse_to(&self) -> Option<R>;
-}
-
-#[cfg(not(feature = "core"))]
-impl<'a,R: FromStr> ParseTo<R> for &'a[u8] {
-  fn parse_to(&self) -> Option<R> {
-    from_utf8(self).ok().and_then(|s| s.parse().ok())
-  }
-}
-
-#[cfg(not(feature = "core"))]
-impl<'a,R:FromStr> ParseTo<R> for &'a str {
-  fn parse_to(&self) -> Option<R> {
-    self.parse().ok()
-  }
-}
-
 /// slicing operations using ranges
 ///
 /// this trait is loosely based on


Test patch:
diff --git a/tests/named_args.rs b/tests/named_args.rs
deleted file mode 100644
index e998a08..0000000
--- a/tests/named_args.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-#[macro_use]
-extern crate nom;
-
-use nom::{IResult,digit};
-
-// Parser definition
-
-use std::str;
-use std::str::FromStr;
-
-use self::Operator::*;
-
-enum Operator {
-    Slash,
-    Star,
-}
-
-impl Operator {
-    fn to_str(&self) -> &'static str {
-        match *self {
-            Slash => "/",
-            Star => "*",
-        }
-    }
-}
-
-// Parse the specified `Operator`.
-named_args!(operator(op: Operator) <&[u8]>,
-    tag!(op.to_str())
-);
-
-// We parse any expr surrounded by the tags `open_tag` and `close_tag`, ignoring all whitespaces around those
-named_args!(brackets<'a>(open_tag: &str, close_tag: &str) <i64>, ws!(delimited!( tag!(open_tag), expr, tag!(close_tag) )) );
-
-// We transform an integer string into a i64, ignoring surrounding whitespaces
-// We look for a digit suite, and try to convert it.
-// If either str::from_utf8 or FromStr::from_str fail,
-// we fallback to the brackets parser defined above
-named!(factor<i64>, alt!(
-    map_res!(
-      map_res!(
-        ws!(digit),
-        str::from_utf8
-      ),
-      FromStr::from_str
-    )
-  | call!(brackets, "(", ")")
-  )
-);
-
-// We read an initial factor and for each time we find
-// a * or / operator followed by another factor, we do
-// the math by folding everything
-named!(term <i64>, do_parse!(
-    init: factor >>
-    res:  fold_many0!(
-        pair!(alt!(call!(operator, Star) | call!(operator, Slash)), factor),
-        init,
-        |acc, (op, val): (&[u8], i64)| {
-            if (op[0] as char) == '*' { acc * val } else { acc / val }
-        }
-    ) >>
-    (res)
-  )
-);
-
-named!(expr <i64>, do_parse!(
-    init: term >>
-    res:  fold_many0!(
-        pair!(alt!(tag!("+") | tag!("-")), term),
-        init,
-        |acc, (op, val): (&[u8], i64)| {
-            if (op[0] as char) == '+' { acc + val } else { acc - val }
-        }
-    ) >>
-    (res)
-  )
-);
-
-#[test]
-fn factor_test() {
-  assert_eq!(factor(&b"3"[..]), IResult::Done(&b""[..], 3));
-  assert_eq!(factor(&b" 12"[..]), IResult::Done(&b""[..], 12));
-  assert_eq!(factor(&b"537  "[..]), IResult::Done(&b""[..], 537));
-  assert_eq!(factor(&b"  24   "[..]), IResult::Done(&b""[..], 24));
-}
-
-
-#[test]
-fn term_test() {
-  assert_eq!(term(&b" 12 *2 /  3"[..]), IResult::Done(&b""[..], 8));
-  assert_eq!(term(&b" 2* 3  *2 *2 /  3"[..]), IResult::Done(&b""[..], 8));
-  assert_eq!(term(&b" 48 /  3/2"[..]), IResult::Done(&b""[..], 8));
-}
-
-#[test]
-fn expr_test() {
-  assert_eq!(expr(&b" 1 +  2 "[..]), IResult::Done(&b""[..], 3));
-  assert_eq!(expr(&b" 12 + 6 - 4+  3"[..]), IResult::Done(&b""[..], 17));
-  assert_eq!(expr(&b" 1 + 2*3 + 4"[..]), IResult::Done(&b""[..], 11));
-}
-
-#[test]
-fn parens_test() {
-  assert_eq!(expr(&b" (  2 )"[..]), IResult::Done(&b""[..], 2));
-  assert_eq!(expr(&b" 2* (  3 + 4 ) "[..]), IResult::Done(&b""[..], 14));
-  assert_eq!(expr(&b"  2*2 / ( 5 - 1) + 3"[..]), IResult::Done(&b""[..], 4));
-}