44[ ![ crates.io] ( http://meritbadge.herokuapp.com/clucstr )] ( https://crates.io/crates/clucstr )
55[ ![ Documentation] ( https://docs.rs/clucstr/badge.svg )] ( https://docs.rs/clucstr )
66
7- Creation of strings C with zero cost. A plug-in for the rust compiler .
7+ Safe creation of 'CStr' with zero cost at a compilation stage with check of zero bytes and a possibility of communication of several values .
88
99# Features
10- 1 . The transparent creation of the C strings with zero cost.
11- 2 . Check of the C lines at the level of the compiler.
12- 3 . Convenient macro for creation of lines.
13- 4 . Plug-in for the compiler.
14-
10+ 1 . Creation of safe CStr at a compilation stage.
11+ 2 . Check of zero bytes at a stage of compilation or checks of "Rls or Rust check".
12+ 3 . Concatenation of several values, different types: [ u8] , & 'static str, u8, i8, (0 without specifying the type).
13+ 4 . All actions happen at a compilation stage, processor time is not required.
1514
1615# Use
1716```
@@ -21,124 +20,137 @@ Creation of strings C with zero cost. A plug-in for the rust compiler.
2120use std::ffi::CStr;
2221
2322fn main() {
24- let c_str = cstr!("cluWorld!!!");
25- let c_str_barr = cstr!(b"cluWorld!!!");
26- let c_str_b = cstr!(b'A');
27- }
28- ```
29-
30- ```
31- #![feature(plugin)]
32- #![plugin(clucstr)]
33-
34- use std::ffi::CStr;
35-
36- fn main() {
37- println_str(cstr!("cluWorld!!!"));
38- //CSTR "cluWorld!!!"
39- //CArray [99, 108, 117, 87, 111, 114, 108, 100, 33, 33, 33, 0] 12
40-
41- println_str(cstr!(b"cluWorld!!!"));
42- //CSTR "cluWorld!!!"
43- //CArray [99, 108, 117, 87, 111, 114, 108, 100, 33, 33, 33, 0] 12
44-
45- println_str(cstr!(b'A'));
46- //CSTR "A"
47- //CArray [65, 0] 2
23+ let c_str = cstr!("cluWorld");
24+ //"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
25+
26+ let c_str2 = cstr!("cluWorld\0");
27+ //"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
28+
29+ let c_str3 = cstr!("clu", b"World");
30+ //"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
31+
32+ let c_str4 = cstr!(
33+ b'c', b'l', b'u',
34+ b'W', b'o', b'r', b'l', b'd',
35+ 0
36+ );
37+ //"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
38+
39+ let c_str5 = cstr!(
40+ "clu",
41+ //It is possible to insert such values as: [u8], & 'static str, u8, i8, (0 without specifying the type).
42+
43+ b'W', b'o', b'r', b'l', b"d\0"
44+ //The zero byte is automatically added, it is possible to write it, and it is possible not to write.
45+ //It is forbidden to insert zero byte in the middle or at the beginning of a line.
46+ );
47+ //"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
48+
49+ my_function(c_str);
50+ my_function(c_str2);
51+ my_function(c_str3);
52+ my_function(c_str4);
53+ my_function(c_str5);
4854}
4955
50-
51- fn println_str(cstr: &CStr) {
52- println!("CSTR {:?}", cstr);
53-
54- let cstr_array = cstr.to_bytes_with_nul();
55- println!("CArray {:?} {}", cstr_array, cstr_array.len());
56- println!();
56+ fn my_function(a: &'static CStr) {
57+ //'static --> it is possible not to write.
58+
59+ let c_arr = a.to_bytes_with_nul();
60+ println!("{:?} <-- array: {:?}, len: {}", a, c_arr, c_arr.len());
5761}
5862```
5963
6064# Panic
6165```
66+
6267#![feature(plugin)]
6368#![plugin(clucstr)]
6469
70+ #[allow(unused_imports)]
6571use std::ffi::CStr;
6672
6773fn main() {
68- let c_str = cstr!("\0Test_str ");
69- // PANIC! A null byte was found.
74+ // let c_str = cstr!("cluW\0orld ");
75+ //PANIC! trailing byte detected
7076
71- let c_str = cstr!(b"\0Test_array ");
72- // PANIC! A null byte was found.
77+ // let c_str2 = cstr!("cluWorld\0\0 ");
78+ //PANIC! trailing byte detected
7379
74- let c_str = cstr!("Test_str\0");
75- //It is allowed to write since the null byte is at the end.
80+ // let c_str3 = cstr!("\0clu", b"W\0orld");
81+ //PANIC! trailing byte detected
7682
77- let c_str = cstr!(b"Test_str\0");
78- //It is allowed to write since the null byte is at the end.
83+ /*let c_str4 = cstr!(
84+ b'c', b'l', b'u', 0u8,
85+ b'W', b'o', b'r', b'l', b'd',
86+ 0
87+ );*/
88+ //PANIC! trailing byte detected
7989}
8090```
8191
8292# Benchmarking
83- cstr_macros - old method of converting strings to cstr. Note that in CStr, there is no protection from null bytes.
8493
85- cstr_plugin - new method for converting strings to cstr.
8694```
87- #![feature(plugin)]
88- #![plugin(clucstr)]
8995#![feature(test)]
9096
91- extern crate test;
92- use std::ffi::CStr;
93-
94-
95- #[macro_export]
96- macro_rules! cstr_macro {
97- ($s:expr) => {
98- unsafe {
99- ::std::ffi::CStr::from_ptr(
100- concat!($s, "\0")
101- as *const str
102- as *const [::std::os::raw::c_char]
103- as *const ::std::os::raw::c_char
104- )
105- }
106- };
107- }
97+ #![feature(plugin)]
98+ #![plugin(clucstr)]
10899
109100
110101#[cfg(test)]
111102mod tests {
112- use super::*;
113- use test::Bencher;
114-
115- #[bench]
116- fn cstr_plugin(b: &mut Bencher) {
117- b.iter(|| {
118- for _a in 0..10 {
119- let _cstr0 = cstr!(b"test");
120- }
121- });
122- }
123- #[bench]
124- fn cstr_macros(b: &mut Bencher) {
125- b.iter(|| {
126- for _a in 0..10 {
127- let _cstr0 = cstr_macro!("test");
128- }
129- });
130- }
103+ use super::*;
104+ use tests::test::Bencher;
105+ use std::ffi::CStr;
106+
107+ extern crate test;
108+
109+
110+
111+ macro_rules! unsafe_cstr {
112+ ($s:expr) => {
113+ unsafe {
114+ ::std::ffi::CStr::from_ptr(
115+ concat!($s, "\0")
116+ as *const str
117+ as *const [::std::os::raw::c_char]
118+ as *const ::std::os::raw::c_char
119+ )
120+ }
121+ };
122+ }
123+
124+ #[bench]
125+ fn cstr_plugin(b: &mut Bencher) {
126+ b.iter(|| {
127+ for _a in 0..10 {
128+ let _cstr0 = cstr!(b"test");
129+ }
130+ });
131+ }
132+ #[bench]
133+ fn cstr_macros(b: &mut Bencher) {
134+ b.iter(|| {
135+ for _a in 0..10 {
136+ let _cstr0 = unsafe_cstr!("test");
137+ }
138+ });
139+ }
131140}
132141```
133142running 2 tests
134143
135- test tests::cstr_macros ... bench: 90 ns/iter (+/- 14)
144+ test tests::cstr_macros ... bench: 67 ns/iter (+/- 1) !Attention ns > 0, full unsafe, no guarantees
145+
146+ test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0) !Attention ns == 0, plus zero byte checking and plus concatenation
136147
137- test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0)
148+ # Launch benchmark:
138149
150+ cargo bench --example bench
139151
140152# License
141153
142- Copyright 2018 #UlinProject Денис Котляров
154+ Copyright 2019 #UlinProject Denis Kotlyarov ( Денис Котляров)
143155
144- Licensed under the Apache License, Version 2.0
156+ Licensed under the Apache License, Version 2.0
0 commit comments