Arduino DLNA Server
Str.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "StrView.h"
4 #include "Vector.h"
5 
6 namespace tiny_dlna {
7 
22 class Str : public StrView {
23  public:
24  Str() = default;
25 
26  Str(int initialAllocatedLength) : Str() {
27  maxlen = initialAllocatedLength;
28  is_const = false;
29  grow(maxlen);
30  }
31 
32  Str(const char *str) : Str() {
33  if (str != nullptr) {
34  len = strlen(str);
35  maxlen = len;
36  grow(maxlen);
37  if (chars != nullptr) {
38  strcpy(chars, str);
39  }
40  }
41  }
42 
44  Str(StrView &source) : Str() { set(source); }
45 
47  Str(Str &source) : Str() { set(source); }
48 
50  Str(Str &&obj) { move(obj); }
51 
53  ~Str() {
54  len = maxlen = 0;
55  chars = nullptr;
56  }
57 
59  Str &operator=(Str &&obj) {
60  return move(obj);
61  }
62 
64  Str &operator=(Str &obj) {
65  //assert(&obj!=nullptr);
66  set(obj.c_str());
67  return *this;
68  };
69 
70  bool isOnHeap() override { return true; }
71 
72  bool isConst() override { return false; }
73 
74  void operator=(const char *str) override { set(str); }
75 
76  void operator=(char *str) override { set(str); }
77 
78  void operator=(int v) override { set(v); }
79 
80  void operator=(double v) override { set(v); }
81 
82  size_t capacity() { return maxlen; }
83 
84  void setCapacity(size_t newLen) { grow(newLen); }
85 
86  // make sure that the max size is allocated
87  void allocate(int len = -1) {
88  int new_size = len < 0 ? maxlen : len;
89  grow(new_size);
90  this->len = new_size;
91  }
92 
94  void copyFrom(const char *source, int len, int maxlen = 0) {
95  this->maxlen = maxlen == 0 ? len : maxlen;
96  resize(this->maxlen);
97  if (this->chars != nullptr) {
98  this->len = len;
99  this->is_const = false;
100  memmove(this->chars, source, len);
101  this->chars[len] = 0;
102  }
103  }
104 
106  void setChars(char c, int len) {
107  grow(this->maxlen);
108  if (this->chars != nullptr) {
109  for (int j = 0; j < len; j++) {
110  this->chars[j] = c;
111  }
112  this->len = len;
113  this->is_const = false;
114  this->chars[len] = 0;
115  }
116  }
117 
119  void urlEncode() {
120  char temp[4];
121  int new_size = 0;
122  // Calculate the new size
123  for (size_t i = 0; i < len; i++) {
124  urlEncodeChar(chars[i], temp, 4);
125  new_size += strlen(temp);
126  }
127  // build new string
128  char result[new_size + 1];
129  memset(result,0, new_size+1);
130  for (size_t i = 0; i < len; i++) {
131  urlEncodeChar(chars[i], temp, 4);
132  strcat(result, temp);
133  }
134  // save result
135  grow(new_size);
136  strcpy(chars, result);
137  this->len = strlen(temp);
138  }
139 
141  void urlDecode() {
142  char szTemp[2];
143  size_t i = 0;
144  size_t result_idx = 0;
145  while (i < len) {
146  if (chars[i] == '%') {
147  szTemp[0] = chars[i + 1];
148  szTemp[1] = chars[i + 2];
149  chars[result_idx] = strToBin(szTemp);
150  i = i + 3;
151  } else if (chars[i] == '+') {
152  chars[result_idx] = ' ';
153  i++;
154  } else {
155  chars[result_idx] += chars[i];
156  i++;
157  }
158  result_idx++;
159  }
160  chars[result_idx] = 0;
161  this->len = result_idx;
162  }
163 
164  void clear() override {
165  len = 0;
166  maxlen = 0;
167  vector.resize(0);
168  chars = nullptr;
169  }
170 
171  void resize(int size) {
172  vector.resize(size+1);
173  maxlen = size;
174  len = size;
175  chars = vector.data();
176  }
177 
178  void swap(Str &other){
179  int tmp_len = len;
180  int tmp_maxlen = maxlen;
181  len = other.len;
182  maxlen = other.maxlen;
183  vector.swap(other.vector);
184  chars = vector.data();
185  other.chars = other.vector.data();
186  }
187 
188  const char* c_str() { return vector.data(); }
189 
190  // just sets the len to 0
191  void reset() {
192  memset(vector.data(),0, len);
193  len = 0;
194  }
195 
196  protected:
198 
199  Str& move(Str &other) {
200  swap(other);
201  other.clear();
202  return *this;
203  }
204 
205  bool grow(int newMaxLen) override {
206  bool grown = false;
207  assert(newMaxLen < 1024 * 10);
208  if (newMaxLen < 0) return false;
209 
210  if (chars == nullptr || newMaxLen > maxlen) {
211  grown = true;
212  // we use at minimum the defined maxlen
213  int newSize = newMaxLen > maxlen ? newMaxLen : maxlen;
214  vector.resize(newSize + 1);
215  chars = &vector[0];
216  maxlen = newSize;
217  }
218  return grown;
219  }
220 
221  void urlEncodeChar(char c, char *result, int maxLen) {
222  if (isalnum(c)) {
223  snprintf(result, maxLen, "%c", c);
224  } else if (isspace(c)) {
225  snprintf(result, maxLen, "%s", "+");
226  } else {
227  snprintf(result, maxLen, "%%%X%X", c >> 4, c % 16);
228  }
229  }
230 
231  char charToInt(char ch) {
232  if (ch >= '0' && ch <= '9') {
233  return (char)(ch - '0');
234  }
235  if (ch >= 'a' && ch <= 'f') {
236  return (char)(ch - 'a' + 10);
237  }
238  if (ch >= 'A' && ch <= 'F') {
239  return (char)(ch - 'A' + 10);
240  }
241  return -1;
242  }
243 
244  char strToBin(char *pString) {
245  char szBuffer[2];
246  char ch;
247  szBuffer[0] = charToInt(pString[0]); // make the B to 11 -- 00001011
248  szBuffer[1] = charToInt(pString[1]); // make the 0 to 0 -- 00000000
249  ch = (szBuffer[0] << 4) | szBuffer[1]; // to change the BO to 10110000
250  return ch;
251  }
252 };
253 
254 } // namespace tiny_dlna
A simple wrapper to provide string functions on char*. If the underlying char* is a const we do not a...
Definition: StrView.h:25
char * chars
Definition: StrView.h:747
int len
Definition: StrView.h:749
int maxlen
Definition: StrView.h:750
virtual void set(const char *alt)
assigs a value
Definition: StrView.h:51
bool is_const
Definition: StrView.h:748
String implementation which keeps the data on the heap. We grow the allocated memory only if the copy...
Definition: Str.h:22
void resize(int size)
Definition: Str.h:171
Str(int initialAllocatedLength)
Definition: Str.h:26
void operator=(const char *str) override
we can assign a const char*
Definition: Str.h:74
void urlEncode()
url encode the string
Definition: Str.h:119
void clear() override
clears the string by setting the terminating 0 at the beginning
Definition: Str.h:164
Str(const char *str)
Definition: Str.h:32
Str & operator=(Str &obj)
Copy assingment.
Definition: Str.h:64
char charToInt(char ch)
Definition: Str.h:231
bool isOnHeap() override
checks if the string is on the heap
Definition: Str.h:70
Str(Str &&obj)
Move constructor.
Definition: Str.h:50
void setChars(char c, int len)
Fills the string with len chars.
Definition: Str.h:106
void copyFrom(const char *source, int len, int maxlen=0)
assigns a memory buffer
Definition: Str.h:94
Str(Str &source)
Copy constructor.
Definition: Str.h:47
size_t capacity()
Definition: Str.h:82
void urlDecode()
decodes a url encoded string
Definition: Str.h:141
Str()=default
Str & operator=(Str &&obj)
Move assignment.
Definition: Str.h:59
Vector< char > vector
Definition: Str.h:197
void reset()
Definition: Str.h:191
Str & move(Str &other)
Definition: Str.h:199
void allocate(int len=-1)
Definition: Str.h:87
bool grow(int newMaxLen) override
only supported in subclasses
Definition: Str.h:205
Str(StrView &source)
Convert StrView to Str.
Definition: Str.h:44
void swap(Str &other)
Definition: Str.h:178
char strToBin(char *pString)
Definition: Str.h:244
void operator=(double v) override
we can assign a double
Definition: Str.h:80
bool isConst() override
checks if the string is a constant that must not be changed
Definition: Str.h:72
~Str()
Destructor.
Definition: Str.h:53
void operator=(char *str) override
we can assign a char*
Definition: Str.h:76
void setCapacity(size_t newLen)
Definition: Str.h:84
void urlEncodeChar(char c, char *result, int maxLen)
Definition: Str.h:221
void operator=(int v) override
we can assign an int
Definition: Str.h:78
const char * c_str()
provides the string value as const char*
Definition: Str.h:188
bool resize(int newSize, T value)
Definition: Vector.h:247
void swap(Vector< T > &in)
Definition: Vector.h:225
T * data()
Definition: Vector.h:294
Definition: Allocator.h:6