Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Common/ExpandingString.cpp
Views: 1798
/*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 = hal.util->std_realloc(buf, newsize+1);5152if (newbuf == nullptr) {53allocation_failed = true;54return false;55}5657buflen = newsize;58buf = (char *)newbuf;59memset(&buf[used], 0, newsize-used);6061return true;62}6364/*65print into the buffer, expanding if needed66*/67void ExpandingString::printf(const char *format, ...)68{69if (allocation_failed) {70return;71}72if (buflen == used && !expand(0)) {73return;74}75int n;7677/*78print into the buffer, expanding the buffer if needed79*/80while (true) {81va_list arg;82va_start(arg, format);83n = hal.util->vsnprintf(&buf[used], buflen-used, format, arg);84va_end(arg);85if (n < 0) {86return;87}88if (uint32_t(n) < buflen - used) {89break;90}91if (!expand(n+1)) {92return;93}94}95used += n;96}9798/*99print into the buffer, expanding if needed100*/101bool ExpandingString::append(const char *s, uint32_t len)102{103if (allocation_failed) {104return false;105}106if (buflen - used < len && !expand(len)) {107return false;108}109if (s != nullptr) {110memcpy(&buf[used], s, len);111}112used += len;113return true;114}115116ExpandingString::~ExpandingString()117{118if (!external_buffer) {119free(buf);120}121}122123124void ExpandingString::set_buffer(char *s, uint32_t total_len, uint32_t used_len)125{126if (buf != nullptr) {127// we need to free previously used buffer128free(buf);129}130131buf = s;132buflen = total_len;133used = used_len;134allocation_failed = false;135external_buffer = true;136}137138#endif // HAL_BOOTLOADER_BUILD139140141