1 //! Parsers recognizing numbers
2 
3 /// If the parameter is `nom::Endianness::Big`, parse a big endian u16 integer,
4 /// otherwise a little endian u16 integer.
5 ///
6 /// ```rust
7 /// # #[macro_use] extern crate nom;
8 /// # use nom::{Err, Needed};
9 /// use nom::number::Endianness;
10 ///
11 /// # fn main() {
12 /// named!(be<u16>, u16!(Endianness::Big));
13 ///
14 /// assert_eq!(be(b"\x00\x01abcd"), Ok((&b"abcd"[..], 0x0001)));
15 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(1))));
16 ///
17 /// named!(le<u16>, u16!(Endianness::Little));
18 ///
19 /// assert_eq!(le(b"\x00\x01abcd"), Ok((&b"abcd"[..], 0x0100)));
20 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(1))));
21 /// # }
22 /// ```
23 #[macro_export(local_inner_macros)]
24 macro_rules! u16 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_u16($i) } else { $crate::number::streaming::le_u16($i) } } ););
25 
26 /// If the parameter is `nom::Endianness::Big`, parse a big endian u32 integer,
27 /// otherwise a little endian u32 integer.
28 ///
29 /// ```rust
30 /// # #[macro_use] extern crate nom;
31 /// # use nom::{Err, Needed};
32 /// use nom::number::Endianness;
33 ///
34 /// # fn main() {
35 /// named!(be<u32>, u32!(Endianness::Big));
36 ///
37 /// assert_eq!(be(b"\x00\x01\x02\x03abcd"), Ok((&b"abcd"[..], 0x00010203)));
38 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(3))));
39 ///
40 /// named!(le<u32>, u32!(Endianness::Little));
41 ///
42 /// assert_eq!(le(b"\x00\x01\x02\x03abcd"), Ok((&b"abcd"[..], 0x03020100)));
43 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(3))));
44 /// # }
45 /// ```
46 #[macro_export(local_inner_macros)]
47 macro_rules! u32 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_u32($i) } else { $crate::number::streaming::le_u32($i) } } ););
48 
49 /// If the parameter is `nom::Endianness::Big`, parse a big endian u64 integer,
50 /// otherwise a little endian u64 integer.
51 ///
52 /// ```rust
53 /// # #[macro_use] extern crate nom;
54 /// # use nom::{Err, Needed};
55 /// use nom::number::Endianness;
56 ///
57 /// # fn main() {
58 /// named!(be<u64>, u64!(Endianness::Big));
59 ///
60 /// assert_eq!(be(b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"), Ok((&b"abcd"[..], 0x0001020304050607)));
61 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(7))));
62 ///
63 /// named!(le<u64>, u64!(Endianness::Little));
64 ///
65 /// assert_eq!(le(b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"), Ok((&b"abcd"[..], 0x0706050403020100)));
66 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(7))));
67 /// # }
68 /// ```
69 #[macro_export(local_inner_macros)]
70 macro_rules! u64 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_u64($i) } else { $crate::number::streaming::le_u64($i) } } ););
71 
72 /// If the parameter is `nom::Endianness::Big`, parse a big endian u128 integer,
73 /// otherwise a little endian u128 integer.
74 ///
75 /// ```rust
76 /// # #[macro_use] extern crate nom;
77 /// # use nom::{Err, Needed};
78 /// use nom::number::Endianness;
79 ///
80 /// # fn main() {
81 /// named!(be<u128>, u128!(Endianness::Big));
82 ///
83 /// assert_eq!(be(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"), Ok((&b"abcd"[..], 0x00010203040506070809101112131415)));
84 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(15))));
85 ///
86 /// named!(le<u128>, u128!(Endianness::Little));
87 ///
88 /// assert_eq!(le(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"), Ok((&b"abcd"[..], 0x15141312111009080706050403020100)));
89 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(15))));
90 /// # }
91 /// ```
92 #[macro_export(local_inner_macros)]
93 #[cfg(stable_i128)]
94 macro_rules! u128 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_u128($i) } else { $crate::number::streaming::le_u128($i) } } ););
95 
96 /// If the parameter is `nom::Endianness::Big`, parse a big endian i16 integer,
97 /// otherwise a little endian i16 integer.
98 ///
99 /// ```rust
100 /// # #[macro_use] extern crate nom;
101 /// # use nom::{Err, Needed};
102 /// use nom::number::Endianness;
103 ///
104 /// # fn main() {
105 /// named!(be<i16>, i16!(Endianness::Big));
106 ///
107 /// assert_eq!(be(b"\x00\x01abcd"), Ok((&b"abcd"[..], 0x0001)));
108 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(1))));
109 ///
110 /// named!(le<i16>, i16!(Endianness::Little));
111 ///
112 /// assert_eq!(le(b"\x00\x01abcd"), Ok((&b"abcd"[..], 0x0100)));
113 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(1))));
114 /// # }
115 /// ```
116 #[macro_export(local_inner_macros)]
117 macro_rules! i16 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_i16($i) } else { $crate::number::streaming::le_i16($i) } } ););
118 
119 /// If the parameter is `nom::Endianness::Big`, parse a big endian i32 integer,
120 /// otherwise a little endian i32 integer.
121 ///
122 /// ```rust
123 /// # #[macro_use] extern crate nom;
124 /// # use nom::{Err, Needed};
125 /// use nom::number::Endianness;
126 ///
127 /// # fn main() {
128 /// named!(be<i32>, i32!(Endianness::Big));
129 ///
130 /// assert_eq!(be(b"\x00\x01\x02\x03abcd"), Ok((&b"abcd"[..], 0x00010203)));
131 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(3))));
132 ///
133 /// named!(le<i32>, i32!(Endianness::Little));
134 ///
135 /// assert_eq!(le(b"\x00\x01\x02\x03abcd"), Ok((&b"abcd"[..], 0x03020100)));
136 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(3))));
137 /// # }
138 /// ```
139 #[macro_export(local_inner_macros)]
140 macro_rules! i32 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_i32($i) } else { $crate::number::streaming::le_i32($i) } } ););
141 
142 /// If the parameter is `nom::Endianness::Big`, parse a big endian i64 integer,
143 /// otherwise a little endian i64 integer.
144 ///
145 /// ```rust
146 /// # #[macro_use] extern crate nom;
147 /// # use nom::{Err, Needed};
148 /// use nom::number::Endianness;
149 ///
150 /// # fn main() {
151 /// named!(be<i64>, i64!(Endianness::Big));
152 ///
153 /// assert_eq!(be(b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"), Ok((&b"abcd"[..], 0x0001020304050607)));
154 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(7))));
155 ///
156 /// named!(le<i64>, i64!(Endianness::Little));
157 ///
158 /// assert_eq!(le(b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"), Ok((&b"abcd"[..], 0x0706050403020100)));
159 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(7))));
160 /// # }
161 /// ```
162 #[macro_export(local_inner_macros)]
163 macro_rules! i64 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_i64($i) } else { $crate::number::streaming::le_i64($i) } } ););
164 
165 /// If the parameter is `nom::Endianness::Big`, parse a big endian i64 integer,
166 /// otherwise a little endian i64 integer.
167 ///
168 /// ```rust
169 /// # #[macro_use] extern crate nom;
170 /// # use nom::{Err, Needed};
171 /// use nom::number::Endianness;
172 ///
173 /// # fn main() {
174 /// named!(be<i128>, i128!(Endianness::Big));
175 ///
176 /// assert_eq!(be(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"), Ok((&b"abcd"[..], 0x00010203040506070809101112131415)));
177 /// assert_eq!(be(b"\x01"), Err(Err::Incomplete(Needed::new(15))));
178 ///
179 /// named!(le<i128>, i128!(Endianness::Little));
180 ///
181 /// assert_eq!(le(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"), Ok((&b"abcd"[..], 0x15141312111009080706050403020100)));
182 /// assert_eq!(le(b"\x01"), Err(Err::Incomplete(Needed::new(15))));
183 /// # }
184 /// ```
185 #[macro_export(local_inner_macros)]
186 #[cfg(stable_i128)]
187 macro_rules! i128 ( ($i:expr, $e:expr) => ( {if $crate::number::Endianness::Big == $e { $crate::number::streaming::be_i128($i) } else { $crate::number::streaming::le_i128($i) } } ););
188 
189 #[cfg(test)]
190 mod tests {
191   use crate::number::Endianness;
192 
193   #[test]
194   fn configurable_endianness() {
195     named!(be_tst16<u16>, u16!(Endianness::Big));
196     named!(le_tst16<u16>, u16!(Endianness::Little));
197     assert_eq!(be_tst16(&[0x80, 0x00]), Ok((&b""[..], 32_768_u16)));
198     assert_eq!(le_tst16(&[0x80, 0x00]), Ok((&b""[..], 128_u16)));
199 
200     named!(be_tst32<u32>, u32!(Endianness::Big));
201     named!(le_tst32<u32>, u32!(Endianness::Little));
202     assert_eq!(
203       be_tst32(&[0x12, 0x00, 0x60, 0x00]),
204       Ok((&b""[..], 302_014_464_u32))
205     );
206     assert_eq!(
207       le_tst32(&[0x12, 0x00, 0x60, 0x00]),
208       Ok((&b""[..], 6_291_474_u32))
209     );
210 
211     named!(be_tst64<u64>, u64!(Endianness::Big));
212     named!(le_tst64<u64>, u64!(Endianness::Little));
213     assert_eq!(
214       be_tst64(&[0x12, 0x00, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
215       Ok((&b""[..], 1_297_142_246_100_992_000_u64))
216     );
217     assert_eq!(
218       le_tst64(&[0x12, 0x00, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
219       Ok((&b""[..], 36_028_874_334_666_770_u64))
220     );
221 
222     named!(be_tsti16<i16>, i16!(Endianness::Big));
223     named!(le_tsti16<i16>, i16!(Endianness::Little));
224     assert_eq!(be_tsti16(&[0x00, 0x80]), Ok((&b""[..], 128_i16)));
225     assert_eq!(le_tsti16(&[0x00, 0x80]), Ok((&b""[..], -32_768_i16)));
226 
227     named!(be_tsti32<i32>, i32!(Endianness::Big));
228     named!(le_tsti32<i32>, i32!(Endianness::Little));
229     assert_eq!(
230       be_tsti32(&[0x00, 0x12, 0x60, 0x00]),
231       Ok((&b""[..], 1_204_224_i32))
232     );
233     assert_eq!(
234       le_tsti32(&[0x00, 0x12, 0x60, 0x00]),
235       Ok((&b""[..], 6_296_064_i32))
236     );
237 
238     named!(be_tsti64<i64>, i64!(Endianness::Big));
239     named!(le_tsti64<i64>, i64!(Endianness::Little));
240     assert_eq!(
241       be_tsti64(&[0x00, 0xFF, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
242       Ok((&b""[..], 71_881_672_479_506_432_i64))
243     );
244     assert_eq!(
245       le_tsti64(&[0x00, 0xFF, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
246       Ok((&b""[..], 36_028_874_334_732_032_i64))
247     );
248   }
249 
250   //FIXME
251   /*
252   #[test]
253   #[cfg(feature = "std")]
254   fn manual_configurable_endianness_test() {
255     let x = 1;
256     let int_parse: Box<Fn(&[u8]) -> IResult<&[u8], u16, (&[u8], ErrorKind)>> = if x == 2 {
257       Box::new(be_u16)
258     } else {
259       Box::new(le_u16)
260     };
261     println!("{:?}", int_parse(&b"3"[..]));
262     assert_eq!(int_parse(&[0x80, 0x00]), Ok((&b""[..], 128_u16)));
263   }
264   */
265 }
266