diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cxx.cc | 27 | ||||
-rw-r--r-- | src/symbols/rust_string.rs | 20 |
2 files changed, 42 insertions, 5 deletions
@@ -31,8 +31,10 @@ void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr, void cxxbridge1$string$new(rust::String *self) noexcept; void cxxbridge1$string$clone(rust::String *self, const rust::String &other) noexcept; -bool cxxbridge1$string$from(rust::String *self, const char *ptr, - std::size_t len) noexcept; +bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr, + std::size_t len) noexcept; +bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, + std::size_t len) noexcept; void cxxbridge1$string$drop(rust::String *self) noexcept; const char *cxxbridge1$string$ptr(const rust::String *self) noexcept; std::size_t cxxbridge1$string$len(const rust::String *self) noexcept; @@ -81,11 +83,17 @@ String::String(String &&other) noexcept : repr(other.repr) { String::~String() noexcept { cxxbridge1$string$drop(this); } static void initString(String *self, const char *s, std::size_t len) { - if (!cxxbridge1$string$from(self, s, len)) { + if (!cxxbridge1$string$from_utf8(self, s, len)) { panic<std::invalid_argument>("data for rust::String is not utf-8"); } } +static void initString(String *self, const char16_t *s, std::size_t len) { + if (!cxxbridge1$string$from_utf16(self, s, len)) { + panic<std::invalid_argument>("data for rust::String is not utf-16"); + } +} + String::String(const std::string &s) { initString(this, s.data(), s.length()); } String::String(const char *s) { @@ -100,6 +108,19 @@ String::String(const char *s, std::size_t len) { len); } +String::String(const char16_t *s) { + assert(s != nullptr); + initString(this, s, std::char_traits<char16_t>::length(s)); +} + +String::String(const char16_t *s, std::size_t len) { + assert(s != nullptr || len == 0); + initString(this, + s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2) + : s, + len); +} + String &String::operator=(const String &other) &noexcept { if (this != &other) { cxxbridge1$string$drop(this); diff --git a/src/symbols/rust_string.rs b/src/symbols/rust_string.rs index 91fd78a3..29bcf85d 100644 --- a/src/symbols/rust_string.rs +++ b/src/symbols/rust_string.rs @@ -15,8 +15,8 @@ unsafe extern "C" fn string_clone(this: &mut MaybeUninit<String>, other: &String ptr::write(this.as_mut_ptr(), other.clone()); } -#[export_name = "cxxbridge1$string$from"] -unsafe extern "C" fn string_from( +#[export_name = "cxxbridge1$string$from_utf8"] +unsafe extern "C" fn string_from_utf8( this: &mut MaybeUninit<String>, ptr: *const u8, len: usize, @@ -31,6 +31,22 @@ unsafe extern "C" fn string_from( } } +#[export_name = "cxxbridge1$string$from_utf16"] +unsafe extern "C" fn string_from_utf16( + this: &mut MaybeUninit<String>, + ptr: *const u16, + len: usize, +) -> bool { + let slice = slice::from_raw_parts(ptr, len); + match String::from_utf16(slice) { + Ok(s) => { + ptr::write(this.as_mut_ptr(), s); + true + } + Err(_) => false, + } +} + #[export_name = "cxxbridge1$string$drop"] unsafe extern "C" fn string_drop(this: &mut ManuallyDrop<String>) { ManuallyDrop::drop(this); |