From 4199c52af17820836703a81517c95cb654f701b6 Mon Sep 17 00:00:00 2001 From: srgg Date: Fri, 24 Oct 2025 07:48:45 -0600 Subject: [PATCH] fix: correct byte size calculation for ATT values set from containers --- src/NimBLEAttValue.h | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/NimBLEAttValue.h b/src/NimBLEAttValue.h index ba92b08..bddf020 100644 --- a/src/NimBLEAttValue.h +++ b/src/NimBLEAttValue.h @@ -73,6 +73,14 @@ template struct Has_c_str_length().c_str())), decltype(void(std::declval().length()))> : std::true_type {}; +/* Used to determine if the type passed to a template has a value_type member (std::vector, std::array, std::string, etc.). */ +template +struct Has_value_type : std::false_type {}; + +template +struct Has_value_type + : std::true_type {}; + /** * @brief A specialized container class to hold BLE attribute values. * @details This class is designed to be more memory efficient than using\n @@ -274,13 +282,32 @@ class NimBLEAttValue { /** * @brief Template to set value to the value of val. * @param [in] v The value to set. - * @details Only used if the has a `data()` and `size()` method. + * @details Only used if the has a `data()` and `size()` method with `value_type`. + * Correctly calculates byte size for containers with multi-byte element types. */ template # ifdef _DOXYGEN_ bool # else - typename std::enable_if::value, bool>::type + typename std::enable_if::value && Has_value_type::value, bool>::type +# endif + setValue(const T& v) { + return setValue( + reinterpret_cast(v.data()), + v.size() * sizeof(typename T::value_type) + ); + } + + /** + * @brief Template to set value to the value of val. + * @param [in] v The value to set. + * @details Only used if the has a `data()` and `size()` method without `value_type`. + */ + template +# ifdef _DOXYGEN_ + bool +# else + typename std::enable_if::value && !Has_value_type::value, bool>::type # endif setValue(const T& v) { return setValue(reinterpret_cast(v.data()), v.size()); @@ -295,7 +322,11 @@ class NimBLEAttValue { template typename std::enable_if::value, bool>::type setValue(const T& s) { if constexpr (Has_data_size::value) { - return setValue(reinterpret_cast(s.data()), s.size()); + if constexpr (Has_value_type::value) { + return setValue(reinterpret_cast(s.data()), s.size() * sizeof(typename T::value_type)); + } else { + return setValue(reinterpret_cast(s.data()), s.size()); + } } else if constexpr (Has_c_str_length::value) { return setValue(reinterpret_cast(s.c_str()), s.length()); } else {