|
133 | 133 | #[cfg(not(windows))]
|
134 | 134 | use std::os::unix::prelude::*;
|
135 | 135 | use std::{
|
| 136 | + borrow::Cow, |
136 | 137 | char,
|
137 | 138 | cmp::{Eq, Ordering, PartialEq},
|
138 | 139 | collections::HashMap,
|
@@ -502,72 +503,81 @@ impl<'a, P: Ptr, T: ?Sized + ToGlibPtr<'a, P>> ToGlibPtr<'a, P> for &'a T {
|
502 | 503 | }
|
503 | 504 |
|
504 | 505 | impl<'a> ToGlibPtr<'a, *const c_char> for str {
|
505 |
| - type Storage = CString; |
| 506 | + type Storage = Cow<'static, [u8]>; |
506 | 507 |
|
507 |
| - #[inline] |
508 | 508 | fn to_glib_none(&'a self) -> Stash<'a, *const c_char, Self> {
|
509 |
| - let tmp = |
510 |
| - CString::new(self).expect("str::ToGlibPtr<*const c_char>: unexpected '\0' character"); |
511 |
| - Stash(tmp.as_ptr(), tmp) |
| 509 | + static EMPTY_STRING: &[u8] = &[0]; |
| 510 | + |
| 511 | + let bytes = if self.is_empty() { |
| 512 | + Cow::Borrowed(EMPTY_STRING) |
| 513 | + } else { |
| 514 | + if cfg!(debug_assertions) { |
| 515 | + crate::GStr::check_interior_nuls(self).unwrap(); |
| 516 | + } |
| 517 | + let mut bytes = Vec::with_capacity(self.len() + 1); |
| 518 | + unsafe { |
| 519 | + ptr::copy_nonoverlapping(self.as_ptr(), bytes.as_mut_ptr(), self.len()); |
| 520 | + bytes.as_mut_ptr().add(self.len()).write(0); |
| 521 | + bytes.set_len(self.len() + 1); |
| 522 | + } |
| 523 | + Cow::Owned(bytes) |
| 524 | + }; |
| 525 | + Stash(bytes.as_ptr() as *const c_char, bytes) |
512 | 526 | }
|
513 | 527 |
|
514 | 528 | #[inline]
|
515 | 529 | fn to_glib_full(&self) -> *const c_char {
|
| 530 | + if cfg!(debug_assertions) { |
| 531 | + crate::GStr::check_interior_nuls(self).unwrap(); |
| 532 | + } |
516 | 533 | unsafe {
|
517 | 534 | ffi::g_strndup(self.as_ptr() as *const c_char, self.len() as size_t) as *const c_char
|
518 | 535 | }
|
519 | 536 | }
|
520 | 537 | }
|
521 | 538 |
|
522 | 539 | impl<'a> ToGlibPtr<'a, *mut c_char> for str {
|
523 |
| - type Storage = CString; |
| 540 | + type Storage = Cow<'static, [u8]>; |
524 | 541 |
|
525 | 542 | #[inline]
|
526 | 543 | fn to_glib_none(&'a self) -> Stash<'a, *mut c_char, Self> {
|
527 |
| - let tmp = |
528 |
| - CString::new(self).expect("str::ToGlibPtr<*mut c_char>: unexpected '\0' character"); |
529 |
| - Stash(tmp.as_ptr() as *mut c_char, tmp) |
| 544 | + let s = ToGlibPtr::<*const c_char>::to_glib_none(self); |
| 545 | + Stash(s.0 as *mut _, s.1) |
530 | 546 | }
|
531 | 547 |
|
532 | 548 | #[inline]
|
533 | 549 | fn to_glib_full(&self) -> *mut c_char {
|
534 |
| - unsafe { ffi::g_strndup(self.as_ptr() as *mut c_char, self.len() as size_t) } |
| 550 | + ToGlibPtr::<*const c_char>::to_glib_full(self) as *mut _ |
535 | 551 | }
|
536 | 552 | }
|
537 | 553 |
|
538 | 554 | impl<'a> ToGlibPtr<'a, *const c_char> for String {
|
539 |
| - type Storage = CString; |
| 555 | + type Storage = Cow<'static, [u8]>; |
540 | 556 |
|
541 | 557 | #[inline]
|
542 | 558 | fn to_glib_none(&self) -> Stash<'a, *const c_char, String> {
|
543 |
| - let tmp = CString::new(&self[..]) |
544 |
| - .expect("String::ToGlibPtr<*const c_char>: unexpected '\0' character"); |
545 |
| - Stash(tmp.as_ptr(), tmp) |
| 559 | + let s = ToGlibPtr::to_glib_none(self.as_str()); |
| 560 | + Stash(s.0, s.1) |
546 | 561 | }
|
547 | 562 |
|
548 | 563 | #[inline]
|
549 | 564 | fn to_glib_full(&self) -> *const c_char {
|
550 |
| - unsafe { |
551 |
| - ffi::g_strndup(self.as_ptr() as *const c_char, self.len() as size_t) as *const c_char |
552 |
| - } |
| 565 | + ToGlibPtr::to_glib_full(self.as_str()) |
553 | 566 | }
|
554 | 567 | }
|
555 | 568 |
|
556 | 569 | impl<'a> ToGlibPtr<'a, *mut c_char> for String {
|
557 |
| - type Storage = CString; |
| 570 | + type Storage = Cow<'static, [u8]>; |
558 | 571 |
|
559 | 572 | #[inline]
|
560 | 573 | fn to_glib_none(&self) -> Stash<'a, *mut c_char, String> {
|
561 |
| - let tmp = CString::new(&self[..]) |
562 |
| - .expect("String::ToGlibPtr<*mut c_char>: unexpected '\0' character"); |
563 |
| - Stash(tmp.as_ptr() as *mut c_char, tmp) |
| 574 | + let s = ToGlibPtr::to_glib_none(self.as_str()); |
| 575 | + Stash(s.0, s.1) |
564 | 576 | }
|
565 | 577 |
|
566 | 578 | #[inline]
|
567 | 579 | fn to_glib_full(&self) -> *mut c_char {
|
568 |
| - unsafe { |
569 |
| - ffi::g_strndup(self.as_ptr() as *const c_char, self.len() as size_t) as *mut c_char |
570 |
| - } |
| 580 | + ToGlibPtr::to_glib_full(self.as_str()) |
571 | 581 | }
|
572 | 582 | }
|
573 | 583 |
|
|
0 commit comments