Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_Common/ExpandingString.cpp
9379 views
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 = mem_realloc(buf, used, newsize+1);
52
53
if (newbuf == nullptr) {
54
allocation_failed = true;
55
return false;
56
}
57
58
buflen = newsize;
59
buf = (char *)newbuf;
60
61
return true;
62
}
63
64
/*
65
print into the buffer, expanding if needed
66
*/
67
void ExpandingString::printf(const char *format, ...)
68
{
69
if (allocation_failed) {
70
return;
71
}
72
if (buflen == used && !expand(0)) {
73
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
va_start(arg, format);
83
n = hal.util->vsnprintf(&buf[used], buflen-used, format, arg);
84
va_end(arg);
85
if (n < 0) {
86
return;
87
}
88
if (uint32_t(n) < buflen - used) {
89
break;
90
}
91
if (!expand(n+1)) {
92
return;
93
}
94
}
95
used += n;
96
}
97
98
/*
99
print into the buffer, expanding if needed
100
*/
101
bool ExpandingString::append(const char *s, uint32_t len)
102
{
103
if (allocation_failed) {
104
return false;
105
}
106
if (buflen - used < len && !expand(len)) {
107
return false;
108
}
109
if (s != nullptr) {
110
memcpy(&buf[used], s, len);
111
}
112
used += len;
113
return true;
114
}
115
116
ExpandingString::~ExpandingString()
117
{
118
if (!external_buffer) {
119
free(buf);
120
}
121
}
122
123
124
void ExpandingString::set_buffer(char *s, uint32_t total_len, uint32_t used_len)
125
{
126
if (buf != nullptr) {
127
// we need to free previously used buffer
128
free(buf);
129
}
130
131
buf = s;
132
buflen = total_len;
133
used = used_len;
134
allocation_failed = false;
135
external_buffer = true;
136
}
137
138
#endif // HAL_BOOTLOADER_BUILD
139
140