ini_core/parse/
mod.rs

1/*!
2Optimized routines for parsing INI.
3
4This module provides 2 functions: `find_nl` and `find_nl_chr`:
5
6* `fn find_nl(s: &[u8]) -> usize`
7
8  Finds the first `b'\r'` or `b'\n'` in the input byte string and returns its index.
9  If no match was found returns the length of the input.
10
11* `fn find_nl_chr(s: &[u8], chr: u8) -> usize`
12
13  Finds the first `b'\r'`, `b'\n'` or `chr` in the input byte string and returns its index.
14  If no match was found returns the length of the input.
15
16For more information on the SWAR approaches see: <http://0x80.pl/articles/simd-strfind.html#swar>.
17In reality I only see minor improvements with SWAR (about 33% faster).
18
19*/
20
21// LLVM is big dum dum, trust me I'm a human
22#[cfg(not(debug_assertions))]
23macro_rules! unsafe_assert {
24	($e:expr) => { unsafe { if !$e { ::core::hint::unreachable_unchecked(); } } };
25}
26#[cfg(debug_assertions)]
27macro_rules! unsafe_assert {
28	($e:expr) => {};
29}
30
31mod generic;
32
33cfg_if::cfg_if! {
34	// These optimizations are little endian specific
35	if #[cfg(not(target_endian = "little"))] {
36		pub use self::generic::*;
37	}
38	else if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "avx2"))] {
39		mod avx2;
40		pub use self::avx2::*;
41	}
42	else if #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))] {
43		mod sse2;
44		pub use self::sse2::*;
45	}
46	else if #[cfg(target_pointer_width = "64")] {
47		mod swar64;
48		pub use self::swar64::*;
49	}
50	else if #[cfg(target_pointer_width = "32")] {
51		mod swar32;
52		pub use self::swar32::*;
53	}
54	else {
55		pub use self::generic::*;
56	}
57}
58
59#[test]
60fn test_parse() {
61	let mut buffer = [b'-'; 254];
62	for i in 0..buffer.len() {
63		buffer[i] = b'\n';
64
65		// Check reference implementation
66		assert_eq!(generic::find_nl(&buffer), i);
67		assert_eq!(generic::find_nl_chr(&buffer, b'='), i);
68
69		// Check target implementation
70		assert_eq!(find_nl(&buffer), i);
71		assert_eq!(find_nl_chr(&buffer, b'='), i);
72
73		// Write annoying byte back
74		buffer[i] = if i & 1 == 0 { !0x0D } else { !0x0A };
75	}
76}