]> git.proxmox.com Git - rustc.git/blob - vendor/windows-sys-0.42.0/src/core/literals.rs
New upstream version 1.70.0+dfsg1
[rustc.git] / vendor / windows-sys-0.42.0 / src / core / literals.rs
1 /// A literal UTF-8 string with a trailing null terminator.
2 #[macro_export]
3 macro_rules! s {
4 ($s:literal) => {
5 ::core::concat!($s, '\0').as_ptr()
6 };
7 }
8
9 /// A literal UTF-16 wide string with a trailing null terminator.
10 #[macro_export]
11 macro_rules! w {
12 ($s:literal) => {{
13 const INPUT: &[u8] = $s.as_bytes();
14 const OUTPUT_LEN: usize = $crate::core::utf16_len(INPUT) + 1;
15 const OUTPUT: &[u16; OUTPUT_LEN] = {
16 let mut buffer = [0; OUTPUT_LEN];
17 let mut input_pos = 0;
18 let mut output_pos = 0;
19 while let Some((mut code_point, new_pos)) = $crate::core::decode_utf8_char(INPUT, input_pos) {
20 input_pos = new_pos;
21 if code_point <= 0xffff {
22 buffer[output_pos] = code_point as u16;
23 output_pos += 1;
24 } else {
25 code_point -= 0x10000;
26 buffer[output_pos] = 0xd800 + (code_point >> 10) as u16;
27 output_pos += 1;
28 buffer[output_pos] = 0xdc00 + (code_point & 0x3ff) as u16;
29 output_pos += 1;
30 }
31 }
32 &{ buffer }
33 };
34 OUTPUT.as_ptr()
35 }};
36 }
37
38 // Ensures that the macros are exported from the `windows::core` module.
39 pub use s;
40 pub use w;
41
42 #[doc(hidden)]
43 pub const fn decode_utf8_char(bytes: &[u8], mut pos: usize) -> Option<(u32, usize)> {
44 if bytes.len() == pos {
45 return None;
46 }
47 let ch = bytes[pos] as u32;
48 pos += 1;
49 if ch <= 0x7f {
50 return Some((ch, pos));
51 }
52 if (ch & 0xe0) == 0xc0 {
53 if bytes.len() - pos < 1 {
54 return None;
55 }
56 let ch2 = bytes[pos] as u32;
57 pos += 1;
58 if (ch2 & 0xc0) != 0x80 {
59 return None;
60 }
61 let result: u32 = ((ch & 0x1f) << 6) | (ch2 & 0x3f);
62 if result <= 0x7f {
63 return None;
64 }
65 return Some((result, pos));
66 }
67 if (ch & 0xf0) == 0xe0 {
68 if bytes.len() - pos < 2 {
69 return None;
70 }
71 let ch2 = bytes[pos] as u32;
72 pos += 1;
73 let ch3 = bytes[pos] as u32;
74 pos += 1;
75 if (ch2 & 0xc0) != 0x80 || (ch3 & 0xc0) != 0x80 {
76 return None;
77 }
78 let result = ((ch & 0x0f) << 12) | ((ch2 & 0x3f) << 6) | (ch3 & 0x3f);
79 if result <= 0x7ff || (0xd800 <= result && result <= 0xdfff) {
80 return None;
81 }
82 return Some((result, pos));
83 }
84 if (ch & 0xf8) == 0xf0 {
85 if bytes.len() - pos < 3 {
86 return None;
87 }
88 let ch2 = bytes[pos] as u32;
89 pos += 1;
90 let ch3 = bytes[pos] as u32;
91 pos += 1;
92 let ch4 = bytes[pos] as u32;
93 pos += 1;
94 if (ch2 & 0xc0) != 0x80 || (ch3 & 0xc0) != 0x80 || (ch4 & 0xc0) != 0x80 {
95 return None;
96 }
97 let result = ((ch & 0x07) << 18) | ((ch2 & 0x3f) << 12) | ((ch3 & 0x3f) << 6) | (ch4 & 0x3f);
98 if result <= 0xffff || 0x10ffff < result {
99 return None;
100 }
101 return Some((result, pos));
102 }
103 None
104 }
105
106 #[doc(hidden)]
107 pub const fn utf16_len(bytes: &[u8]) -> usize {
108 let mut pos = 0;
109 let mut len = 0;
110 while let Some((code_point, new_pos)) = decode_utf8_char(bytes, pos) {
111 pos = new_pos;
112 len += if code_point <= 0xffff { 1 } else { 2 };
113 }
114 len
115 }