v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
string.h
1 /* -*- mode: C; c-basic-offset: 4; intent-tabs-mode: nil -*-
2  *
3  * This file is part of the public interface to the Sifteo SDK.
4  * Copyright <c> 2012 Sifteo, Inc. All rights reserved.
5  */
6 
7 #pragma once
8 #ifdef NOT_USERSPACE
9 # error This is a userspace-only header, not allowed by the current build.
10 #endif
11 
12 #include <sifteo/abi.h>
13 
14 namespace Sifteo {
15 
30 struct Fixed {
37  Fixed(int value, unsigned width, bool leadingZeroes=false)
38  : value(value), width(width), leadingZeroes(leadingZeroes) {}
39  int value;
40  unsigned width;
41  bool leadingZeroes;
42 };
43 
54 struct FixedFP {
61  FixedFP(float value, unsigned left, unsigned right, bool leadingZeroes=false)
62  : widthL(left), widthR(right), leadingZeroes(leadingZeroes)
63  {
64  // Left side: truncate to integer
65  valueL = int(value);
66 
67  /*
68  * Right side: We want to convert the right side to an integer by
69  * multiplying it by 10^right, then we can rely on String's
70  * field width truncation to do the rest. There aren't very many
71  * values of 'right' that won't overflow, so we can do this
72  * with a lookup table. Typically the field width is constant
73  * at compile-time, so this lookup table will optimize out.
74  */
75  switch (right) {
76  default: ASSERT(0);
77  case 0: valueR = value * 0; break;
78  case 1: valueR = value * 10; break;
79  case 2: valueR = value * 100; break;
80  case 3: valueR = value * 1000; break;
81  case 4: valueR = value * 10000; break;
82  case 5: valueR = value * 100000; break;
83  case 6: valueR = value * 1000000; break;
84  case 7: valueR = value * 10000000; break;
85  case 8: valueR = value * 100000000; break;
86  case 9: valueR = value * 1000000000; break;
87  }
88  }
89 
90  int valueL;
91  int valueR;
92  unsigned widthL, widthR;
93  bool leadingZeroes;
94 };
95 
102 struct Hex {
109  Hex(uint32_t value, unsigned width=8, bool leadingZeroes=true)
110  : value(value), width(width), leadingZeroes(leadingZeroes) {}
111  uint32_t value;
112  unsigned width;
113  bool leadingZeroes;
114 };
115 
122 struct Hex64 {
129  Hex64(uint64_t value, unsigned width=16, bool leadingZeroes=true)
130  : value(value), width(width), leadingZeroes(leadingZeroes) {}
131  uint64_t value;
132  unsigned width;
133  bool leadingZeroes;
134 };
135 
136 
146 inline int strncmp(const char *a, const char *b, unsigned count)
147 {
148  return _SYS_strncmp(a, b, count);
149 }
150 
157 inline unsigned strnlen(const char *str, uint32_t maxLen) {
158  return _SYS_strnlen(str, maxLen);
159 }
160 
171 template <unsigned tCapacity>
172 class String {
173 public:
174 
175  typedef char* iterator;
176  typedef const char* const_iterator;
177 
179  String() {
180  clear();
181  }
182 
184  char * c_str() {
185  return buffer;
186  }
187 
189  const char * c_str() const {
190  return buffer;
191  }
192 
194  operator char *() {
195  return buffer;
196  }
197 
199  operator const char *() const {
200  return buffer;
201  }
202 
204  static unsigned capacity() {
205  return tCapacity;
206  }
207 
209  unsigned size() const {
210  return _SYS_strnlen(buffer, tCapacity-1);
211  }
212 
214  iterator begin() {
215  return &buffer[0];
216  }
217 
219  iterator end() {
220  return &buffer[size()];
221  }
222 
224  const_iterator begin() const {
225  return &buffer[0];
226  }
227 
229  const_iterator end() const {
230  return &buffer[size()];
231  }
232 
234  void clear() {
235  buffer[0] = '\0';
236  }
237 
239  bool empty() const {
240  return buffer[0] == '\0';
241  }
242 
252  template <class T> int compare(const T &other) const {
253  return strncmp(*this, other, MIN(capacity(), other.capacity()));
254  }
255 
265  int compare(const char *other) const {
266  return strncmp(*this, other, capacity());
267  }
268 
270  String& operator=(const char *src) {
271  _SYS_strlcpy(buffer, src, tCapacity);
272  return *this;
273  }
274 
276  String& operator+=(const char *src) {
277  _SYS_strlcat(buffer, src, tCapacity);
278  return *this;
279  }
280 
282  char &operator[](unsigned index) {
283  return buffer[index];
284  }
285 
287  char &operator[](int index) {
288  return buffer[index];
289  }
290 
292  char operator[](unsigned index) const {
293  return buffer[index];
294  }
295 
297  char operator[](int index) const {
298  return buffer[index];
299  }
300 
302  String& operator<<(const char *src) {
303  _SYS_strlcat(buffer, src, tCapacity);
304  return *this;
305  }
306 
308  String& operator<<(int src) {
309  _SYS_strlcat_int(buffer, src, tCapacity);
310  return *this;
311  }
312 
314  String& operator<<(const Fixed &src) {
315  _SYS_strlcat_int_fixed(buffer, src.value, src.width, src.leadingZeroes, tCapacity);
316  return *this;
317  }
318 
320  String& operator<<(const FixedFP &src) {
321  _SYS_strlcat_int_fixed(buffer, src.valueL, src.widthL, src.leadingZeroes, tCapacity);
322  _SYS_strlcat(buffer, ".", tCapacity);
323  _SYS_strlcat_int_fixed(buffer, src.valueR, src.widthR, true, tCapacity);
324  return *this;
325  }
326 
328  String& operator<<(const Hex &src) {
329  _SYS_strlcat_int_hex(buffer, src.value, src.width, src.leadingZeroes, tCapacity);
330  return *this;
331  }
332 
334  String& operator<<(const Hex64 &src) {
335  uint32_t high = src.value >> 32;
336  uint32_t low = src.value;
337  if (src.width > 8 || high != 0) {
338  _SYS_strlcat_int_hex(buffer, high, src.width - 8, src.leadingZeroes, tCapacity);
339  _SYS_strlcat_int_hex(buffer, low, 8, true, tCapacity);
340  } else {
341  _SYS_strlcat_int_hex(buffer, low, src.width, src.leadingZeroes, tCapacity);
342  }
343  return *this;
344  }
345 
347  template <typename T> bool operator==(const T &other) {
348  return compare(other) == 0;
349  }
350 
352  template <typename T> bool operator!=(const T &other) {
353  return compare(other) != 0;
354  }
355 
357  template <typename T> bool operator<(const T &other) {
358  return compare(other) < 0;
359  }
360 
362  template <typename T> bool operator<=(const T &other) {
363  return compare(other) <= 0;
364  }
365 
367  template <typename T> bool operator>(const T &other) {
368  return compare(other) > 0;
369  }
370 
372  template <typename T> bool operator>=(const T &other) {
373  return compare(other) >= 0;
374  }
375 
376 private:
377  char buffer[tCapacity];
378 };
379 
384 }; // namespace Sifteo