16855e09eSopenharmony_ci//! Bit level parsers 26855e09eSopenharmony_ci//! 36855e09eSopenharmony_ci 46855e09eSopenharmony_ciuse crate::error::{ErrorKind, ParseError}; 56855e09eSopenharmony_ciuse crate::internal::{Err, IResult}; 66855e09eSopenharmony_ciuse crate::lib::std::ops::{AddAssign, Div, RangeFrom, Shl, Shr}; 76855e09eSopenharmony_ciuse crate::traits::{InputIter, InputLength, Slice, ToUsize}; 86855e09eSopenharmony_ci 96855e09eSopenharmony_ci/// Generates a parser taking `count` bits 106855e09eSopenharmony_ci/// 116855e09eSopenharmony_ci/// # Example 126855e09eSopenharmony_ci/// ```rust 136855e09eSopenharmony_ci/// # use nom::bits::complete::take; 146855e09eSopenharmony_ci/// # use nom::IResult; 156855e09eSopenharmony_ci/// # use nom::error::{Error, ErrorKind}; 166855e09eSopenharmony_ci/// // Input is a tuple of (input: I, bit_offset: usize) 176855e09eSopenharmony_ci/// fn parser(input: (&[u8], usize), count: usize)-> IResult<(&[u8], usize), u8> { 186855e09eSopenharmony_ci/// take(count)(input) 196855e09eSopenharmony_ci/// } 206855e09eSopenharmony_ci/// 216855e09eSopenharmony_ci/// // Consumes 0 bits, returns 0 226855e09eSopenharmony_ci/// assert_eq!(parser(([0b00010010].as_ref(), 0), 0), Ok((([0b00010010].as_ref(), 0), 0))); 236855e09eSopenharmony_ci/// 246855e09eSopenharmony_ci/// // Consumes 4 bits, returns their values and increase offset to 4 256855e09eSopenharmony_ci/// assert_eq!(parser(([0b00010010].as_ref(), 0), 4), Ok((([0b00010010].as_ref(), 4), 0b00000001))); 266855e09eSopenharmony_ci/// 276855e09eSopenharmony_ci/// // Consumes 4 bits, offset is 4, returns their values and increase offset to 0 of next byte 286855e09eSopenharmony_ci/// assert_eq!(parser(([0b00010010].as_ref(), 4), 4), Ok((([].as_ref(), 0), 0b00000010))); 296855e09eSopenharmony_ci/// 306855e09eSopenharmony_ci/// // Tries to consume 12 bits but only 8 are available 316855e09eSopenharmony_ci/// assert_eq!(parser(([0b00010010].as_ref(), 0), 12), Err(nom::Err::Error(Error{input: ([0b00010010].as_ref(), 0), code: ErrorKind::Eof }))); 326855e09eSopenharmony_ci/// ``` 336855e09eSopenharmony_cipub fn take<I, O, C, E: ParseError<(I, usize)>>( 346855e09eSopenharmony_ci count: C, 356855e09eSopenharmony_ci) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E> 366855e09eSopenharmony_ciwhere 376855e09eSopenharmony_ci I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength, 386855e09eSopenharmony_ci C: ToUsize, 396855e09eSopenharmony_ci O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O>, 406855e09eSopenharmony_ci{ 416855e09eSopenharmony_ci let count = count.to_usize(); 426855e09eSopenharmony_ci move |(input, bit_offset): (I, usize)| { 436855e09eSopenharmony_ci if count == 0 { 446855e09eSopenharmony_ci Ok(((input, bit_offset), 0u8.into())) 456855e09eSopenharmony_ci } else { 466855e09eSopenharmony_ci let cnt = (count + bit_offset).div(8); 476855e09eSopenharmony_ci if input.input_len() * 8 < count + bit_offset { 486855e09eSopenharmony_ci Err(Err::Error(E::from_error_kind( 496855e09eSopenharmony_ci (input, bit_offset), 506855e09eSopenharmony_ci ErrorKind::Eof, 516855e09eSopenharmony_ci ))) 526855e09eSopenharmony_ci } else { 536855e09eSopenharmony_ci let mut acc: O = 0_u8.into(); 546855e09eSopenharmony_ci let mut offset: usize = bit_offset; 556855e09eSopenharmony_ci let mut remaining: usize = count; 566855e09eSopenharmony_ci let mut end_offset: usize = 0; 576855e09eSopenharmony_ci 586855e09eSopenharmony_ci for byte in input.iter_elements().take(cnt + 1) { 596855e09eSopenharmony_ci if remaining == 0 { 606855e09eSopenharmony_ci break; 616855e09eSopenharmony_ci } 626855e09eSopenharmony_ci let val: O = if offset == 0 { 636855e09eSopenharmony_ci byte.into() 646855e09eSopenharmony_ci } else { 656855e09eSopenharmony_ci ((byte << offset) as u8 >> offset).into() 666855e09eSopenharmony_ci }; 676855e09eSopenharmony_ci 686855e09eSopenharmony_ci if remaining < 8 - offset { 696855e09eSopenharmony_ci acc += val >> (8 - offset - remaining); 706855e09eSopenharmony_ci end_offset = remaining + offset; 716855e09eSopenharmony_ci break; 726855e09eSopenharmony_ci } else { 736855e09eSopenharmony_ci acc += val << (remaining - (8 - offset)); 746855e09eSopenharmony_ci remaining -= 8 - offset; 756855e09eSopenharmony_ci offset = 0; 766855e09eSopenharmony_ci } 776855e09eSopenharmony_ci } 786855e09eSopenharmony_ci Ok(((input.slice(cnt..), end_offset), acc)) 796855e09eSopenharmony_ci } 806855e09eSopenharmony_ci } 816855e09eSopenharmony_ci } 826855e09eSopenharmony_ci} 836855e09eSopenharmony_ci 846855e09eSopenharmony_ci/// Generates a parser taking `count` bits and comparing them to `pattern` 856855e09eSopenharmony_cipub fn tag<I, O, C, E: ParseError<(I, usize)>>( 866855e09eSopenharmony_ci pattern: O, 876855e09eSopenharmony_ci count: C, 886855e09eSopenharmony_ci) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E> 896855e09eSopenharmony_ciwhere 906855e09eSopenharmony_ci I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + Clone, 916855e09eSopenharmony_ci C: ToUsize, 926855e09eSopenharmony_ci O: From<u8> + AddAssign + Shl<usize, Output = O> + Shr<usize, Output = O> + PartialEq, 936855e09eSopenharmony_ci{ 946855e09eSopenharmony_ci let count = count.to_usize(); 956855e09eSopenharmony_ci move |input: (I, usize)| { 966855e09eSopenharmony_ci let inp = input.clone(); 976855e09eSopenharmony_ci 986855e09eSopenharmony_ci take(count)(input).and_then(|(i, o)| { 996855e09eSopenharmony_ci if pattern == o { 1006855e09eSopenharmony_ci Ok((i, o)) 1016855e09eSopenharmony_ci } else { 1026855e09eSopenharmony_ci Err(Err::Error(error_position!(inp, ErrorKind::TagBits))) 1036855e09eSopenharmony_ci } 1046855e09eSopenharmony_ci }) 1056855e09eSopenharmony_ci } 1066855e09eSopenharmony_ci} 1076855e09eSopenharmony_ci 1086855e09eSopenharmony_ci/// Parses one specific bit as a bool. 1096855e09eSopenharmony_ci/// 1106855e09eSopenharmony_ci/// # Example 1116855e09eSopenharmony_ci/// ```rust 1126855e09eSopenharmony_ci/// # use nom::bits::complete::bool; 1136855e09eSopenharmony_ci/// # use nom::IResult; 1146855e09eSopenharmony_ci/// # use nom::error::{Error, ErrorKind}; 1156855e09eSopenharmony_ci/// 1166855e09eSopenharmony_ci/// fn parse(input: (&[u8], usize)) -> IResult<(&[u8], usize), bool> { 1176855e09eSopenharmony_ci/// bool(input) 1186855e09eSopenharmony_ci/// } 1196855e09eSopenharmony_ci/// 1206855e09eSopenharmony_ci/// assert_eq!(parse(([0b10000000].as_ref(), 0)), Ok((([0b10000000].as_ref(), 1), true))); 1216855e09eSopenharmony_ci/// assert_eq!(parse(([0b10000000].as_ref(), 1)), Ok((([0b10000000].as_ref(), 2), false))); 1226855e09eSopenharmony_ci/// ``` 1236855e09eSopenharmony_cipub fn bool<I, E: ParseError<(I, usize)>>(input: (I, usize)) -> IResult<(I, usize), bool, E> 1246855e09eSopenharmony_ciwhere 1256855e09eSopenharmony_ci I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength, 1266855e09eSopenharmony_ci{ 1276855e09eSopenharmony_ci let (res, bit): (_, u32) = take(1usize)(input)?; 1286855e09eSopenharmony_ci Ok((res, bit != 0)) 1296855e09eSopenharmony_ci} 1306855e09eSopenharmony_ci 1316855e09eSopenharmony_ci#[cfg(test)] 1326855e09eSopenharmony_cimod test { 1336855e09eSopenharmony_ci use super::*; 1346855e09eSopenharmony_ci 1356855e09eSopenharmony_ci #[test] 1366855e09eSopenharmony_ci fn test_take_0() { 1376855e09eSopenharmony_ci let input = [0b00010010].as_ref(); 1386855e09eSopenharmony_ci let count = 0usize; 1396855e09eSopenharmony_ci assert_eq!(count, 0usize); 1406855e09eSopenharmony_ci let offset = 0usize; 1416855e09eSopenharmony_ci 1426855e09eSopenharmony_ci let result: crate::IResult<(&[u8], usize), usize> = take(count)((input, offset)); 1436855e09eSopenharmony_ci 1446855e09eSopenharmony_ci assert_eq!(result, Ok(((input, offset), 0))); 1456855e09eSopenharmony_ci } 1466855e09eSopenharmony_ci 1476855e09eSopenharmony_ci #[test] 1486855e09eSopenharmony_ci fn test_take_eof() { 1496855e09eSopenharmony_ci let input = [0b00010010].as_ref(); 1506855e09eSopenharmony_ci 1516855e09eSopenharmony_ci let result: crate::IResult<(&[u8], usize), usize> = take(1usize)((input, 8)); 1526855e09eSopenharmony_ci 1536855e09eSopenharmony_ci assert_eq!( 1546855e09eSopenharmony_ci result, 1556855e09eSopenharmony_ci Err(crate::Err::Error(crate::error::Error { 1566855e09eSopenharmony_ci input: (input, 8), 1576855e09eSopenharmony_ci code: ErrorKind::Eof 1586855e09eSopenharmony_ci })) 1596855e09eSopenharmony_ci ) 1606855e09eSopenharmony_ci } 1616855e09eSopenharmony_ci 1626855e09eSopenharmony_ci #[test] 1636855e09eSopenharmony_ci fn test_take_span_over_multiple_bytes() { 1646855e09eSopenharmony_ci let input = [0b00010010, 0b00110100, 0b11111111, 0b11111111].as_ref(); 1656855e09eSopenharmony_ci 1666855e09eSopenharmony_ci let result: crate::IResult<(&[u8], usize), usize> = take(24usize)((input, 4)); 1676855e09eSopenharmony_ci 1686855e09eSopenharmony_ci assert_eq!( 1696855e09eSopenharmony_ci result, 1706855e09eSopenharmony_ci Ok((([0b11111111].as_ref(), 4), 0b1000110100111111111111)) 1716855e09eSopenharmony_ci ); 1726855e09eSopenharmony_ci } 1736855e09eSopenharmony_ci 1746855e09eSopenharmony_ci #[test] 1756855e09eSopenharmony_ci fn test_bool_0() { 1766855e09eSopenharmony_ci let input = [0b10000000].as_ref(); 1776855e09eSopenharmony_ci 1786855e09eSopenharmony_ci let result: crate::IResult<(&[u8], usize), bool> = bool((input, 0)); 1796855e09eSopenharmony_ci 1806855e09eSopenharmony_ci assert_eq!(result, Ok(((input, 1), true))); 1816855e09eSopenharmony_ci } 1826855e09eSopenharmony_ci 1836855e09eSopenharmony_ci #[test] 1846855e09eSopenharmony_ci fn test_bool_eof() { 1856855e09eSopenharmony_ci let input = [0b10000000].as_ref(); 1866855e09eSopenharmony_ci 1876855e09eSopenharmony_ci let result: crate::IResult<(&[u8], usize), bool> = bool((input, 8)); 1886855e09eSopenharmony_ci 1896855e09eSopenharmony_ci assert_eq!( 1906855e09eSopenharmony_ci result, 1916855e09eSopenharmony_ci Err(crate::Err::Error(crate::error::Error { 1926855e09eSopenharmony_ci input: (input, 8), 1936855e09eSopenharmony_ci code: ErrorKind::Eof 1946855e09eSopenharmony_ci })) 1956855e09eSopenharmony_ci ); 1966855e09eSopenharmony_ci } 1976855e09eSopenharmony_ci} 198