v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
string.h
1 /* -*- mode: C; c-basic-offset: 4; intent-tabs-mode: nil -*-
2  *
3  * Sifteo SDK
4  *
5  * Copyright <c> 2012 Sifteo, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #pragma once
27 #ifdef NOT_USERSPACE
28 # error This is a userspace-only header, not allowed by the current build.
29 #endif
30 
31 #include <sifteo/abi.h>
32 
33 namespace Sifteo {
34 
49 struct Fixed {
56  Fixed(int value, unsigned width, bool leadingZeroes=false)
57  : value(value), width(width), leadingZeroes(leadingZeroes) {}
58  int value;
59  unsigned width;
60  bool leadingZeroes;
61 };
62 
73 struct FixedFP {
80  FixedFP(float value, unsigned left, unsigned right, bool leadingZeroes=false)
81  : widthL(left), widthR(right), leadingZeroes(leadingZeroes)
82  {
83  // Left side: truncate to integer
84  valueL = int(value);
85 
86  /*
87  * Right side: We want to convert the right side to an integer by
88  * multiplying it by 10^right, then we can rely on String's
89  * field width truncation to do the rest. There aren't very many
90  * values of 'right' that won't overflow, so we can do this
91  * with a lookup table. Typically the field width is constant
92  * at compile-time, so this lookup table will optimize out.
93  */
94  switch (right) {
95  default: ASSERT(0);
96  case 0: valueR = value * 0; break;
97  case 1: valueR = value * 10; break;
98  case 2: valueR = value * 100; break;
99  case 3: valueR = value * 1000; break;
100  case 4: valueR = value * 10000; break;
101  case 5: valueR = value * 100000; break;
102  case 6: valueR = value * 1000000; break;
103  case 7: valueR = value * 10000000; break;
104  case 8: valueR = value * 100000000; break;
105  case 9: valueR = value * 1000000000; break;
106  }
107  }
108 
109  int valueL;
110  int valueR;
111  unsigned widthL, widthR;
112  bool leadingZeroes;
113 };
114 
121 struct Hex {
128  Hex(uint32_t value, unsigned width=8, bool leadingZeroes=true)
129  : value(value), width(width), leadingZeroes(leadingZeroes) {}
130  uint32_t value;
131  unsigned width;
132  bool leadingZeroes;
133 };
134 
141 struct Hex64 {
148  Hex64(uint64_t value, unsigned width=16, bool leadingZeroes=true)
149  : value(value), width(width), leadingZeroes(leadingZeroes) {}
150  uint64_t value;
151  unsigned width;
152  bool leadingZeroes;
153 };
154 
155 
165 inline int strncmp(const char *a, const char *b, unsigned count)
166 {
167  return _SYS_strncmp(a, b, count);
168 }
169 
176 inline unsigned strnlen(const char *str, uint32_t maxLen) {
177  return _SYS_strnlen(str, maxLen);
178 }
179 
190 template <unsigned tCapacity>
191 class String {
192 public:
193 
194  typedef char* iterator;
195  typedef const char* const_iterator;
196 
198  String() {
199  clear();
200  }
201 
203  char * c_str() {
204  return buffer;
205  }
206 
208  const char * c_str() const {
209  return buffer;
210  }
211 
213  operator char *() {
214  return buffer;
215  }
216 
218  operator const char *() const {
219  return buffer;
220  }
221 
223  static unsigned capacity() {
224  return tCapacity;
225  }
226 
228  unsigned size() const {
229  return _SYS_strnlen(buffer, tCapacity-1);
230  }
231 
233  iterator begin() {
234  return &buffer[0];
235  }
236 
238  iterator end() {
239  return &buffer[size()];
240  }
241 
243  const_iterator begin() const {
244  return &buffer[0];
245  }
246 
248  const_iterator end() const {
249  return &buffer[size()];
250  }
251 
253  void clear() {
254  buffer[0] = '\0';
255  }
256 
258  bool empty() const {
259  return buffer[0] == '\0';
260  }
261 
271  template <class T> int compare(const T &other) const {
272  return strncmp(*this, other, MIN(capacity(), other.capacity()));
273  }
274 
284  int compare(const char *other) const {
285  return strncmp(*this, other, capacity());
286  }
287 
289  String& operator=(const char *src) {
290  _SYS_strlcpy(buffer, src, tCapacity);
291  return *this;
292  }
293 
295  String& operator+=(const char *src) {
296  _SYS_strlcat(buffer, src, tCapacity);
297  return *this;
298  }
299 
301  char &operator[](unsigned index) {
302  return buffer[index];
303  }
304 
306  char &operator[](int index) {
307  return buffer[index];
308  }
309 
311  char operator[](unsigned index) const {
312  return buffer[index];
313  }
314 
316  char operator[](int index) const {
317  return buffer[index];
318  }
319 
321  String& operator<<(const char *src) {
322  _SYS_strlcat(buffer, src, tCapacity);
323  return *this;
324  }
325 
327  String& operator<<(int src) {
328  _SYS_strlcat_int(buffer, src, tCapacity);
329  return *this;
330  }
331 
333  String& operator<<(const Fixed &src) {
334  _SYS_strlcat_int_fixed(buffer, src.value, src.width, src.leadingZeroes, tCapacity);
335  return *this;
336  }
337 
339  String& operator<<(const FixedFP &src) {
340  _SYS_strlcat_int_fixed(buffer, src.valueL, src.widthL, src.leadingZeroes, tCapacity);
341  _SYS_strlcat(buffer, ".", tCapacity);
342  _SYS_strlcat_int_fixed(buffer, src.valueR, src.widthR, true, tCapacity);
343  return *this;
344  }
345 
347  String& operator<<(const Hex &src) {
348  _SYS_strlcat_int_hex(buffer, src.value, src.width, src.leadingZeroes, tCapacity);
349  return *this;
350  }
351 
353  String& operator<<(const Hex64 &src) {
354  uint32_t high = src.value >> 32;
355  uint32_t low = src.value;
356  if (src.width > 8 || high != 0) {
357  _SYS_strlcat_int_hex(buffer, high, src.width - 8, src.leadingZeroes, tCapacity);
358  _SYS_strlcat_int_hex(buffer, low, 8, true, tCapacity);
359  } else {
360  _SYS_strlcat_int_hex(buffer, low, src.width, src.leadingZeroes, tCapacity);
361  }
362  return *this;
363  }
364 
366  template <typename T> bool operator==(const T &other) {
367  return compare(other) == 0;
368  }
369 
371  template <typename T> bool operator!=(const T &other) {
372  return compare(other) != 0;
373  }
374 
376  template <typename T> bool operator<(const T &other) {
377  return compare(other) < 0;
378  }
379 
381  template <typename T> bool operator<=(const T &other) {
382  return compare(other) <= 0;
383  }
384 
386  template <typename T> bool operator>(const T &other) {
387  return compare(other) > 0;
388  }
389 
391  template <typename T> bool operator>=(const T &other) {
392  return compare(other) >= 0;
393  }
394 
395 private:
396  char buffer[tCapacity];
397 };
398 
403 }; // namespace Sifteo
String & operator<<(const Fixed &src)
STL-style formatting operator, append a fixed-width decimal integer.
Definition: string.h:333
Hex64(uint64_t value, unsigned width=16, bool leadingZeroes=true)
Format 'value' using exactly 'width' characters.
Definition: string.h:148
bool empty() const
Is the string empty? (Faster than size() == 0)
Definition: string.h:258
String & operator<<(const FixedFP &src)
STL-style formatting operator, append a fixed-width floating point number.
Definition: string.h:339
String & operator<<(const Hex64 &src)
STL-style formatting operator, append a fixed-width hexadecimal 64-bit integer.
Definition: string.h:353
FixedFP(float value, unsigned left, unsigned right, bool leadingZeroes=false)
Format 'value' using exactly 'left' digits to the left of the decimal, and 'right' digits to the righ...
Definition: string.h:80
Hex(uint32_t value, unsigned width=8, bool leadingZeroes=true)
Format 'value' using exactly 'width' characters.
Definition: string.h:128
String formatting wrapper for fixed-width hexadecimal 64-bit integers.
Definition: string.h:141
iterator end()
Return an iterator, pointing just past the end of the string (at the NUL)
Definition: string.h:238
String & operator<<(const Hex &src)
STL-style formatting operator, append a fixed-width hexadecimal integer.
Definition: string.h:347
char & operator[](int index)
Indexing operator, to get or set one character.
Definition: string.h:306
String & operator<<(int src)
STL-style formatting operator, append a decimal integer.
Definition: string.h:327
const char * c_str() const
Return a C-style constant character pointer.
Definition: string.h:208
const_iterator begin() const
Const version of begin()
Definition: string.h:243
int compare(const char *other) const
Compare this string against a C-style string.
Definition: string.h:284
#define ASSERT(_x)
Runtime debug assertion.
Definition: macros.h:205
String & operator=(const char *src)
Overwrite this with another string.
Definition: string.h:289
String & operator+=(const char *src)
Append another string to this one.
Definition: string.h:295
const_iterator end() const
Const version of end()
Definition: string.h:248
int compare(const T &other) const
Compare this string against another.
Definition: string.h:271
A statically sized character buffer, with output formatting support.
Definition: string.h:191
String()
Initialize a new empty string.
Definition: string.h:198
bool operator!=(const T &other)
Is this string different from another?
Definition: string.h:371
static unsigned capacity()
Retrieve the size of the buffer, in bytes, including space for NUL termination.
Definition: string.h:223
char & operator[](unsigned index)
Indexing operator, to get or set one character.
Definition: string.h:301
bool operator==(const T &other)
Is this string equal to another?
Definition: string.h:366
char * c_str()
Return a C-style character pointer.
Definition: string.h:203
char operator[](int index) const
Const indexing operator.
Definition: string.h:316
bool operator<=(const T &other)
Is this string before another or equal, in ASCII order?
Definition: string.h:381
void clear()
Overwrite this with the empty string.
Definition: string.h:253
Definition: array.h:34
String formatting wrapper for fixed-width integers.
Definition: string.h:49
unsigned size() const
Get the current size of the string, in characters, excluding NUL termination.
Definition: string.h:228
#define MIN(a, b)
Definition: macros.h:347
String & operator<<(const char *src)
STL-style formatting operator, append a string.
Definition: string.h:321
iterator begin()
Return an iterator, pointing to the first character in the string.
Definition: string.h:233
bool operator>(const T &other)
Is this string after another, in ASCII order?
Definition: string.h:386
int strncmp(const char *a, const char *b, unsigned count)
Compare two C-style strings.
Definition: string.h:165
Format a floating point number using fixed precision.
Definition: string.h:73
Fixed(int value, unsigned width, bool leadingZeroes=false)
Format 'value' using exactly 'width' characters.
Definition: string.h:56
String formatting wrapper for fixed-width hexadecimal integers.
Definition: string.h:121
unsigned strnlen(const char *str, uint32_t maxLen)
Get the length of a C-style string.
Definition: string.h:176
bool operator>=(const T &other)
Is this string after another or equal, in ASCII order?
Definition: string.h:391
char operator[](unsigned index) const
Const indexing operator.
Definition: string.h:311
bool operator<(const T &other)
Is this string before another, in ASCII order?
Definition: string.h:376