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