Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef _Common_string_HH | |
9 | #define _Common_string_HH | |
10 | ||
11 | #include <string.h> | |
12 | ||
13 | class stringpool; | |
14 | class ustring; | |
15 | ||
16 | /** | |
17 | * Class for handling general string operations. | |
18 | */ | |
19 | class string { | |
20 | friend class stringpool; | |
21 | friend string operator+(const char *s1, const string& s2); | |
22 | ||
23 | /** string value structure */ | |
24 | struct string_struct { | |
25 | unsigned int ref_count; | |
26 | size_t n_chars; | |
27 | char chars_ptr[sizeof(size_t)]; | |
28 | } *val_ptr; | |
29 | ||
30 | string(size_t n) : val_ptr(0) { init_struct(n); } | |
31 | string(string_struct *ptr) : val_ptr(ptr) { val_ptr->ref_count++; } | |
32 | ||
33 | void init_struct(size_t n_chars); | |
34 | void copy_value_and_append(const char *s, size_t n); | |
35 | void replace(size_t pos, size_t n, const char *s, size_t s_len); | |
36 | static void clean_up(string_struct *ptr); | |
37 | ||
38 | /** Three-way lexicographical comparison of \a *this and \a s, | |
39 | * much like \c strcmp. */ | |
40 | int compare(const string& s) const; | |
41 | ||
42 | /** Three-way lexicographical comparison of \a *this and \a s, | |
43 | * much like \c strcmp. */ | |
44 | int compare(const char *s) const; | |
45 | ||
46 | public: | |
47 | /** The largest possible value of type size_t. That is, size_t(-1). */ | |
48 | static const size_t max_string_len = (size_t)-1 - | |
49 | (sizeof(string_struct) - sizeof(size_t) + 1); | |
50 | ||
51 | /** Constructs an empty string. */ | |
52 | string() : val_ptr(0) { init_struct(0); } | |
53 | ||
54 | /** Constructs a string containing single character \a c. */ | |
55 | explicit string(char c) : val_ptr(0) | |
56 | { init_struct(1); val_ptr->chars_ptr[0] = c; } | |
57 | ||
58 | /** Constructs a string from \a s. */ | |
59 | explicit string(const char *s); | |
60 | ||
61 | /** Constructs a string from \a s taking the first \a n characters. */ | |
62 | string(size_t n, const char *s); | |
63 | ||
64 | /** Copy constructor */ | |
65 | string(const string& s) : val_ptr(s.val_ptr) { val_ptr->ref_count++; } | |
66 | ||
67 | /** Constructs a string from ustring \a s. All characters of \a s must fit | |
68 | * in one byte. */ | |
69 | explicit string(const ustring& s); | |
70 | ||
71 | /** The destructor. */ | |
72 | ~string() { clean_up(val_ptr); } | |
73 | ||
74 | /** Returns the size of the string. */ | |
75 | size_t size() const { return val_ptr->n_chars; } | |
76 | ||
77 | /** true if the string's size is 0. */ | |
78 | bool empty() const { return val_ptr->n_chars == 0; } | |
79 | ||
80 | /** true if the string contains a valid value of TTCN-3 type charstring | |
81 | * i.e. character code of every character is within the range 0..127 */ | |
82 | bool is_cstr() const; | |
83 | ||
84 | /** Returns a pointer to a null-terminated array of characters | |
85 | * representing the string's contents. */ | |
86 | const char *c_str() const { return val_ptr->chars_ptr; } | |
87 | ||
88 | /** Erases the string; identical to \a *this="". */ | |
89 | void clear(); | |
90 | ||
91 | /** Creates a string from a substring of \a *this. | |
92 | * The substring begins at character position \a pos, | |
93 | * and terminates at character position \a pos+n or at the end of | |
94 | * the string, whichever comes first. */ | |
95 | string substr(size_t pos=0, size_t n=max_string_len) const; | |
96 | ||
97 | /** Appends characters, or erases characters from the end, | |
98 | * as necessary to make the string's length exactly \a n characters. */ | |
99 | void resize(size_t n, char c = '\0'); | |
100 | ||
101 | /** Replaces the \a n long substring of \a *this beginning | |
102 | * at position \a pos with the string \a s. */ | |
103 | void replace(size_t pos, size_t n, const string& s); | |
104 | ||
105 | /** Replaces the \a n long substring of \a *this beginning | |
106 | * at position \a pos with the string \a s. | |
107 | * @pre \a s must not be NULL */ | |
108 | void replace(size_t pos, size_t n, const char *s); | |
109 | ||
110 | /** Searches for the character \a c, beginning at character | |
111 | * position \a pos. If not found, returns size(). */ | |
112 | size_t find(char c, size_t pos=0) const; | |
113 | ||
114 | /** Searches for a null-terminated character array | |
115 | * as a substring of \a *this, beginning at character \a pos | |
116 | * of \a *this. If not found, returns size(). */ | |
117 | size_t find(const char* s, size_t pos=0) const; | |
118 | ||
119 | /** Searches backward for the character \a c, | |
120 | * beginning at character position \a min(pos, size()). */ | |
121 | size_t rfind(char c, size_t pos=max_string_len) const; | |
122 | ||
123 | /** Searches backward for a null-terminated character array | |
124 | * as a substring of \a *this, beginning at character | |
125 | * min(pos, size()) | |
126 | size_t rfind(const char* s, size_t pos=max_string_len) const; */ | |
127 | ||
128 | /** | |
129 | * Returns the first position \a i in the range [first, last) | |
130 | * such that <tt>pred((*this)[i]) != 0</tt>. | |
131 | * Returns \a last if no such position exists. | |
132 | * | |
133 | * I want to use this function like this: | |
134 | * \code size_t pos=str.find_if(0, str.size(), islower); \endcode | |
135 | */ | |
136 | size_t find_if(size_t first, size_t last, | |
137 | int (*pred)(int)) const; | |
138 | ||
139 | /** Returns whether \a c is a whitespace character */ | |
140 | static bool is_whitespace(unsigned char c); | |
141 | /** Returns whether \a c is a printable character */ | |
142 | static bool is_printable(unsigned char c); | |
143 | /** Appends the (possibly escaped) printable representation of character | |
144 | * \a c to \a this. Applicable only if \a c is a printable character. */ | |
145 | void append_stringRepr(char c); | |
146 | /** Returns the printable representation of charstring value stored in | |
147 | * \a this. The non-printable and special characters are escaped in the | |
148 | * returned string. */ | |
149 | string get_stringRepr() const; | |
150 | ||
151 | /** Creates universal string from pattern form: ([A-P]{8})* | |
152 | * | |
153 | */ | |
154 | ustring convert_stringRepr_for_pattern() const; | |
155 | ||
156 | /** Assignment operator. */ | |
157 | string& operator=(const string&); | |
158 | ||
159 | /** Assign a null-terminated character array to a string. */ | |
160 | string& operator=(const char *s); | |
161 | ||
162 | /** Returns the <em>n</em>th character. | |
163 | * The first character's position is zero. | |
164 | * If \a n >= size() then... Fatal error. */ | |
165 | char& operator[](size_t n); | |
166 | ||
167 | /** Returns the <em>n</em>th character. | |
168 | * The first character's position is zero. | |
169 | * If \a n >= size() then... Fatal error. */ | |
170 | char operator[](size_t n) const; | |
171 | ||
172 | /** String concatenation. */ | |
173 | string operator+(const string& s) const; | |
174 | ||
175 | /** String concatenation. */ | |
176 | string operator+(const char *s) const; | |
177 | ||
178 | /** Append \a s to \a *this. */ | |
179 | string& operator+=(const string& s); | |
180 | ||
181 | /** Append \a s to \a *this. */ | |
182 | string& operator+=(const char *s); | |
183 | ||
184 | /** Append \a c to \a *this. */ | |
185 | string& operator+=(char c) { copy_value_and_append(&c, 1); return *this; } | |
186 | ||
187 | /** String equality. Equivalent to this->compare(string(s)) == 0. */ | |
188 | bool operator==(const char *s) const; | |
189 | ||
190 | /** String equality. Equivalent to this->compare(s2) == 0. */ | |
191 | bool operator==(const string& s) const; | |
192 | ||
193 | /** String inequality. Equivalent to this->compare(s2) != 0. */ | |
194 | inline bool operator!=(const string& s) const { return !(*this == s); } | |
195 | ||
196 | /** String inequality. Equivalent to this->compare(string(s2)) != 0. */ | |
197 | inline bool operator!=(const char *s) const { return !(*this == s); } | |
198 | ||
199 | /** String comparison. */ | |
200 | inline bool operator<=(const string& s) const { return compare(s) <= 0; } | |
201 | ||
202 | /** String comparison. */ | |
203 | inline bool operator<=(const char *s) const { return compare(s) <= 0; } | |
204 | ||
205 | /** String comparison. */ | |
206 | inline bool operator<(const string& s) const { return compare(s) < 0; } | |
207 | ||
208 | /** String comparison. */ | |
209 | inline bool operator<(const char *s) const { return compare(s) < 0; } | |
210 | ||
211 | /** String comparison. */ | |
212 | inline bool operator>=(const string& s) const { return compare(s) >= 0; } | |
213 | ||
214 | /** String comparison. */ | |
215 | inline bool operator>=(const char *s) const { return compare(s) >= 0; } | |
216 | ||
217 | /** String comparison. */ | |
218 | inline bool operator>(const string& s) const { return compare(s) > 0; } | |
219 | ||
220 | /** String comparison. */ | |
221 | inline bool operator>(const char *s) const { return compare(s) > 0; } | |
222 | }; | |
223 | ||
224 | /** String concatenation. */ | |
225 | extern string operator+(const char *s1, const string& s2); | |
226 | ||
227 | /** String equality. */ | |
228 | inline bool operator==(const char *s1, const string& s2) { return s2 == s1; } | |
229 | ||
230 | /** String inequality. */ | |
231 | inline bool operator!=(const char *s1, const string& s2) { return !(s2 == s1); } | |
232 | ||
233 | /** | |
234 | * Class for preserving the memory allocated for temporary strings within a | |
235 | * statement block. | |
236 | */ | |
237 | class stringpool { | |
238 | string::string_struct **string_list; | |
239 | size_t list_size; /**< The number of strings allocated */ | |
240 | size_t list_len; /**< The number of strings in use. At most \a list_size */ | |
241 | /** Copy constructor not implemented */ | |
242 | stringpool(const stringpool& p); | |
243 | /** Assignment not implemented */ | |
244 | stringpool& operator=(const stringpool& p); | |
245 | ||
246 | public: | |
247 | /** Drops all strings from the pool. */ | |
248 | void clear(); | |
249 | /** Default constructor: creates an empty pool */ | |
250 | stringpool() : string_list(NULL), list_size(0), list_len(0) { } | |
251 | /** Destructor: drops the contents of the entire pool */ | |
252 | ~stringpool() { clear(); } | |
253 | /** Adds the current value of string \a s to the pool and returns its | |
254 | * pointer. The pointer is usable until \a this stringpool is destructed. */ | |
255 | const char *add(const string& s); | |
256 | /** Returns the number of strings in the pool */ | |
257 | size_t size() const { return list_len; } | |
258 | /** Returns the pointer to the \a n-th string of the pool */ | |
259 | const char *get_str(size_t n) const; | |
260 | /** Returns a newly constructed string containing the \a n-th element */ | |
261 | string get_string(size_t n) const; | |
262 | }; | |
263 | ||
264 | #endif // _Common_string_HH |