Path: blob/master/libraries/AP_Common/ExpandingString.cpp
9353 views
/*1This program is free software: you can redistribute it and/or modify2it under the terms of the GNU General Public License as published by3the Free Software Foundation, either version 3 of the License, or4(at your option) any later version.56This program is distributed in the hope that it will be useful,7but WITHOUT ANY WARRANTY; without even the implied warranty of8MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9GNU General Public License for more details.1011You should have received a copy of the GNU General Public License12along with this program. If not, see <http://www.gnu.org/licenses/>.13*/14/*15expanding string for easy construction of text buffers16*/1718#include "ExpandingString.h"19#include <AP_HAL/AP_HAL.h>2021#ifndef HAL_BOOTLOADER_BUILD2223extern const AP_HAL::HAL& hal;2425#define EXPAND_INCREMENT 5122627ExpandingString::ExpandingString(char* s, uint32_t total_len) : buf(0)28{29set_buffer(s, total_len, 0);30memset(buf, 0, buflen);31}323334/*35expand the string buffer36*/37bool ExpandingString::expand(uint32_t min_extra_space_needed)38{39if (external_buffer) {40// we can't expand an external buffer41return false;42}43// expand a reasonable amount44uint32_t newsize = (5*buflen/4) + EXPAND_INCREMENT;45if (newsize - used < min_extra_space_needed) {46newsize = used + min_extra_space_needed;47}4849// add one to ensure we are always null terminated50void *newbuf = mem_realloc(buf, used, newsize+1);5152if (newbuf == nullptr) {53allocation_failed = true;54return false;55}5657buflen = newsize;58buf = (char *)newbuf;5960return true;61}6263/*64print into the buffer, expanding if needed65*/66void ExpandingString::printf(const char *format, ...)67{68if (allocation_failed) {69return;70}71if (buflen == used && !expand(0)) {72return;73}74int n;7576/*77print into the buffer, expanding the buffer if needed78*/79while (true) {80va_list arg;81va_start(arg, format);82n = hal.util->vsnprintf(&buf[used], buflen-used, format, arg);83va_end(arg);84if (n < 0) {85return;86}87if (uint32_t(n) < buflen - used) {88break;89}90if (!expand(n+1)) {91return;92}93}94used += n;95}9697/*98print into the buffer, expanding if needed99*/100bool ExpandingString::append(const char *s, uint32_t len)101{102if (allocation_failed) {103return false;104}105if (buflen - used < len && !expand(len)) {106return false;107}108if (s != nullptr) {109memcpy(&buf[used], s, len);110}111used += len;112return true;113}114115ExpandingString::~ExpandingString()116{117if (!external_buffer) {118free(buf);119}120}121122123void ExpandingString::set_buffer(char *s, uint32_t total_len, uint32_t used_len)124{125if (buf != nullptr) {126// we need to free previously used buffer127free(buf);128}129130buf = s;131buflen = total_len;132used = used_len;133allocation_failed = false;134external_buffer = true;135}136137#endif // HAL_BOOTLOADER_BUILD138139140