]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cxx/lib/base/include/string
update
[l4.git] / l4 / pkg / cxx / lib / base / include / string
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  *
10  * As a special exception, you may use this file as part of a free software
11  * library without restriction.  Specifically, if other files instantiate
12  * templates or use macros or inline functions from this file, or you compile
13  * this file and link it with other files to produce an executable, this
14  * file does not by itself cause the resulting executable to be covered by
15  * the GNU General Public License.  This exception does not however
16  * invalidate any other reasons why the executable file might be covered by
17  * the GNU General Public License.
18  */
19
20 #pragma once
21
22 #include <l4/cxx/minmax>
23 #include <l4/cxx/basic_ostream>
24
25
26 namespace cxx {
27
28 /*
29  * This class is used to group characters of a string which belong
30  * to one syntactical token types number, identifier, string,
31  * whitespace or another single character.
32  */
33 class String
34 {
35 public:
36
37   typedef char const *Index;
38
39   String(char const *s) throw() : _start(s), _len(__builtin_strlen(s)) {}
40   String(char const *s, unsigned long len) throw() : _start(s), _len(len) {}
41   String(char const *s, char const *e) throw() : _start(s), _len(e-s) {}
42
43   String() : _start(0), _len(0) {}
44
45   Index start() const { return _start; }
46   Index end() const { return _start + _len; }
47   int len() const { return _len; }
48
49   void start(char const *s) { _start = s; }
50   void len(unsigned long len) { _len = len; }
51   bool empty() const { return !_len; }
52
53   String head(Index end) const
54   {
55     if (end < _start)
56       return String();
57
58     if (eof(end))
59       return *this;
60
61     return String(_start, end - _start);
62   }
63
64   String head(unsigned long end) const
65   { return head(start() + end); }
66
67   String substr(unsigned long idx, unsigned long len = ~0UL) const
68   {
69     if (idx >= _len)
70       return String(end(), 0UL);
71
72     return String(_start + idx, cxx::min(len, _len - idx));
73   }
74
75   String substr(char const *start, unsigned long len = 0) const
76   {
77     if (start >= _start && !eof(start))
78       {
79         unsigned long nlen =_start + _len - start;
80         if (len != 0)
81           nlen = cxx::min(nlen, len);
82         return String(start, nlen);
83       }
84
85     return String(end(), 0UL);
86   }
87
88   template< typename F >
89   char const *find_match(F const &match) const
90   {
91     String::Index s = _start;
92     while (1)
93       {
94         if (eof(s))
95           return s;
96
97         if (match(*s))
98           return s;
99
100         ++s;
101       }
102   }
103
104   char const *find(char const *c) const
105   { return find(c, start());  }
106
107   char const *find(int c) const
108   { return find(c, start());  }
109
110   char const *rfind(char const *c) const
111   {
112     if (!_len)
113       return end();
114
115     char const *p = end();
116     --p;
117     while (p >= _start)
118       {
119         if (*p == *c)
120           return p;
121         --p;
122       }
123     return end();
124
125   }
126
127   Index starts_with(cxx::String const &c) const
128   {
129     unsigned long i;
130     for (i = 0; i < c._len && i < _len; ++i)
131       if (_start[i] != c[i])
132         return 0;
133     return i == c._len ? start() + i : 0;
134   }
135
136   char const *find(int c, char const *s) const
137   {
138     if (s<_start)
139       return end();
140
141     while (1)
142       {
143         if (eof(s))
144           return s;
145
146         if (*s == c)
147           return s;
148
149         ++s;
150       }
151   }
152
153   char const *find(char const *c, char const *s) const
154   {
155     if (s<_start)
156       return end();
157
158     while (1)
159       {
160         if (eof(s))
161           return s;
162
163         for (char const *x = c; *x; ++x)
164           if (*s == *x)
165             return s;
166
167         ++s;
168       }
169   }
170
171   char const &operator [] (unsigned long idx) const { return _start[idx]; }
172   char const &operator [] (int idx) const { return _start[idx]; }
173   char const &operator [] (Index idx) const { return *idx; }
174
175   bool eof(char const *s) const { return s >= _start + _len || !*s; }
176
177   template<typename INT>
178   int from_dec(INT *v) const
179   {
180     *v = 0;
181     Index c;
182     for (c = start(); !eof(c); ++c)
183       {
184         unsigned char n;
185         if (*c >= '0' && *c <= '9')
186           n = *c - '0';
187         else
188           return c - start();
189
190         *v *= 10;
191         *v += n;
192       }
193     return c - start();
194   }
195
196   template<typename INT>
197   int from_hex(INT *v) const
198   {
199     *v = 0;
200     unsigned shift = 0;
201     Index c;
202     for (c = start(); !eof(c); ++c)
203       {
204         shift += 4;
205         if (shift > sizeof(INT) * 8)
206           return -1;
207         unsigned char n;
208         if (*c >= '0' && *c <= '9')
209           n = *c - '0';
210         else if (*c >= 'A' && *c <= 'F')
211           n = *c - 'A' + 10;
212         else if (*c >= 'a' && *c <= 'f')
213           n = *c - 'a' + 10;
214         else
215           return c - start();
216
217         *v <<= 4;
218         *v |= n;
219       }
220     return c - start();
221   }
222
223   bool operator == (String const &o) const
224   {
225     if (len() != o.len())
226       return false;
227
228     for (unsigned long i = 0; i < _len; ++i)
229       if (_start[i] != o._start[i])
230         return false;
231
232     return true;
233   }
234
235   bool operator != (String const &o) const
236   { return ! (operator == (o)); }
237
238 private:
239
240   char const *_start;
241   unsigned long      _len;
242
243 };
244
245 }
246
247 inline
248 L4::BasicOStream &operator << (L4::BasicOStream &s, cxx::String const &str)
249 {
250   s.write(str.start(), str.len());
251   return s;
252 }