44 this->data[this->
pos++] =
'\n';
45 }
else if (this->size > 0) {
47 this->data[this->size - 1] =
'\n';
53 if (this->
pos + MAX_HEADER_SIZE > this->size)
56 char *p = this->current_();
59 this->write_ansi_color_(p, level);
68 *p++ =
static_cast<char>(
progmem_read_byte(
reinterpret_cast<const uint8_t *
>(&LOG_LEVEL_LETTER_CHARS[level])));
75 this->copy_string_(p,
tag);
80 if (
line > 999) [[unlikely]] {
81 write_digit(p,
line, 1000);
83 write_digit(p,
line, 100);
84 write_digit(p,
line, 10);
88#if defined(USE_ESP32) || defined(USE_LIBRETINY) || defined(USE_ZEPHYR) || defined(USE_HOST)
90 if (thread_name !=
nullptr) {
91 this->write_ansi_color_(p, 1);
93 this->copy_string_(p, thread_name);
95 this->write_ansi_color_(p, level);
108#ifdef USE_STORE_LOG_STR_IN_FLASH
115 const uint16_t available = this->remaining_();
116 const uint16_t copy_len = (text_length < available) ? text_length : available;
118 memcpy(this->current_(), text, copy_len);
119 this->
pos += copy_len;
125 bool full_()
const {
return this->
pos >= this->
size; }
126 uint16_t remaining_()
const {
return this->size - this->
pos; }
127 char *current_() {
return this->data + this->
pos; }
129 this->write_ansi_reset_();
131 this->data[this->full_() ? this->size - 1 : this->
pos] =
'\0';
134 static constexpr uint16_t ANSI_RESET_LEN = 4;
135 void write_ansi_reset_() {
136 if (this->remaining_() >= ANSI_RESET_LEN) {
137 char *p = this->current_();
142 this->
pos += ANSI_RESET_LEN;
145 void strip_trailing_newlines_() {
146 while (this->
pos > 0 && this->data[this->
pos - 1] ==
'\n')
149 void process_vsnprintf_result_(
int ret) {
152 const uint16_t rem = this->remaining_();
153 this->
pos += (ret >= rem) ? (rem - 1) :
static_cast<uint16_t
>(ret);
154 this->strip_trailing_newlines_();
156 void format_vsnprintf_(
const char *
format, va_list
args) {
159 this->process_vsnprintf_result_(vsnprintf(this->current_(), this->remaining_(),
format,
args));
161#ifdef USE_STORE_LOG_STR_IN_FLASH
162 void format_vsnprintf_P_(PGM_P
format, va_list
args) {
165 this->process_vsnprintf_result_(vsnprintf_P(this->current_(), this->remaining_(),
format,
args));
169 static inline void ESPHOME_ALWAYS_INLINE write_digit(
char *&p,
int &value,
int divisor) {
171 while (value >= divisor) {
179 void write_ansi_color_(
char *&p, uint8_t level) {
185 *p++ = (level == 1) ?
'1' :
'0';
188 *p++ =
static_cast<char>(
progmem_read_byte(
reinterpret_cast<const uint8_t *
>(&LOG_LEVEL_COLOR_DIGIT[level])));
193 void copy_string_(
char *&p,
const char *str) {
194 const size_t len = strlen(str);