mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2024-11-23 07:10:29 +00:00
Added UTF-16 rust::String initialization
This patch exposes String::from_utf16 to the C++ interface for rust::String.
This commit is contained in:
parent
c59a4022cd
commit
31a410246a
@ -43,6 +43,8 @@ public:
|
||||
String(const std::string &);
|
||||
String(const char *);
|
||||
String(const char *, std::size_t);
|
||||
String(const char16_t *);
|
||||
String(const char16_t *, std::size_t);
|
||||
|
||||
String &operator=(const String &) &noexcept;
|
||||
String &operator=(String &&) &noexcept;
|
||||
|
27
src/cxx.cc
27
src/cxx.cc
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -841,6 +841,12 @@ extern "C" const char *cxx_run_test() noexcept {
|
||||
ASSERT(cstr == "foo");
|
||||
ASSERT(other_cstr == "test");
|
||||
|
||||
const char *utf8_literal = u8"Test string";
|
||||
const char16_t *utf16_literal = u"Test string";
|
||||
rust::String utf8_rstring = utf8_literal;
|
||||
rust::String utf16_rstring = utf16_literal;
|
||||
ASSERT(utf8_rstring == utf16_rstring);
|
||||
|
||||
rust::Vec<int> vec1{1, 2};
|
||||
rust::Vec<int> vec2{3, 4};
|
||||
swap(vec1, vec2);
|
||||
|
Loading…
Reference in New Issue
Block a user