Skip to content

Commit

Permalink
Incomplete can hold either a needed size, or an unknown size
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Mar 1, 2015
1 parent d4ea23e commit 232f676
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 65 deletions.
8 changes: 4 additions & 4 deletions src/consumer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//! This consumer will take 4 samples from the input, print them, then stop
//!
//! ```rust
//! use nom::{IResult,MemProducer,Consumer,ConsumerState};
//! use nom::{IResult,Needed,MemProducer,Consumer,ConsumerState};
//! use std::str;
//! use std::io::SeekFrom;
//!
Expand All @@ -24,7 +24,7 @@
//!
//! fn take4(i:&[u8]) -> IResult<&[u8], &[u8]>{
//! if i.len() < 4 {
//! IResult::Incomplete(4)
//! IResult::Incomplete(Needed::Size(4))
//! } else {
//! IResult::Done(&i[4..],&i[0..4])
//! }
Expand Down Expand Up @@ -204,7 +204,7 @@ mod tests {
use super::*;
use super::ConsumerState::*;
use producer::MemProducer;
use internal::IResult;
use internal::{Needed,IResult};
use std::str;
use std::io::SeekFrom;

Expand All @@ -213,7 +213,7 @@ macro_rules! take(
($name:ident $count:expr) => (
fn $name(i:&[u8]) -> IResult<&[u8], &[u8]>{
if i.len() < $count {
IResult::Incomplete(0)
IResult::Incomplete(Needed::Size($count))
} else {
IResult::Done(&i[$count..],&i[0..$count])
}
Expand Down
8 changes: 7 additions & 1 deletion src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ impl<'a,I:Eq,O:Eq> Eq for IResultClosure<'a,I,O> {}
//type IResultClosure<'a,I,O> = |I|:'a -> IResult<'a,I,O>;
//type IResultClosure<'a,I,O> = Fn<I, IResult<'a,I,O>>;

#[derive(Debug,PartialEq,Eq)]
pub enum Needed {
Unknown,
Size(u32)
}

/// Holds the result of parsing functions
///
/// It depends on I, the input types, and O, the output type.
Expand All @@ -50,7 +56,7 @@ pub enum IResult<I,O> {
Done(I,O),
Error(Err),
//Incomplete(proc(I):'a -> IResult<I,O>)
Incomplete(u32)
Incomplete(Needed)
//Incomplete(Box<FnMut(I) -> IResult<I,O>>)
//Incomplete(IResultClosure<I,O>)
//Incomplete(|I|:'a -> IResult<'a,I,O>)
Expand Down
105 changes: 70 additions & 35 deletions src/map.rs

Large diffs are not rendered by default.

33 changes: 17 additions & 16 deletions src/nom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ macro_rules! tag(
let bytes = as_bytes(&expected);

if bytes.len() > i.len() {
return Incomplete(bytes.len() as u32);
return Incomplete(Needed::Size(bytes.len() as u32));
}

if &i[0..bytes.len()] == bytes {
Expand Down Expand Up @@ -489,15 +489,15 @@ pub fn multispace(input:&[u8]) -> IResult<&[u8], &[u8]> {

pub fn sized_buffer(input:&[u8]) -> IResult<&[u8], &[u8]> {
if input.len() == 0 {
return Incomplete(0)
return Incomplete(Needed::Unknown)
}

let len = input[0] as usize;

if input.len() >= len + 1 {
return Done(&input[len+1..], &input[1..len+1])
} else {
return Incomplete(0)
return Incomplete(Needed::Size(1 + len as u32))
}
}

Expand Down Expand Up @@ -659,7 +659,7 @@ pub fn length_value(input:&[u8]) -> IResult<&[u8], &[u8]> {
return IResult::Done(&input[len+1..], &input[1..len+1])
} else {
// FIXME: return Incomplete
return IResult::Error(0)
return IResult::Incomplete(Needed::Size(1+len as u32))
}
}

Expand All @@ -668,7 +668,7 @@ macro_rules! take(
($name:ident $count:expr) => (
fn $name(i:&[u8]) -> IResult<&[u8], &[u8]>{
if i.len() < $count {
Incomplete(0)
Incomplete(Needed::Size($count))
} else {
Done(&i[$count..],&i[0..$count])
}
Expand All @@ -690,7 +690,7 @@ macro_rules! take_until(

for idx in 0..i.len() {
if idx + bytes.len() > i.len() {
return Incomplete(0)
return Incomplete(Needed::Size((idx + bytes.len()) as u32))
}
if &i[idx..idx + bytes.len()] == bytes {
if idx + bytes.len() > i.len() {
Expand Down Expand Up @@ -719,7 +719,7 @@ macro_rules! take_until_and_leave(

for idx in 0..i.len() {
if idx + bytes.len() > i.len() {
return Incomplete(0)
return Incomplete(Needed::Size((idx + bytes.len()) as u32))
}
if &i[idx..idx+bytes.len()] == bytes {
return Done(&i[idx..], &i[0..idx])
Expand All @@ -744,7 +744,7 @@ macro_rules! take_until_either(

for idx in 0..i.len() {
if idx + 1 > i.len() {
return Incomplete(0)
return Incomplete(Needed::Size(1 + idx as u32))
}
for &t in bytes.iter() {
if i[idx] == t {
Expand Down Expand Up @@ -775,7 +775,7 @@ macro_rules! take_until_either_and_leave(

for idx in 0..i.len() {
if idx + 1 > i.len() {
return Incomplete(0)
return Incomplete(Needed::Size(1 + idx as u32))
}
for &t in bytes.iter() {
if i[idx] == t {
Expand All @@ -790,15 +790,15 @@ macro_rules! take_until_either_and_leave(

pub fn be_u8(i: &[u8]) -> IResult<&[u8], u8> {
if i.len() < 1 {
Incomplete(0)
Incomplete(Needed::Size(1))
} else {
Done(&i[1..], i[0])
}
}

pub fn be_u16(i: &[u8]) -> IResult<&[u8], u16> {
if i.len() < 2 {
Incomplete(0)
Incomplete(Needed::Size(2))
} else {
let res = ((i[0] as u16) << 8) + i[1] as u16;
Done(&i[2..], res)
Expand All @@ -807,7 +807,7 @@ pub fn be_u16(i: &[u8]) -> IResult<&[u8], u16> {

pub fn be_u32(i: &[u8]) -> IResult<&[u8], u32> {
if i.len() < 4 {
Incomplete(0)
Incomplete(Needed::Size(4))
} else {
let res = ((i[0] as u32) << 24) + ((i[1] as u32) << 16) + ((i[2] as u32) << 8) + i[3] as u32;
Done(&i[4..], res)
Expand All @@ -816,7 +816,7 @@ pub fn be_u32(i: &[u8]) -> IResult<&[u8], u32> {

pub fn be_u64(i: &[u8]) -> IResult<&[u8], u64> {
if i.len() < 8 {
Incomplete(0)
Incomplete(Needed::Size(8))
} else {
let res = ((i[0] as u64) << 56) + ((i[1] as u64) << 48) + ((i[2] as u64) << 40) + ((i[3] as u64) << 32) +
((i[4] as u64) << 24) + ((i[5] as u64) << 16) + ((i[6] as u64) << 8) + i[7] as u64;
Expand Down Expand Up @@ -852,6 +852,7 @@ pub fn be_f64(input: &[u8]) -> IResult<&[u8], f64> {
mod tests {
use super::*;
use map::*;
use internal::Needed;
use internal::IResult;
use internal::IResult::*;

Expand Down Expand Up @@ -1023,7 +1024,7 @@ mod tests {
assert_eq!(r2, Done(b"WXYZ", C{a: 1, b: None}));

let r3 = f(b"abcdX");
assert_eq!(r3, Incomplete(4));
assert_eq!(r3, Incomplete(Needed::Size(4)));
}

#[test]
Expand Down Expand Up @@ -1110,7 +1111,7 @@ mod tests {
let arr3:[u8; 7usize] = [8, 4, 5, 6, 7, 8, 9];
let res3 = length_value(&arr3);
//FIXME: should be incomplete
assert_eq!(Error(0), res3);
assert_eq!(Incomplete(Needed::Size(9)), res3);
}

#[test]
Expand All @@ -1126,6 +1127,6 @@ mod tests {

println!("Done 2\n");
let r3 = x(b"abcefg");
assert_eq!(r3, Incomplete(0));
assert_eq!(r3, Incomplete(Needed::Size(7)));
}
}
6 changes: 3 additions & 3 deletions src/producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ macro_rules! pusher (
#[cfg(test)]
mod tests {
use super::*;
use internal::IResult;
use internal::{Needed,IResult};
use internal::IResult::*;
use std::fmt::Debug;
use std::str;
Expand Down Expand Up @@ -305,7 +305,7 @@ mod tests {
fn accu() {
fn f(input:&[u8]) -> IResult<&[u8],&[u8]> {
if input.len() <= 4 {
Incomplete(0)
Incomplete(Needed::Size(4))
} else {
Done(b"", input)
}
Expand All @@ -326,7 +326,7 @@ mod tests {
fn accu_2() {
fn f(input:&[u8]) -> IResult<&[u8],&[u8]> {
if input.len() <= 4 || &input[0..5] != b"abcde" {
Incomplete(0)
Incomplete(Needed::Size(4))
} else {
Done(&input[5..], &input[0..5])
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ini.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[macro_use]
extern crate nom;

use nom::{IResult,FlatMapOpt,line_ending,not_line_ending, space, alphanumeric, multispace};
use nom::{IResult,Needed,FlatMapOpt,line_ending,not_line_ending, space, alphanumeric, multispace};
use nom::IResult::*;

use std::str;
Expand Down
6 changes: 3 additions & 3 deletions tests/mp4.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[macro_use]
extern crate nom;

use nom::{HexDisplay,IResult,FlatMapOpt,Functor,FileProducer,be_u16,be_u32,be_u64,be_f32};
use nom::{HexDisplay,Needed,IResult,FlatMapOpt,Functor,FileProducer,be_u16,be_u32,be_u64,be_f32};
use nom::{Consumer,ConsumerState};
use nom::IResult::*;

Expand All @@ -15,7 +15,7 @@ fn mp4_box(input:&[u8]) -> IResult<&[u8], &[u8]> {
if i.len() >= sz - 4 {
return Done(&i[(sz-4)..], &i[0..(sz-4)])
} else {
return Incomplete(1234)
return Incomplete(Needed::Size(4 + offset as u32))
}
}
Error(e) => Error(e),
Expand Down Expand Up @@ -287,7 +287,7 @@ fn moov_iods_type(input:&[u8]) -> IResult<&[u8], MP4BoxType> {

fn mvhd_box(input:&[u8]) -> IResult<&[u8],MvhdBox> {
if input.len() < 100 {
Incomplete(0)
Incomplete(Needed::Size(100))
} else if input.len() == 100 {
mvhd32(input)
} else if input.len() == 112 {
Expand Down
2 changes: 1 addition & 1 deletion tests/omnom.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[macro_use]
extern crate nom;

use nom::{Consumer,ConsumerState,MemProducer,IResult};
use nom::{Consumer,ConsumerState,MemProducer,IResult,Needed};
use nom::IResult::*;

#[derive(PartialEq,Eq,Debug)]
Expand Down
2 changes: 1 addition & 1 deletion tests/test1.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[macro_use]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,FlatMapOpt,Functor,not_line_ending};
use nom::{IResult,Needed,Producer,FileProducer,ProducerState,FlatMapOpt,Functor,not_line_ending};
use nom::IResult::*;

use std::str;
Expand Down

0 comments on commit 232f676

Please sign in to comment.