• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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