Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : /* 16 : expanding string for easy construction of text buffers 17 : */ 18 : 19 : #include "ExpandingString.h" 20 : #include <AP_HAL/AP_HAL.h> 21 : 22 : #ifndef HAL_BOOTLOADER_BUILD 23 : 24 : extern const AP_HAL::HAL& hal; 25 : 26 : #define EXPAND_INCREMENT 512 27 : 28 494 : ExpandingString::ExpandingString(char* s, uint32_t total_len) : buf(0) 29 : { 30 494 : set_buffer(s, total_len, 0); 31 494 : memset(buf, 0, buflen); 32 494 : } 33 : 34 : 35 : /* 36 : expand the string buffer 37 : */ 38 2596 : bool ExpandingString::expand(uint32_t min_extra_space_needed) 39 : { 40 2596 : if (external_buffer) { 41 : // we can't expand an external buffer 42 0 : return false; 43 : } 44 : // expand a reasonable amount 45 2596 : uint32_t newsize = (5*buflen/4) + EXPAND_INCREMENT; 46 2596 : if (newsize - used < min_extra_space_needed) { 47 2 : newsize = used + min_extra_space_needed; 48 : } 49 : 50 : // add one to ensure we are always null terminated 51 2596 : void *newbuf = mem_realloc(buf, used, newsize+1); 52 : 53 2596 : if (newbuf == nullptr) { 54 6 : allocation_failed = true; 55 6 : return false; 56 : } 57 : 58 2590 : buflen = newsize; 59 2590 : buf = (char *)newbuf; 60 : 61 2590 : return true; 62 : } 63 : 64 : /* 65 : print into the buffer, expanding if needed 66 : */ 67 25474 : void ExpandingString::printf(const char *format, ...) 68 : { 69 25474 : if (allocation_failed) { 70 2 : return; 71 : } 72 25472 : if (buflen == used && !expand(0)) { 73 2 : return; 74 : } 75 : int n; 76 : 77 : /* 78 : print into the buffer, expanding the buffer if needed 79 : */ 80 : while (true) { 81 : va_list arg; 82 26760 : va_start(arg, format); 83 26760 : n = hal.util->vsnprintf(&buf[used], buflen-used, format, arg); 84 26760 : va_end(arg); 85 26760 : if (n < 0) { 86 4 : return; 87 : } 88 26758 : if (uint32_t(n) < buflen - used) { 89 25466 : break; 90 : } 91 1292 : if (!expand(n+1)) { 92 2 : return; 93 : } 94 1290 : } 95 25466 : used += n; 96 : } 97 : 98 : /* 99 : print into the buffer, expanding if needed 100 : */ 101 33 : bool ExpandingString::append(const char *s, uint32_t len) 102 : { 103 33 : if (allocation_failed) { 104 2 : return false; 105 : } 106 31 : if (buflen - used < len && !expand(len)) { 107 2 : return false; 108 : } 109 29 : if (s != nullptr) { 110 28 : memcpy(&buf[used], s, len); 111 : } 112 29 : used += len; 113 29 : return true; 114 : } 115 : 116 10770 : ExpandingString::~ExpandingString() 117 : { 118 10770 : if (!external_buffer) { 119 9081 : free(buf); 120 : } 121 10770 : } 122 : 123 : 124 1753 : void ExpandingString::set_buffer(char *s, uint32_t total_len, uint32_t used_len) 125 : { 126 1753 : if (buf != nullptr) { 127 : // we need to free previously used buffer 128 0 : free(buf); 129 : } 130 : 131 1753 : buf = s; 132 1753 : buflen = total_len; 133 1753 : used = used_len; 134 1753 : allocation_failed = false; 135 1753 : external_buffer = true; 136 1753 : } 137 : 138 : #endif // HAL_BOOTLOADER_BUILD