1 /* 2 #[macro_use] 3 extern crate nom; 4 extern crate bytes; 5 6 use nom::{Compare,CompareResult,InputLength,InputIter,Slice,HexDisplay}; 7 8 use std::str; 9 use std::str::FromStr; 10 use bytes::{Buf,MutBuf}; 11 use bytes::buf::{BlockBuf,BlockBufCursor}; 12 use std::ops::{Range,RangeTo,RangeFrom,RangeFull}; 13 use std::iter::{Enumerate,Iterator}; 14 use std::fmt; 15 use std::cmp::{min,PartialEq}; 16 17 #[derive(Clone,Copy)] 18 #[repr(C)] 19 pub struct BlockSlice<'a> { 20 buf: &'a BlockBuf, 21 start: usize, 22 end: usize, 23 } 24 25 impl<'a> BlockSlice<'a> { 26 fn cursor(&self) -> WrapCursor<'a> { 27 let mut cur = self.buf.buf(); 28 cur.advance(self.start); 29 WrapCursor { 30 cursor: cur, 31 length: self.end - self.start, 32 } 33 } 34 } 35 36 impl<'a> fmt::Debug for BlockSlice<'a> { 37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 38 write!(f, "BlockSlice {{ start: {}, end: {}, data:\n{}\n}}", self.start, self.end, self.buf.bytes().unwrap_or(&b""[..]).to_hex(16)) 39 } 40 } 41 42 impl<'a> PartialEq for BlockSlice<'a> { 43 fn eq(&self, other: &BlockSlice<'a>) -> bool { 44 let bufs = (self.buf as *const BlockBuf) == (other.buf as *const BlockBuf); 45 self.start == other.start && self.end == other.end && bufs 46 } 47 } 48 49 impl<'a> Slice<Range<usize>> for BlockSlice<'a> { 50 fn slice(&self, range:Range<usize>) -> Self { 51 BlockSlice { 52 buf: self.buf, 53 start: self.start + range.start, 54 //FIXME: check for valid end here 55 end: self.start + range.end, 56 } 57 } 58 } 59 60 impl<'a> Slice<RangeTo<usize>> for BlockSlice<'a> { 61 fn slice(&self, range:RangeTo<usize>) -> Self { 62 self.slice(0..range.end) 63 } 64 } 65 66 impl<'a> Slice<RangeFrom<usize>> for BlockSlice<'a> { 67 fn slice(&self, range:RangeFrom<usize>) -> Self { 68 self.slice(range.start..self.end - self.start) 69 } 70 } 71 72 impl<'a> Slice<RangeFull> for BlockSlice<'a> { 73 fn slice(&self, _:RangeFull) -> Self { 74 BlockSlice { 75 buf: self.buf, 76 start: self.start, 77 end: self.end, 78 } 79 } 80 } 81 82 83 impl<'a> InputIter for BlockSlice<'a> { 84 type Item = u8; 85 type RawItem = u8; 86 type Iter = Enumerate<WrapCursor<'a>>; 87 type IterElem = WrapCursor<'a>; 88 89 fn iter_indices(&self) -> Self::Iter { 90 self.cursor().enumerate() 91 } 92 fn iter_elements(&self) -> Self::IterElem { 93 self.cursor() 94 } 95 fn position<P>(&self, predicate: P) -> Option<usize> where P: Fn(Self::RawItem) -> bool { 96 self.cursor().position(|b| predicate(b)) 97 } 98 fn slice_index(&self, count:usize) -> Option<usize> { 99 if self.end - self.start >= count { 100 Some(count) 101 } else { 102 None 103 } 104 } 105 } 106 107 108 impl<'a> InputLength for BlockSlice<'a> { 109 fn input_len(&self) -> usize { 110 self.end - self.start 111 } 112 } 113 114 impl<'a,'b> Compare<&'b[u8]> for BlockSlice<'a> { 115 fn compare(&self, t: &'b[u8]) -> CompareResult { 116 let len = self.end - self.start; 117 let blen = t.len(); 118 let m = if len < blen { len } else { blen }; 119 let reduced = self.slice(..m); 120 let b = &t[..m]; 121 122 for (a,b) in reduced.cursor().zip(b.iter()) { 123 if a != *b { 124 return CompareResult::Error; 125 } 126 } 127 if m < blen { 128 CompareResult::Incomplete 129 } else { 130 CompareResult::Ok 131 } 132 } 133 134 135 #[inline(always)] 136 fn compare_no_case(&self, t: &'b[u8]) -> CompareResult { 137 let len = self.end - self.start; 138 let blen = t.len(); 139 let m = if len < blen { len } else { blen }; 140 let reduced = self.slice(..m); 141 let other = &t[..m]; 142 143 if !reduced.cursor().zip(other).all(|(a, b)| { 144 match (a,*b) { 145 (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == *b, 146 (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122 ) |(97...122, 65...90) => { 147 a & 0b01000000 == *b & 0b01000000 148 } 149 _ => false 150 } 151 }) { 152 CompareResult::Error 153 } else if m < blen { 154 CompareResult::Incomplete 155 } else { 156 CompareResult::Ok 157 } 158 } 159 } 160 161 impl<'a,'b> Compare<&'b str> for BlockSlice<'a> { 162 fn compare(&self, t: &'b str) -> CompareResult { 163 self.compare(str::as_bytes(t)) 164 } 165 fn compare_no_case(&self, t: &'b str) -> CompareResult { 166 self.compare_no_case(str::as_bytes(t)) 167 } 168 } 169 170 //Wrapper to implement Iterator on BlockBufCursor 171 pub struct WrapCursor<'a> { 172 pub cursor: BlockBufCursor<'a>, 173 pub length: usize, 174 } 175 176 impl<'a> Iterator for WrapCursor<'a> { 177 type Item = u8; 178 fn next(&mut self) -> Option<u8> { 179 //println!("NEXT: length={}, remaining={}", self.length, self.cursor.remaining()); 180 if min(self.length, self.cursor.remaining()) > 0 { 181 self.length -=1; 182 Some(self.cursor.read_u8()) 183 } else { 184 None 185 } 186 } 187 } 188 189 //Reimplement eat_separator instead of fixing iterators 190 #[macro_export] 191 macro_rules! block_eat_separator ( 192 ($i:expr, $arr:expr) => ( 193 { 194 use nom::{InputLength,InputIter,Slice}; 195 if ($i).input_len() == 0 { 196 Ok(($i, ($i).slice(0..0))) 197 } else { 198 match ($i).iter_indices().position(|(_, item)| { 199 for (_,c) in ($arr).iter_indices() { 200 if *c == item { return false; } 201 } 202 true 203 }) { 204 Some(index) => { 205 Ok((($i).slice(index..), ($i).slice(..index))) 206 }, 207 None => { 208 Ok((($i).slice(($i).input_len()..), $i)) 209 } 210 } 211 } 212 } 213 ) 214 ); 215 216 #[macro_export] 217 macro_rules! block_named ( 218 ($name:ident, $submac:ident!( $($args:tt)* )) => ( 219 fn $name<'a>( i: BlockSlice<'a> ) -> nom::IResult<BlockSlice<'a>, BlockSlice<'a>, u32> { 220 $submac!(i, $($args)*) 221 } 222 ); 223 ($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => ( 224 fn $name<'a>( i: BlockSlice<'a> ) -> nom::IResult<BlockSlice<'a>, $o, u32> { 225 $submac!(i, $($args)*) 226 } 227 ); 228 ); 229 230 block_named!(sp, block_eat_separator!(&b" \t\r\n"[..])); 231 232 macro_rules! block_ws ( 233 ($i:expr, $($args:tt)*) => ( 234 { 235 sep!($i, sp, $($args)*) 236 } 237 ) 238 ); 239 240 block_named!(digit, is_a!("0123456789")); 241 242 block_named!(parens<i64>, block_ws!(delimited!( tag!("("), expr, tag!(")") )) ); 243 244 245 block_named!(factor<i64>, alt!( 246 map_res!( 247 block_ws!(digit), 248 to_i64 249 ) 250 | parens 251 ) 252 ); 253 254 block_named!(term <i64>, do_parse!( 255 init: factor >> 256 res: fold_many0!( 257 pair!(alt!(tag!("*") | tag!("/")), factor), 258 init, 259 |acc, (op, val): (BlockSlice, i64)| { 260 if (op.cursor().next().unwrap() as char) == '*' { acc * val } else { acc / val } 261 } 262 ) >> 263 (res) 264 ) 265 ); 266 267 block_named!(expr <i64>, do_parse!( 268 init: term >> 269 res: fold_many0!( 270 pair!(alt!(tag!("+") | tag!("-")), term), 271 init, 272 |acc, (op, val): (BlockSlice, i64)| { 273 if (op.cursor().next().unwrap() as char) == '+' { acc + val } else { acc - val } 274 } 275 ) >> 276 (res) 277 ) 278 ); 279 280 281 fn blockbuf_from(input: &[u8]) -> BlockBuf { 282 let mut b = BlockBuf::new(2, 100); 283 b.copy_from(input); 284 b 285 } 286 287 288 fn sl<'a>(input: &'a BlockBuf) -> BlockSlice<'a> { 289 BlockSlice { 290 buf: input, 291 start: 0, 292 end: input.len(), 293 } 294 } 295 296 fn to_i64<'a>(input: BlockSlice<'a>) -> Result<i64, ()> { 297 let v: Vec<u8> = input.cursor().collect(); 298 299 match str::from_utf8(&v) { 300 Err(_) => Err(()), 301 Ok(s) => match FromStr::from_str(s) { 302 Err(_) => Err(()), 303 Ok(i) => Ok(i) 304 } 305 } 306 } 307 308 #[test] 309 fn factor_test() { 310 let a = blockbuf_from(&b"3"[..]); 311 println!("calculated: {:?}", factor(sl(&a))); 312 } 313 314 #[test] 315 fn parens_test() { 316 let input1 = blockbuf_from(&b" 2* ( 3 + 4 ) "[..]); 317 println!("calculated 1: {:?}", expr(sl(&input1))); 318 let input2 = blockbuf_from(&b" 2*2 / ( 5 - 1) + 3"[..]); 319 println!("calculated 2: {:?}", expr(sl(&input2))); 320 } 321 */ 322