Extract buf_append_sep_str helper, add tests

This commit is contained in:
J. Nick Koston
2026-04-08 20:52:51 -10:00
parent c8e636f253
commit e52c3b01e6
3 changed files with 53 additions and 15 deletions
+3 -15
View File
@@ -569,21 +569,9 @@ size_t value_accuracy_with_uom_to_buf(std::span<char, VALUE_ACCURACY_MAX_LEN> bu
if (unit_of_measurement.empty()) {
return len;
}
// Append " <uom>" directly
char *p = buf.data() + len;
size_t remaining = buf.size() - len;
size_t uom_len = unit_of_measurement.size();
// Need space for: ' ' + uom + '\0'
if (remaining < 2) {
return len;
}
*p++ = ' ';
remaining--;
size_t copy_len = std::min(uom_len, remaining - 1);
memcpy(p, unit_of_measurement.c_str(), copy_len);
p += copy_len;
*p = '\0';
return static_cast<size_t>(p - buf.data());
char *end = buf_append_sep_str(buf.data() + len, buf.size() - len, ' ', unit_of_measurement.c_str(),
unit_of_measurement.size());
return static_cast<size_t>(end - buf.data());
}
int8_t step_to_accuracy_decimals(float step) {
+15
View File
@@ -1295,6 +1295,21 @@ inline char *int8_to_str(char *buf, int8_t val) {
return buf;
}
/// Append a separator char and a string to a buffer, respecting remaining space.
/// Returns pointer past last char written (null terminator is written).
inline char *buf_append_sep_str(char *buf, size_t remaining, char separator, const char *str, size_t str_len) {
if (remaining < 2) {
return buf;
}
*buf++ = separator;
remaining--;
size_t copy_len = std::min(str_len, remaining - 1);
memcpy(buf, str, copy_len);
buf += copy_len;
*buf = '\0';
return buf;
}
/// Return 10^n for small non-negative n (0-3) as uint32_t, avoiding float.
inline uint32_t small_pow10(int8_t n) {
if (n == 1) {
+35
View File
@@ -116,4 +116,39 @@ TEST(FracToStr, ZeroDivisor) {
EXPECT_EQ(end, buf); // writes nothing
}
// --- buf_append_sep_str() ---
TEST(BufAppendSepStr, Basic) {
char buf[32] = "23.46";
char *start = buf + 5;
char *end = buf_append_sep_str(start, sizeof(buf) - 5, ' ', "°C", 3);
EXPECT_STREQ(buf, "23.46 °C");
EXPECT_EQ(end - buf, 9); // "°C" is 3 bytes (UTF-8)
}
TEST(BufAppendSepStr, EmptyString) {
char buf[32] = "100";
char *start = buf + 3;
char *end = buf_append_sep_str(start, sizeof(buf) - 3, ' ', "", 0);
EXPECT_STREQ(buf, "100 ");
EXPECT_EQ(end - start, 1); // just the separator
}
TEST(BufAppendSepStr, NoRoom) {
char buf[8] = "1234567";
char *start = buf + 7;
char *end = buf_append_sep_str(start, 1, ' ', "unit", 4);
EXPECT_EQ(end, start); // nothing written
}
TEST(BufAppendSepStr, Truncation) {
char buf[8] = "val";
char *start = buf + 3;
// remaining = 5, separator takes 1, so 3 chars of string fit + null
char *end = buf_append_sep_str(start, 5, ' ', "longunit", 8);
*end = '\0';
EXPECT_STREQ(buf, "val lon");
EXPECT_EQ(end - buf, 7);
}
} // namespace esphome::testing