1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 // -*- c++ -*-
19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20
21 // O S C L_ S T R I N G C L A S S
22
23 // This is a simple string class without any multithread access
24 // protection.
25
26 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
27
28 #ifndef UNIT_TEST_LOCAL_STRING_H
29 #define UNIT_TEST_LOCAL_STRING_H
30
31 // - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - -
32
_strlen(const char * s)33 inline int _strlen(const char* s)
34 {
35 for (int i = 0; ; i++)
36 {
37 if (s[i] == '\0')
38 return i;
39 }
40 }
41
_strcat(char * dest,const char * src)42 inline char* _strcat(char* dest, const char* src)
43 {
44 char* tmp = dest + _strlen(dest);
45 for (uint32 i = 0; *src != '\0'; i++)
46 {
47 *tmp++ = *src++;
48 }
49 *tmp = '\0';
50 return dest;
51 }
52
_strncpy(char * dest,const char * src,uint32 count)53 inline char* _strncpy(char* dest, const char* src, uint32 count)
54 {
55 char* tmp = dest;
56 uint32 ii;
57 for (ii = 0; ii < count && *src != '\0'; ii++)
58 {
59 *tmp++ = *src++;
60 }
61 // pad with null chars upto length count
62 for (; ii < count; ii++)
63 {
64 *tmp++ = '\0';
65 }
66 return dest;
67 }
68
_strcmp(const char * str1,const char * str2)69 inline int32 _strcmp(const char* str1, const char* str2)
70 {
71 while ((*str1 == *str2) && (*str1 != '\0'))
72 {
73 str1++;
74 str2++;
75 }
76 return (*str1 - *str2);
77 }
78
79 // **************************************************************
80
81 /** @name UnitTest_String is a simple string class
82 which is compatible with regular character array
83 strings as well as Unicode wchar_t array strings.
84
85 The class uses a copy-on-write to minimize unnecessary
86 copying when multiple instances of a string are created
87 for reading. Allocated memory is automatically freed by
88 the class destructor when the last string referencing the
89 memory is destroyed. The class HAS NO thread synchronization
90 built-in, so it is NOT MT-SAFE. External locks should be used
91 if the class is to be shared across threads.
92 */
93
94 class UnitTest_String_Srep : public UnitTest_HeapBase
95 {
96 public:
97
98 char *buffer; // holds actual string value
99 int32 size; // number of elements;
100 int32 refcnt; // reference count;
101
UnitTest_String_Srep(uint32 nsz,const char * src)102 UnitTest_String_Srep(uint32 nsz, const char *src)
103 {
104 refcnt = 1;
105 size = nsz;
106 buffer = (char*)unit_test_allocator::allocate(size + 1); /* allocate enough space
107 * including terminator
108 */
109 _strncpy(buffer, src, size);
110
111 buffer[size] = '\0';
112
113 }
114
~UnitTest_String_Srep()115 ~UnitTest_String_Srep()
116 {
117 unit_test_allocator::deallocate(buffer);
118 }
119
get_own_copy()120 UnitTest_String_Srep* get_own_copy()
121 {
122 if (1 == refcnt)
123 {
124 // already a private copy so return
125 return this;
126 }
127
128
129 --refcnt; // decrement reference
130
131 UnitTest_String_Srep *tmp = new UnitTest_String_Srep(size, buffer);
132 return tmp;
133 }
134
assign(int32 nsz,const char * src)135 void assign(int32 nsz, const char *src)
136 {
137
138 if (size != nsz)
139 {
140 unit_test_allocator::deallocate(buffer);
141 size = nsz;
142 buffer = (char*)unit_test_allocator::allocate(size + 1);
143 }
144
145 _strncpy(buffer, src, size);
146 buffer[size] = '\0';
147
148 }
149
150 private:
151 UnitTest_String_Srep(const UnitTest_String_Srep&);
152 UnitTest_String_Srep& operator=(const UnitTest_String_Srep&);
153
154 };
155
156 class UnitTest_String
157 {
158
159 private:
160 // Not needed anymore! struct Srep; // Note this is a forward declaraton only, allocates no memory.
161 typedef UnitTest_String_Srep Srep;
162 Srep *rep;
163
164 public:
165
166 /// Default constructor -- simply creates an empty string
167 UnitTest_String();
168
169 /// Copy constructor from character array
170 UnitTest_String(const char *cp);
171
172 /// Copy constructor from character array, but allocates
173 /// length according to the length parameter.
174 UnitTest_String(const char *src, uint32 length);
175
176 /// Copy constructor from another UnitTest_String
177 UnitTest_String(const UnitTest_String& src);
178
179 /// Assignment operator from a character array
180 UnitTest_String& operator=(const char *);
181
182 /// Assignment operator from another UnitTest_String
183 UnitTest_String& operator=(const UnitTest_String &);
184
185
186 friend int32 operator== (const UnitTest_String& a, const UnitTest_String& b);
187 friend int32 operator!= (const UnitTest_String& a, const UnitTest_String& b);
188 friend int32 operator< (const UnitTest_String& a, const UnitTest_String& b);
189 friend int32 operator<= (const UnitTest_String& a, const UnitTest_String& b);
190 friend int32 operator> (const UnitTest_String& a, const UnitTest_String& b);
191 friend int32 operator>= (const UnitTest_String& a, const UnitTest_String& b);
192
193
194 ~UnitTest_String();
195
196 /// Access functions for the string size
197 int32 get_size() const;
size()198 int32 size() const
199 {
200 return get_size();
201 };
202
203 /// Access function for the C-style string
204 const char * get_cstr() const;
c_str()205 const char * c_str() const
206 {
207 return get_cstr();
208 };
209
210 /// Append a c-style string
211 UnitTest_String& operator+=(const char* src);
212
213 /// Append another UnitTest_String to this UnitTest_String
214 UnitTest_String& operator+=(const UnitTest_String& src);
215
216 /// Append a single character
217 UnitTest_String& operator+=(const char c);
218
219 char operator[](int32 index) const;
220
221
222 };
223
get_cstr()224 inline const char * UnitTest_String::get_cstr() const
225 {
226 return rep->buffer;
227 }
228
get_size()229 inline int32 UnitTest_String::get_size() const
230 {
231 return rep->size;
232 }
233
234 inline int32 operator==(const UnitTest_String& a, const UnitTest_String& b)
235 {
236 return (!_strcmp(a.rep->buffer, b.rep->buffer));
237 }
238
239 inline int32 operator!=(const UnitTest_String& a, const UnitTest_String& b)
240 {
241 return (_strcmp(a.rep->buffer, b.rep->buffer) != 0);
242 }
243
244 inline int32 operator>(const UnitTest_String& a, const UnitTest_String& b)
245 {
246 return (_strcmp(a.rep->buffer, b.rep->buffer) > 0);
247 }
248
249 inline int32 operator>=(const UnitTest_String& a, const UnitTest_String& b)
250 {
251 return (_strcmp(a.rep->buffer, b.rep->buffer) >= 0);
252 }
253
254 inline int32 operator<=(const UnitTest_String& a, const UnitTest_String& b)
255 {
256 return (_strcmp(a.rep->buffer, b.rep->buffer) <= 0);
257 }
258
259 inline int32 operator<(const UnitTest_String& a, const UnitTest_String& b)
260 {
261 return (_strcmp(a.rep->buffer, b.rep->buffer) < 0);
262 }
263
264 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
UnitTest_String()265 inline UnitTest_String::UnitTest_String()
266 {
267 char *ptr = NULL;
268 rep = new Srep(0, ptr);
269 }
270
UnitTest_String(const char * cp)271 inline UnitTest_String::UnitTest_String(const char *cp)
272 {
273 if (cp)
274 rep = new Srep(_strlen(cp), cp);
275 else
276 rep = new Srep(0, cp);
277 }
278
UnitTest_String(const char * cp,uint32 length)279 inline UnitTest_String::UnitTest_String(const char *cp, uint32 length)
280 {
281 rep = new Srep(length, cp);
282 }
283
UnitTest_String(const UnitTest_String & src)284 inline UnitTest_String::UnitTest_String(const UnitTest_String& src)
285 {
286 src.rep->refcnt++;
287 rep = src.rep;
288 }
289
~UnitTest_String()290 inline UnitTest_String::~UnitTest_String()
291 {
292 if (--rep->refcnt == 0) delete rep;
293 }
294
295 inline UnitTest_String& UnitTest_String::operator=(const UnitTest_String & src)
296 {
297
298 if (rep == src.rep)
299 {
300 return *this; // protect against "str = str"
301 }
302 src.rep->refcnt++;
303 if (--rep->refcnt == 0)
304 {
305 delete rep;
306 }
307
308 rep = src.rep;
309 return *this;
310 }
311
312 inline UnitTest_String& UnitTest_String::operator=(const char * cp)
313 {
314 if (--rep->refcnt == 0)
315 {
316 delete rep;
317 }
318
319 if (cp == NULL)
320 {
321 rep = new Srep(0, cp);
322 }
323 else
324 {
325 rep = new Srep(_strlen(cp), cp);
326 }
327 return *this;
328 }
329
330 inline UnitTest_String& UnitTest_String::operator+=(const char * src)
331 {
332 Srep *new_rep;
333 int32 new_size = rep->size + _strlen(src);
334 new_rep = new Srep(new_size, rep->buffer);
335 _strcat(new_rep->buffer, src);
336 if (--rep->refcnt == 0)
337 {
338 delete rep;
339 }
340 rep = new_rep;
341 return *this;
342 }
343
344 inline UnitTest_String& UnitTest_String::operator+=(const UnitTest_String & src)
345 {
346 Srep *new_rep;
347 int32 new_size = rep->size + src.rep->size;
348 new_rep = new Srep(new_size, rep->buffer);
349 _strcat(new_rep->buffer, src.rep->buffer);
350 if (--rep->refcnt == 0)
351 {
352 delete rep;
353 }
354 rep = new_rep;
355 return *this;
356 }
357
358 inline UnitTest_String& UnitTest_String::operator+=(const char c)
359 {
360 char tmp_str[2];
361 tmp_str[0] = c;
362 tmp_str[1] = (char)'\0';
363
364 return ((*this) += tmp_str);
365 }
366
367 inline char UnitTest_String::operator[](int32 index) const
368 {
369 if (index < 0 || index >= rep->size)
370 return '\0';
371 return rep->buffer[index];
372 }
373
374
375
376 #endif //UNIT_TEST_LOCAL_STRING_H
377
378