cobia/
cape_string_const_win32.rs1use crate::{C,CapeStringImpl};
2#[cfg(doc)] use crate::CapeOpenMap;
3use crate::cape_data_traits::*;
4use std::fmt;
5use crate::cape_result_value::*;
6
7#[derive(Debug)]
50pub struct CapeStringConstNoCase {
51 data: Vec<C::CapeCharacter>,
52}
53
54impl CapeStringConstNoCase {
55
56 pub fn from_string<T:AsRef<str>>(s: T) -> Self {
69 let s=s.as_ref();
70 let mut data=Vec::new();
71 data.reserve(s.len() + 1);
72 for c in s.encode_utf16() {
73 data.push(CapeStringImpl::to_lower_case(c));
74 }
75 data.push(0);
76 CapeStringConstNoCase {
77 data,
78 }
79 }
80
81 pub fn from_cape_char_const(ptr:*const C::CapeCharacter, size:C::CapeSize) -> Self {
88 let mut data=Vec::new();
89 let size=size as usize;
90 data.reserve(size+1);
91 for i in 0..size {
92 let c=unsafe { *ptr.add(i as usize) };
93 data.push(CapeStringImpl::to_lower_case(c));
94 }
95 data.push(0);
96 CapeStringConstNoCase {
97 data,
98 }
99 }
100
101 pub fn from(s:Option<&str>) -> Self {
107 match s {
108 Some(s) => {
109 Self::from_string(s)
110 }
111 None => {
112 CapeStringConstNoCase {
113 data: vec![0u16]
114 }
115 }
116 }
117 }
118
119 pub fn as_string(&self) -> String {
129 let len = self.data.len() - 1;
130 String::from_utf16_lossy(&self.data[..len])
131 }
132
133}
134
135impl fmt::Display for CapeStringConstNoCase {
136 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 if self.data.is_empty() {
147 write!(f, "")
148 } else {
149 let len = self.data.len() - 1;
150 write!(f, "{}", String::from_utf16_lossy(&self.data[..len]))
151 }
152 }
153}
154
155impl CapeStringConstProvider for CapeStringConstNoCase {
156 fn as_capechar_const(&self) -> *const C::CapeCharacter {
171 self.data.as_ptr()
172 }
173 fn as_capechar_const_with_length(&self) -> (*const C::CapeCharacter, C::CapeSize) {
188 (self.data.as_ptr() as *const C::CapeCharacter, (self.data.len() - 1) as C::CapeSize) }
190}
191
192impl<T:AsRef<str>> From<T> for CapeStringConstNoCase {
193 fn from(s: T) -> Self {
194 CapeStringConstNoCase::from_string(s)
195 }
196}
197
198impl Clone for CapeStringConstNoCase {
199 fn clone(&self) -> Self {
200 CapeStringConstNoCase {
201 data: self.data.clone(),
202 }
203 }
204}
205
206impl<T: CapeStringConstProvider> PartialEq<T> for CapeStringConstNoCase {
207 fn eq(&self, other: &T) -> bool {
208 let (ptr,len)=other.as_capechar_const_with_length();
209 let len=len as usize;
210 if self.data.len()-1 == len {
211 let mut ptr=ptr;
212 for i in 0..len {
213 if CapeStringImpl::to_lower_case(unsafe { *ptr }) != self.data[i] {
214 return false;
215 }
216 ptr=unsafe { ptr.add(1) };
217 }
218 return true;
219 }
220 false
221 }
222}
223
224impl Eq for CapeStringConstNoCase {}
225
226
227impl CapeStringConstNoCase {
228
229 extern "C" fn string_get(
230 me: *mut ::std::os::raw::c_void,
231 data: *mut *const C::CapeCharacter,
232 size: *mut C::CapeSize,
233 ) {
234 let p = me as *mut CapeStringConstNoCase;
235 let s: &mut CapeStringConstNoCase = unsafe { &mut *p };
236 unsafe {
237 *data = s.data.as_ptr() as *const C::CapeCharacter;
238 *size = s.data.len() as C::CapeSize - 1; }
240 }
241
242 extern "C" fn string_set(
243 me: *mut ::std::os::raw::c_void,
244 data: *const C::CapeCharacter,
245 size: C::CapeSize,
246 ) -> C::CapeResult {
247 let p = me as *mut CapeStringConstNoCase;
248 let s: &mut CapeStringConstNoCase = unsafe { &mut *p };
249 s.data.clear();
250 let slice=unsafe{ std::slice::from_raw_parts(data, size as usize)};
251 s.data.reserve(slice.len() + 1);
252 s.data.extend_from_slice(&slice);
253 s.data.push(0); COBIAERR_NOERROR
255 }
256
257 const CAPE_STRING_VTABLE: C::ICapeString_VTable = C::ICapeString_VTable {
258 get: Some(CapeStringConstNoCase::string_get),
259 set: Some(CapeStringConstNoCase::string_set),
260 };
261
262}
263
264impl CapeStringProviderIn for CapeStringConstNoCase {
265 fn as_cape_string_in(&self) -> C::ICapeString {
266 C::ICapeString {
267 vTbl:(&CapeStringConstNoCase::CAPE_STRING_VTABLE as *const C::ICapeString_VTable).cast_mut(),
268 me:(self as *const CapeStringConstNoCase).cast_mut() as *mut ::std::os::raw::c_void
269 }
270 }
271}
272
273#[derive(Debug)]
292pub enum CapeStringHashKey<'a> {
293 Owned(CapeStringConstNoCase),
294 Borrowed(*const C::CapeCharacter, C::CapeSize,std::marker::PhantomData<&'a ()>),
295}
296
297
298unsafe impl<'a> Send for CapeStringHashKey<'a> {}
302unsafe impl<'a> Sync for CapeStringHashKey<'a> {}
303
304impl<'a> CapeStringHashKey<'a> {
305
306 pub fn from_string<T:AsRef<str>>(s: T) -> Self {
313 CapeStringHashKey::Owned(CapeStringConstNoCase::from_string(s))
314 }
315
316 pub fn from_cape_char_const(ptr:*const C::CapeCharacter, size:C::CapeSize) -> Self {
323 CapeStringHashKey::Owned(CapeStringConstNoCase::from_cape_char_const(ptr,size))
324 }
325
326 pub fn from_string_constant<'b,T:CapeStringConstProvider>(c: &'b T) -> CapeStringHashKey<'b> {
333 let (ptr,len)=c.as_capechar_const_with_length();
334 CapeStringHashKey::Borrowed(ptr,len,std::default::Default::default())
335 }
336 pub fn as_string(&self) -> String {
346 let (ptr,len)=match self {
347 CapeStringHashKey::Owned(str_no_case) => {
348 str_no_case.as_capechar_const_with_length()
349 }
350 CapeStringHashKey::Borrowed(ptr,len,_) => {
351 (*ptr,*len)
352 }
353 };
354 if len==0 {
355 String::new()
356 } else {
357 let data=unsafe { std::slice::from_raw_parts(ptr,len as usize) };
358 String::from_utf16_lossy(&data)
359 }
360 }
361
362}
363
364impl<'a> std::fmt::Display for CapeStringHashKey<'a> {
365 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
375 let (ptr,len)=match self {
376 CapeStringHashKey::Owned(str_no_case) => {
377 str_no_case.as_capechar_const_with_length()
378 }
379 CapeStringHashKey::Borrowed(ptr,len,_) => {
380 (*ptr,*len)
381 }
382 };
383 if len == (0 as C::CapeSize) {
384 write!(f, "")
385 } else {
386 let slice = unsafe { std::slice::from_raw_parts(ptr, len as usize) };
387 write!(f, "{}", String::from_utf16_lossy(slice))
388 }
389 }
390}
391
392impl<'a> PartialEq for CapeStringHashKey<'a> {
393 fn eq(&self, other: &Self) -> bool {
394 match self {
396 CapeStringHashKey::Owned(data) => {
397 let (my_ptr,my_len)=data.as_capechar_const_with_length();
398 match other {
399 CapeStringHashKey::Owned(other_data) => {
400 let (other_ptr,other_len)=other_data.as_capechar_const_with_length();
401 if other_len==my_len {
402 let mut my_ptr=my_ptr;
403 let mut other_ptr=other_ptr;
404 let my_ptr_end=unsafe { my_ptr.add(my_len as usize) };
405 while my_ptr!=my_ptr_end {
406 if unsafe { *other_ptr } != unsafe { *my_ptr } {
407 return false;
408 }
409 my_ptr=unsafe { my_ptr.add(1) };
410 other_ptr=unsafe { other_ptr.add(1) };
411 }
412 return true;
413 }
414 false
415 }
416 CapeStringHashKey::Borrowed(other_ptr,other_len,_) => {
417 if *other_len==my_len {
418 let mut my_ptr=my_ptr;
419 let mut other_ptr=*other_ptr;
420 let my_ptr_end=unsafe { my_ptr.add(my_len as usize) };
421 while my_ptr!=my_ptr_end {
422 if CapeStringImpl::to_lower_case(unsafe { *other_ptr }) != unsafe { *my_ptr } {
423 return false;
424 }
425 my_ptr=unsafe { my_ptr.add(1) };
426 other_ptr=unsafe { other_ptr.add(1) };
427 }
428 return true;
429 }
430 false
431 }
432 }
433 },
434 CapeStringHashKey::Borrowed(my_ptr,my_len,_) => {
435 let my_len=*my_len;
436 match other {
437 CapeStringHashKey::Owned(other_data) => {
438 let (other_ptr,other_len)=other_data.as_capechar_const_with_length();
439 if other_len==my_len {
440 let mut my_ptr=*my_ptr;
441 let mut other_ptr=other_ptr;
442 let my_ptr_end=unsafe { my_ptr.add(my_len as usize) };
443 while my_ptr!=my_ptr_end {
444 if unsafe { *other_ptr } != CapeStringImpl::to_lower_case(unsafe { *my_ptr }) {
445 return false;
446 }
447 my_ptr=unsafe { my_ptr.add(1) };
448 other_ptr=unsafe { other_ptr.add(1) };
449 }
450 return true;
451 }
452 false
453 }
454 CapeStringHashKey::Borrowed(other_ptr,other_len,_) => {
455 if *other_len==my_len {
456 let mut my_ptr=*my_ptr;
457 let mut other_ptr=*other_ptr;
458 let my_ptr_end=unsafe { my_ptr.add(my_len as usize) };
459 while my_ptr!=my_ptr_end {
460 if CapeStringImpl::to_lower_case(unsafe { *other_ptr }) != CapeStringImpl::to_lower_case(unsafe { *my_ptr }) {
461 return false;
462 }
463 my_ptr=unsafe { my_ptr.add(1) };
464 other_ptr=unsafe { other_ptr.add(1) };
465 }
466 return true;
467 }
468 false
469 }
470 }
471 }
472 }
473 }
474}
475
476impl<'a> Eq for CapeStringHashKey<'a> {}
477
478impl<'a> std::hash::Hash for CapeStringHashKey<'a> {
479 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
480 match self {
481 CapeStringHashKey::Owned(data) => {
482 let (my_ptr,my_len)=data.as_capechar_const_with_length();
483 let mut my_ptr=my_ptr;
484 let my_ptr_end=unsafe { my_ptr.add(my_len as usize) };
485 while my_ptr!=my_ptr_end {
486 unsafe { (*my_ptr).hash(state) }; my_ptr=unsafe { my_ptr.add(1) };
488 }
489 }
490 CapeStringHashKey::Borrowed(my_ptr,my_len,_) => {
491 let mut my_ptr=*my_ptr;
492 let my_ptr_end=unsafe { my_ptr.add(*my_len as usize) };
493 while my_ptr!=my_ptr_end {
494 CapeStringImpl::to_lower_case(unsafe { *my_ptr} ).hash(state);
495 my_ptr=unsafe { my_ptr.add(1) };
496 }
497 }
498 }
499 }
500}
501