CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_Common/ExpandingString.cpp
Views: 1798
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
ExpandingString::ExpandingString(char* s, uint32_t total_len) : buf(0)
29
{
30
set_buffer(s, total_len, 0);
31
memset(buf, 0, buflen);
32
}
33
34
35
/*
36
expand the string buffer
37
*/
38
bool ExpandingString::expand(uint32_t min_extra_space_needed)
39
{
40
if (external_buffer) {
41
// we can't expand an external buffer
42
return false;
43
}
44
// expand a reasonable amount
45
uint32_t newsize = (5*buflen/4) + EXPAND_INCREMENT;
46
if (newsize - used < min_extra_space_needed) {
47
newsize = used + min_extra_space_needed;
48
}
49
50
// add one to ensure we are always null terminated
51
void *newbuf = hal.util->std_realloc(buf, newsize+1);
52
53
if (newbuf == nullptr) {
54
allocation_failed = true;
55
return false;
56
}
57
58
buflen = newsize;
59
buf = (char *)newbuf;
60
memset(&buf[used], 0, newsize-used);
61
62
return true;
63
}
64
65
/*
66
print into the buffer, expanding if needed
67
*/
68
void ExpandingString::printf(const char *format, ...)
69
{
70
if (allocation_failed) {
71
return;
72
}
73
if (buflen == used && !expand(0)) {
74
return;
75
}
76
int n;
77
78
/*
79
print into the buffer, expanding the buffer if needed
80
*/
81
while (true) {
82
va_list arg;
83
va_start(arg, format);
84
n = hal.util->vsnprintf(&buf[used], buflen-used, format, arg);
85
va_end(arg);
86
if (n < 0) {
87
return;
88
}
89
if (uint32_t(n) < buflen - used) {
90
break;
91
}
92
if (!expand(n+1)) {
93
return;
94
}
95
}
96
used += n;
97
}
98
99
/*
100
print into the buffer, expanding if needed
101
*/
102
bool ExpandingString::append(const char *s, uint32_t len)
103
{
104
if (allocation_failed) {
105
return false;
106
}
107
if (buflen - used < len && !expand(len)) {
108
return false;
109
}
110
if (s != nullptr) {
111
memcpy(&buf[used], s, len);
112
}
113
used += len;
114
return true;
115
}
116
117
ExpandingString::~ExpandingString()
118
{
119
if (!external_buffer) {
120
free(buf);
121
}
122
}
123
124
125
void ExpandingString::set_buffer(char *s, uint32_t total_len, uint32_t used_len)
126
{
127
if (buf != nullptr) {
128
// we need to free previously used buffer
129
free(buf);
130
}
131
132
buf = s;
133
buflen = total_len;
134
used = used_len;
135
allocation_failed = false;
136
external_buffer = true;
137
}
138
139
#endif // HAL_BOOTLOADER_BUILD
140
141