4
4
[ ![ crates.io] ( http://meritbadge.herokuapp.com/clucstr )] ( https://crates.io/crates/clucstr )
5
5
[ ![ Documentation] ( https://docs.rs/clucstr/badge.svg )] ( https://docs.rs/clucstr )
6
6
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 .
8
8
9
9
# 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.
15
14
16
15
# Use
17
16
```
@@ -21,124 +20,137 @@ Creation of strings C with zero cost. A plug-in for the rust compiler.
21
20
use std::ffi::CStr;
22
21
23
22
fn 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);
48
54
}
49
55
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());
57
61
}
58
62
```
59
63
60
64
# Panic
61
65
```
66
+
62
67
#![feature(plugin)]
63
68
#![plugin(clucstr)]
64
69
70
+ #[allow(unused_imports)]
65
71
use std::ffi::CStr;
66
72
67
73
fn 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
70
76
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
73
79
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
76
82
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
79
89
}
80
90
```
81
91
82
92
# Benchmarking
83
- cstr_macros - old method of converting strings to cstr. Note that in CStr, there is no protection from null bytes.
84
93
85
- cstr_plugin - new method for converting strings to cstr.
86
94
```
87
- #![feature(plugin)]
88
- #![plugin(clucstr)]
89
95
#![feature(test)]
90
96
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)]
108
99
109
100
110
101
#[cfg(test)]
111
102
mod 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
+ }
131
140
}
132
141
```
133
142
running 2 tests
134
143
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
136
147
137
- test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0)
148
+ # Launch benchmark:
138
149
150
+ cargo bench --example bench
139
151
140
152
# License
141
153
142
- Copyright 2018 #UlinProject Денис Котляров
154
+ Copyright 2019 #UlinProject Denis Kotlyarov ( Денис Котляров)
143
155
144
- Licensed under the Apache License, Version 2.0
156
+ Licensed under the Apache License, Version 2.0
0 commit comments