-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathStringBuilder.hpp
More file actions
128 lines (105 loc) · 3.49 KB
/
StringBuilder.hpp
File metadata and controls
128 lines (105 loc) · 3.49 KB
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
#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
#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