dep-protobuf/rust/cpp_kernel/strings.cc
Protobuf Team Bot 7fbb3d2cc7 Make conversion functions for into c++ string types from PtrAndLen.
The invariant is that PtrAndLen may hold ptr+len values which are legal for _either_ C++ string_view or Rust slices: constructing one from either Rust or C++ permits the laxest constraints, and care must be taken when converting a PtrAndLen into either type.

For "into Rust slice" case to handle is that len=0 ptr must be non-null, so len=0 ptr=null gets turned into an arbitrary non-null pointer as provided by std::ptr::NonNull::dangling() (any preexisting non-null ptr is kept in that direction).

For the "into C++ slice" the risk is more obscure that a Rust non-null pointer could potentially be an illegal pointer (such that ptr+0 is not a legal operation in C++), so when going into C++ we map any len=0 cases into ptr=null to avoid this as a possible risk.

PiperOrigin-RevId: 704776210
2024-12-10 11:15:00 -08:00

51 lines
1.3 KiB
C++

#include "rust/cpp_kernel/strings.h"
#include <cstring>
#include <string>
#include "absl/strings/string_view.h"
#include "rust/cpp_kernel/rust_alloc_for_cpp_api.h"
namespace google {
namespace protobuf {
namespace rust {
std::string PtrAndLen::CopyToString() const {
return len == 0 ? "" : std::string(ptr, len);
}
absl::string_view PtrAndLen::AsStringView() const {
return absl::string_view(len == 0 ? nullptr : ptr, len);
}
void PtrAndLen::PlacementNewString(void* location) {
new (location) std::string(len == 0 ? nullptr : ptr, len);
}
RustStringRawParts::RustStringRawParts(std::string src) {
if (src.empty()) {
data = nullptr;
len = 0;
} else {
void* d = proto2_rust_alloc(src.length(), 1);
std::memcpy(d, src.data(), src.length());
data = static_cast<char*>(d);
len = src.length();
}
}
} // namespace rust
} // namespace protobuf
} // namespace google
extern "C" {
std::string* proto2_rust_cpp_new_string(google::protobuf::rust::PtrAndLen src) {
return new std::string(src.CopyToString());
}
void proto2_rust_cpp_delete_string(std::string* str) { delete str; }
google::protobuf::rust::PtrAndLen proto2_rust_cpp_string_to_view(std::string* str) {
return google::protobuf::rust::PtrAndLen{str->data(), str->length()};
}
}