-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathStringBuilder.hpp
136 lines (111 loc) · 3.62 KB
/
StringBuilder.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#ifndef OTF_STRINGBUILDER_H
#define OTF_STRINGBUILDER_H
#if defined(ARDUINO)
#include <Arduino.h>
#else
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <functional>
#include <cstring>
#define snprintf_P snprintf
#define strncpy_P strncpy
#define strcmp_P strcmp
#define strncmp_P strncmp
#define strlen_P strlen
#define F(x) x
static inline int max(int a, int b) {
return a > b ? a : b;
}
static inline int min(int a, int b) {
return a < b ? a : b;
}
#endif
namespace OTF {
typedef std::function<void(const char *data, size_t length, bool streaming)> stream_write_t;
typedef std::function<void()> stream_flush_t;
typedef std::function<void()> stream_end_t;
/**
* Wraps a buffer to build a string with repeated calls to sprintf. If any of calls to sprintf cause an error (such
* as exceeding the size of the internal buffer), the error will be silently swallowed and the StringBuilder will be
* marked as invalid. This means that any error checking can occur after the entire string has been built instead of
* a check being required after each individual call to sprintf.
*/
class StringBuilder {
private:
size_t maxLength;
char *buffer;
size_t length = 0;
size_t totalLength = 0;
stream_write_t stream_write = nullptr;
stream_flush_t stream_flush = nullptr;
stream_end_t stream_end = nullptr;
bool streaming = false;
bool first_message = true;
/**
* Internal write function
*/
size_t _write(const char *data, size_t data_length, bool use_pgm);
protected:
bool valid = true;
public:
explicit StringBuilder(size_t maxLength);
~StringBuilder();
/**
* Inserts a string into the buffer at the current position using the same formatting rules as printf. If the operation
* would cause the buffer length to be exceeded or some other error occurs, the StringBuilder will be marked as invalid.
* @param format The format string to pass to sprintf.
* @param ... The format arguments to pass to sprintf.
*/
void bprintf(const char *format, va_list args);
void bprintf(const char *format, ...);
#if defined(ARDUINO)
void bprintf(const __FlashStringHelper *const format, va_list args);
void bprintf(const __FlashStringHelper *const format, ...);
#endif
/**
* Raw Write to buffer
*/
size_t write(const char *data, size_t length);
#if defined(ARDUINO)
/**
* Raw Write to buffer from PROGMEM
*/
size_t write_P(const __FlashStringHelper *const data, size_t length);
#endif
/**
* Enables streaming mode for the StringBuilder.
*/
void enableStream(stream_write_t write, stream_flush_t flush, stream_end_t end);
/**
* @brief
* Flushes the buffer and ends streaming mode.
*/
bool end();
/**
* Returns the null-terminated represented string stored in the underlying buffer.
* @return The null-terminated represented string stored in the underlying buffer.
*/
char *toString() const;
size_t getLength() const;
/**
* Returns a boolean indicating if the string was built successfully without any errors. If false, the behavior
* of toString() is undefined, and the string it returns (which may or may not be null terminated) should NOT
* be used.
*/
bool isValid();
/**
* Clears the buffer and resets the StringBuilder to a valid state.
*/
void clear();
/**
* Returns the maximum length of the buffer.
*/
size_t getMaxLength() const;
/**
* Total length of the string built so far.
*/
size_t getTotalLength() const;
};
}// namespace OTF
#endif