diff --git a/include/rfl/avro/Writer.hpp b/include/rfl/avro/Writer.hpp index 4cdf2832..6a6f1528 100644 --- a/include/rfl/avro/Writer.hpp +++ b/include/rfl/avro/Writer.hpp @@ -147,7 +147,8 @@ class RFL_API Writer { OutputVarType add_value_to_map(const std::string_view& _name, const T& _var, OutputMapType* _parent) const { avro_value_t new_value; - int result = avro_value_add(&_parent->val_, _name.data(), &new_value, + // Copy name to nullterminate. + int result = avro_value_add(&_parent->val_, std::string(_name).c_str(), &new_value, nullptr, nullptr); if (result != 0) { throw std::runtime_error("Error adding value to map: error(" + @@ -163,7 +164,8 @@ class RFL_API Writer { const T& _var, OutputObjectType* _parent) const { avro_value_t new_value; - int result = avro_value_get_by_name(&_parent->val_, _name.data(), + // Copy name to nullterminate. + int result = avro_value_get_by_name(&_parent->val_, std::string(_name).c_str(), &new_value, nullptr); if (result != 0) { throw std::runtime_error("Error adding value to object: error(" + diff --git a/include/rfl/capnproto/Reader.hpp b/include/rfl/capnproto/Reader.hpp index 819a5f3e..684b2c55 100644 --- a/include/rfl/capnproto/Reader.hpp +++ b/include/rfl/capnproto/Reader.hpp @@ -165,8 +165,8 @@ class RFL_API Reader { const auto entries = _map.val_.get("entries").as(); for (auto entry : entries) { auto s = entry.template as(); - const char* key = s.get("key").as().cStr(); - _map_reader.read(std::string_view(key), InputVarType{s.get("value")}); + const auto key = s.get("key").as(); + _map_reader.read(std::string_view(key.cStr(), key.size()), InputVarType{s.get("value")}); } return std::nullopt; } catch (std::exception& e) { diff --git a/include/rfl/capnproto/Writer.hpp b/include/rfl/capnproto/Writer.hpp index 0eaf4f84..cd9bf9bd 100644 --- a/include/rfl/capnproto/Writer.hpp +++ b/include/rfl/capnproto/Writer.hpp @@ -193,7 +193,7 @@ class RFL_API Writer { auto entries = OutputArrayType{_parent->val_.get("entries").as()}; auto new_entry = add_object_to_array(2, &entries); - add_value_to_object("key", std::string(_name), &new_entry); + new_entry.val_.set("key", { _name.data(), _name.size() }); return add_value_to_object("value", _var, &new_entry); } @@ -202,20 +202,20 @@ class RFL_API Writer { const T& _var, OutputObjectType* _parent) const { if constexpr (std::is_same, std::string>()) { - _parent->val_.set(_name.data(), _var.c_str()); + _parent->val_.set({ _name.data(), _name.size() }, { _var.c_str(), _var.size() }); } else if constexpr (std::is_same, rfl::Bytestring>()) { const auto array_ptr = kj::ArrayPtr( internal::ptr_cast(_var.data()), _var.size()); - _parent->val_.set(_name.data(), capnp::Data::Reader(array_ptr)); + _parent->val_.set({ _name.data(), _name.size() }, capnp::Data::Reader(array_ptr)); } else if constexpr (std::is_floating_point>() || std::is_same, bool>()) { - _parent->val_.set(_name.data(), _var); + _parent->val_.set({ _name.data(), _name.size() }, _var); } else if constexpr (std::is_integral>()) { - _parent->val_.set(_name.data(), static_cast(_var)); + _parent->val_.set({ _name.data(), _name.size() }, static_cast(_var)); } else if constexpr (internal::is_literal_v) { return add_value_to_object(_name, _var.value(), _parent); diff --git a/include/rfl/json/Reader.hpp b/include/rfl/json/Reader.hpp index b358e71f..ac86ad84 100644 --- a/include/rfl/json/Reader.hpp +++ b/include/rfl/json/Reader.hpp @@ -88,7 +88,7 @@ struct Reader { yyjson_obj_iter_init(_obj.val_, &iter); yyjson_val* key; while ((key = yyjson_obj_iter_next(&iter))) { - const auto name = std::string_view(yyjson_get_str(key)); + const auto name = std::string_view(yyjson_get_str(key), yyjson_get_len(key)); _object_reader.read(name, InputVarType(yyjson_obj_iter_get_val(key))); } return std::nullopt; @@ -101,7 +101,7 @@ struct Reader { if (r == NULL) { return error("Could not cast to string."); } - return std::string(r); + return std::string(r, yyjson_get_len(_var.val_)); } else if constexpr (std::is_same, bool>()) { if (!yyjson_is_bool(_var.val_)) { diff --git a/include/rfl/json/Writer.hpp b/include/rfl/json/Writer.hpp index 159c0e0e..951752db 100644 --- a/include/rfl/json/Writer.hpp +++ b/include/rfl/json/Writer.hpp @@ -96,7 +96,7 @@ class RFL_API Writer { OutputObjectType* _parent) const { const auto val = from_basic_type(_var); const bool ok = yyjson_mut_obj_add( - _parent->val_, yyjson_mut_strcpy(doc(), _name.data()), val.val_); + _parent->val_, yyjson_mut_strncpy(doc(), _name.data(), _name.size()), val.val_); if (!ok) { throw std::runtime_error("Could not add field '" + std::string(_name) + "' to object."); @@ -117,7 +117,7 @@ class RFL_API Writer { template OutputVarType from_basic_type(const T& _var) const noexcept { if constexpr (std::is_same, std::string>()) { - return OutputVarType(yyjson_mut_strcpy(doc(), _var.c_str())); + return OutputVarType(yyjson_mut_strncpy(doc(), _var.c_str(), _var.size())); } else if constexpr (std::is_same, bool>()) { return OutputVarType(yyjson_mut_bool(doc(), _var)); diff --git a/include/rfl/xml/Writer.hpp b/include/rfl/xml/Writer.hpp index bd20febe..e68582ce 100644 --- a/include/rfl/xml/Writer.hpp +++ b/include/rfl/xml/Writer.hpp @@ -93,9 +93,9 @@ struct RFL_API Writer { private: template - std::string to_string(const T& _val) const { + decltype(auto) to_string(const T& _val) const { if constexpr (std::is_same, std::string>()) { - return _val; + return _val; // Return reference to avoid expensive string copy. } else if constexpr (std::is_same, bool>()) { return _val ? "true" : "false"; } else if constexpr (std::is_floating_point>() || diff --git a/include/rfl/yaml/Writer.hpp b/include/rfl/yaml/Writer.hpp index 549e6d42..b5bf0616 100644 --- a/include/rfl/yaml/Writer.hpp +++ b/include/rfl/yaml/Writer.hpp @@ -77,7 +77,6 @@ class RFL_API Writer { void end_object(OutputObjectType* _obj) const; - private: template OutputVarType insert_value(const std::string_view& _name, const T& _var) const { @@ -85,14 +84,14 @@ class RFL_API Writer { std::is_same, bool>() || std::is_same, std::remove_cvref_t>()) { - (*out_) << YAML::Key << _name.data() << YAML::Value << _var; + (*out_) << YAML::Key << std::string(_name) << YAML::Value << _var; } else if constexpr (std::is_floating_point>()) { // std::to_string is necessary to ensure that floating point values are // always written as floats. - (*out_) << YAML::Key << _name.data() << YAML::Value + (*out_) << YAML::Key << std::string(_name) << YAML::Value << std::to_string(_var); } else if constexpr (std::is_integral>()) { - (*out_) << YAML::Key << _name.data() << YAML::Value + (*out_) << YAML::Key << std::string(_name) << YAML::Value << static_cast(_var); } else { static_assert(rfl::always_false_v, "Unsupported type."); diff --git a/src/rfl/capnproto/Writer.cpp b/src/rfl/capnproto/Writer.cpp index 9220142e..18e17a0a 100644 --- a/src/rfl/capnproto/Writer.cpp +++ b/src/rfl/capnproto/Writer.cpp @@ -47,7 +47,7 @@ Writer::OutputArrayType Writer::add_array_to_map(const std::string_view& _name, Writer::OutputArrayType Writer::add_array_to_object( const std::string_view& _name, const size_t _size, OutputObjectType* _parent) const { - return OutputArrayType{_parent->val_.init(_name.data(), SafeSizeToUInt(_size)) + return OutputArrayType{_parent->val_.init({ _name.data(), _name.size() }, SafeSizeToUInt(_size)) .as()}; } @@ -111,7 +111,7 @@ Writer::OutputObjectType Writer::add_object_to_object( const std::string_view& _name, const size_t /*_size*/, OutputObjectType* _parent) const { return OutputObjectType{ - _parent->val_.get(_name.data()).as()}; + _parent->val_.get({ _name.data(), _name.size() }).as()}; } Writer::OutputObjectType Writer::add_object_to_union( @@ -142,7 +142,7 @@ Writer::OutputUnionType Writer::add_union_to_map(const std::string_view& _name, Writer::OutputUnionType Writer::add_union_to_object( const std::string_view& _name, OutputObjectType* _parent) const { return OutputUnionType{ - _parent->val_.get(_name.data()).as()}; + _parent->val_.get({ _name.data(), _name.size() }).as()}; } Writer::OutputUnionType Writer::add_union_to_union( @@ -171,7 +171,7 @@ Writer::OutputVarType Writer::add_null_to_map(const std::string_view& _name, Writer::OutputVarType Writer::add_null_to_object( const std::string_view& _name, OutputObjectType* _parent) const { - _parent->val_.set(_name.data(), capnp::VOID); + _parent->val_.set({ _name.data(), _name.size() }, capnp::VOID); return OutputVarType{}; } diff --git a/src/rfl/flexbuf/Writer.cpp b/src/rfl/flexbuf/Writer.cpp index f635c8c3..afaf4538 100644 --- a/src/rfl/flexbuf/Writer.cpp +++ b/src/rfl/flexbuf/Writer.cpp @@ -51,7 +51,8 @@ Writer::OutputVarType Writer::add_null_to_array( Writer::OutputVarType Writer::add_null_to_object( const std::string_view& _name, OutputObjectType* /*_parent*/) const { - fbb_->Null(_name.data()); + // Copy the string, because "std::string_view" might not be nullterminated. + fbb_->Null(std::string(_name).c_str()); return OutputVarType{}; } @@ -64,7 +65,8 @@ void Writer::end_object(OutputObjectType* _obj) const { } Writer::OutputArrayType Writer::new_array(const std::string_view& _name) const { - const auto start = fbb_->StartVector(_name.data()); + // Copy the string, because "std::string_view" might not be nullterminated. + const auto start = fbb_->StartVector(std::string(_name).c_str()); return OutputArrayType{start}; } @@ -75,7 +77,8 @@ Writer::OutputArrayType Writer::new_array() const { Writer::OutputObjectType Writer::new_object( const std::string_view& _name) const { - const auto start = fbb_->StartMap(_name.data()); + // Copy the string, because "std::string_view" might not be nullterminated. + const auto start = fbb_->StartMap(std::string(_name).c_str()); return OutputObjectType{start}; } diff --git a/src/rfl/xml/Writer.cpp b/src/rfl/xml/Writer.cpp index 0ae9d977..83be3cdc 100644 --- a/src/rfl/xml/Writer.cpp +++ b/src/rfl/xml/Writer.cpp @@ -39,27 +39,27 @@ Writer::~Writer() = default; Writer::OutputArrayType Writer::array_as_root(const size_t /*_size*/) const { auto node_child = - Ref::make(root_->append_child(root_name_.c_str())); + Ref::make(root_->append_child(root_name_)); return OutputArrayType(root_name_, node_child); } Writer::OutputObjectType Writer::object_as_root(const size_t /*_size*/) const { auto node_child = - Ref::make(root_->append_child(root_name_.c_str())); + Ref::make(root_->append_child(root_name_)); return OutputObjectType(node_child); } Writer::OutputVarType Writer::null_as_root() const { auto node_child = - Ref::make(root_->append_child(root_name_.c_str())); + Ref::make(root_->append_child(root_name_)); return OutputVarType(node_child); } Writer::OutputVarType Writer::value_as_root_impl( const std::string& _str) const { auto node_child = - Ref::make(root_->append_child(root_name_.c_str())); - node_child->append_child(pugi::node_pcdata).set_value(_str.c_str()); + Ref::make(root_->append_child(root_name_)); + node_child->append_child(pugi::node_pcdata).set_value(_str); return OutputVarType(node_child); } @@ -78,7 +78,7 @@ Writer::OutputVarType Writer::add_value_to_array_impl( const std::string& _str, OutputArrayType* _parent) const { auto node_child = Ref::make(_parent->node_->append_child(_parent->name_)); - node_child->append_child(pugi::node_pcdata).set_value(_str.c_str()); + node_child->append_child(pugi::node_pcdata).set_value(_str); return OutputVarType(node_child); } @@ -86,15 +86,15 @@ Writer::OutputVarType Writer::add_value_to_object_impl( const std::string_view& _name, const std::string& _str, OutputObjectType* _parent, const bool _is_attribute) const { if (_is_attribute) { - _parent->node_->append_attribute(_name) = _str.c_str(); + _parent->node_->append_attribute(_name) = _str; return OutputVarType(_parent->node_); } else if (_name == XML_CONTENT) { - _parent->node_->append_child(pugi::node_pcdata).set_value(_str.c_str()); + _parent->node_->append_child(pugi::node_pcdata).set_value(_str); return OutputVarType(_parent->node_); } else { auto node_child = Ref::make(_parent->node_->append_child(_name)); - node_child->append_child(pugi::node_pcdata).set_value(_str.c_str()); + node_child->append_child(pugi::node_pcdata).set_value(_str); return OutputVarType(node_child); } } diff --git a/src/rfl/yaml/Writer.cpp b/src/rfl/yaml/Writer.cpp index e673e736..a45b144c 100644 --- a/src/rfl/yaml/Writer.cpp +++ b/src/rfl/yaml/Writer.cpp @@ -59,7 +59,7 @@ void Writer::end_object(OutputObjectType* /*_obj*/) const { } Writer::OutputArrayType Writer::new_array(const std::string_view& _name) const { - (*out_) << YAML::Key << _name.data() << YAML::Value << YAML::BeginSeq; + (*out_) << YAML::Key << std::string(_name) << YAML::Value << YAML::BeginSeq; return OutputArrayType{}; } @@ -70,7 +70,7 @@ Writer::OutputArrayType Writer::new_array() const { Writer::OutputObjectType Writer::new_object( const std::string_view& _name) const { - (*out_) << YAML::Key << _name.data() << YAML::Value << YAML::BeginMap; + (*out_) << YAML::Key << std::string(_name) << YAML::Value << YAML::BeginMap; return OutputObjectType{}; }