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