]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/cxx/lib/base/include/string
3a94584f43a67d44a3c94e63561c2a676b198180
[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   bool 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 false;
133     return i == c._len;
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_hex(INT *v) const
179   {
180     *v = 0;
181     unsigned shift = 0;
182     Index c;
183     for (c = start(); !eof(c); ++c)
184       {
185         shift += 4;
186         if (shift > sizeof(INT) * 8)
187           return -1;
188         *v <<= 4;
189         unsigned char n;
190         if (*c >= '0' && *c <= '9')
191           n = *c - '0';
192         else if (*c >= 'A' && *c <= 'F')
193           n = *c - 'A' + 10;
194         else if (*c >= 'a' && *c <= 'f')
195           n = *c - 'a' + 10;
196         else
197           return c - start();
198
199         *v |= n;
200       }
201     return c - start();
202   }
203
204   bool operator == (String const &o) const
205   {
206     if (len() != o.len())
207       return false;
208
209     for (unsigned long i = 0; i < _len; ++i)
210       if (_start[i] != o._start[i])
211         return false;
212
213     return true;
214   }
215
216   bool operator != (String const &o) const
217   { return ! (operator == (o)); }
218
219 private:
220
221   char const *_start;
222   unsigned long      _len;
223
224 };
225
226 }
227
228 inline
229 L4::BasicOStream &operator << (L4::BasicOStream &s, cxx::String const &str)
230 {
231   s.write(str.start(), str.len());
232   return s;
233 }