blob: 28ec2b283b39624cfa973d33a91dec059c9db42a [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
// -*- c++ -*-
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// O S C L_ S T R I N G C L A S S
// This is a simple string class without any multithread access
// protection.
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
#ifndef UNIT_TEST_LOCAL_STRING_H
#define UNIT_TEST_LOCAL_STRING_H
// - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline int _strlen(const char* s)
{
for (int i = 0; ; i++)
{
if (s[i] == '\0')
return i;
}
}
inline char* _strcat(char* dest, const char* src)
{
char* tmp = dest + _strlen(dest);
for (uint32 i = 0; *src != '\0'; i++)
{
*tmp++ = *src++;
}
*tmp = '\0';
return dest;
}
inline char* _strncpy(char* dest, const char* src, uint32 count)
{
char* tmp = dest;
uint32 ii;
for (ii = 0; ii < count && *src != '\0'; ii++)
{
*tmp++ = *src++;
}
// pad with null chars upto length count
for (; ii < count; ii++)
{
*tmp++ = '\0';
}
return dest;
}
inline int32 _strcmp(const char* str1, const char* str2)
{
while ((*str1 == *str2) && (*str1 != '\0'))
{
str1++;
str2++;
}
return (*str1 - *str2);
}
// **************************************************************
/** @name UnitTest_String is a simple string class
which is compatible with regular character array
strings as well as Unicode wchar_t array strings.
The class uses a copy-on-write to minimize unnecessary
copying when multiple instances of a string are created
for reading. Allocated memory is automatically freed by
the class destructor when the last string referencing the
memory is destroyed. The class HAS NO thread synchronization
built-in, so it is NOT MT-SAFE. External locks should be used
if the class is to be shared across threads.
*/
class UnitTest_String_Srep : public UnitTest_HeapBase
{
public:
char *buffer; // holds actual string value
int32 size; // number of elements;
int32 refcnt; // reference count;
UnitTest_String_Srep(uint32 nsz, const char *src)
{
refcnt = 1;
size = nsz;
buffer = (char*)unit_test_allocator::allocate(size + 1); /* allocate enough space
* including terminator
*/
_strncpy(buffer, src, size);
buffer[size] = '\0';
}
~UnitTest_String_Srep()
{
unit_test_allocator::deallocate(buffer);
}
UnitTest_String_Srep* get_own_copy()
{
if (1 == refcnt)
{
// already a private copy so return
return this;
}
--refcnt; // decrement reference
UnitTest_String_Srep *tmp = new UnitTest_String_Srep(size, buffer);
return tmp;
}
void assign(int32 nsz, const char *src)
{
if (size != nsz)
{
unit_test_allocator::deallocate(buffer);
size = nsz;
buffer = (char*)unit_test_allocator::allocate(size + 1);
}
_strncpy(buffer, src, size);
buffer[size] = '\0';
}
private:
UnitTest_String_Srep(const UnitTest_String_Srep&);
UnitTest_String_Srep& operator=(const UnitTest_String_Srep&);
};
class UnitTest_String
{
private:
// Not needed anymore! struct Srep; // Note this is a forward declaraton only, allocates no memory.
typedef UnitTest_String_Srep Srep;
Srep *rep;
public:
/// Default constructor -- simply creates an empty string
UnitTest_String();
/// Copy constructor from character array
UnitTest_String(const char *cp);
/// Copy constructor from character array, but allocates
/// length according to the length parameter.
UnitTest_String(const char *src, uint32 length);
/// Copy constructor from another UnitTest_String
UnitTest_String(const UnitTest_String& src);
/// Assignment operator from a character array
UnitTest_String& operator=(const char *);
/// Assignment operator from another UnitTest_String
UnitTest_String& operator=(const UnitTest_String &);
friend int32 operator== (const UnitTest_String& a, const UnitTest_String& b);
friend int32 operator!= (const UnitTest_String& a, const UnitTest_String& b);
friend int32 operator< (const UnitTest_String& a, const UnitTest_String& b);
friend int32 operator<= (const UnitTest_String& a, const UnitTest_String& b);
friend int32 operator> (const UnitTest_String& a, const UnitTest_String& b);
friend int32 operator>= (const UnitTest_String& a, const UnitTest_String& b);
~UnitTest_String();
/// Access functions for the string size
int32 get_size() const;
int32 size() const
{
return get_size();
};
/// Access function for the C-style string
const char * get_cstr() const;
const char * c_str() const
{
return get_cstr();
};
/// Append a c-style string
UnitTest_String& operator+=(const char* src);
/// Append another UnitTest_String to this UnitTest_String
UnitTest_String& operator+=(const UnitTest_String& src);
/// Append a single character
UnitTest_String& operator+=(const char c);
char operator[](int32 index) const;
};
inline const char * UnitTest_String::get_cstr() const
{
return rep->buffer;
}
inline int32 UnitTest_String::get_size() const
{
return rep->size;
}
inline int32 operator==(const UnitTest_String& a, const UnitTest_String& b)
{
return (!_strcmp(a.rep->buffer, b.rep->buffer));
}
inline int32 operator!=(const UnitTest_String& a, const UnitTest_String& b)
{
return (_strcmp(a.rep->buffer, b.rep->buffer) != 0);
}
inline int32 operator>(const UnitTest_String& a, const UnitTest_String& b)
{
return (_strcmp(a.rep->buffer, b.rep->buffer) > 0);
}
inline int32 operator>=(const UnitTest_String& a, const UnitTest_String& b)
{
return (_strcmp(a.rep->buffer, b.rep->buffer) >= 0);
}
inline int32 operator<=(const UnitTest_String& a, const UnitTest_String& b)
{
return (_strcmp(a.rep->buffer, b.rep->buffer) <= 0);
}
inline int32 operator<(const UnitTest_String& a, const UnitTest_String& b)
{
return (_strcmp(a.rep->buffer, b.rep->buffer) < 0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
inline UnitTest_String::UnitTest_String()
{
char *ptr = NULL;
rep = new Srep(0, ptr);
}
inline UnitTest_String::UnitTest_String(const char *cp)
{
if (cp)
rep = new Srep(_strlen(cp), cp);
else
rep = new Srep(0, cp);
}
inline UnitTest_String::UnitTest_String(const char *cp, uint32 length)
{
rep = new Srep(length, cp);
}
inline UnitTest_String::UnitTest_String(const UnitTest_String& src)
{
src.rep->refcnt++;
rep = src.rep;
}
inline UnitTest_String::~UnitTest_String()
{
if (--rep->refcnt == 0) delete rep;
}
inline UnitTest_String& UnitTest_String::operator=(const UnitTest_String & src)
{
if (rep == src.rep)
{
return *this; // protect against "str = str"
}
src.rep->refcnt++;
if (--rep->refcnt == 0)
{
delete rep;
}
rep = src.rep;
return *this;
}
inline UnitTest_String& UnitTest_String::operator=(const char * cp)
{
if (--rep->refcnt == 0)
{
delete rep;
}
if (cp == NULL)
{
rep = new Srep(0, cp);
}
else
{
rep = new Srep(_strlen(cp), cp);
}
return *this;
}
inline UnitTest_String& UnitTest_String::operator+=(const char * src)
{
Srep *new_rep;
int32 new_size = rep->size + _strlen(src);
new_rep = new Srep(new_size, rep->buffer);
_strcat(new_rep->buffer, src);
if (--rep->refcnt == 0)
{
delete rep;
}
rep = new_rep;
return *this;
}
inline UnitTest_String& UnitTest_String::operator+=(const UnitTest_String & src)
{
Srep *new_rep;
int32 new_size = rep->size + src.rep->size;
new_rep = new Srep(new_size, rep->buffer);
_strcat(new_rep->buffer, src.rep->buffer);
if (--rep->refcnt == 0)
{
delete rep;
}
rep = new_rep;
return *this;
}
inline UnitTest_String& UnitTest_String::operator+=(const char c)
{
char tmp_str[2];
tmp_str[0] = c;
tmp_str[1] = (char)'\0';
return ((*this) += tmp_str);
}
inline char UnitTest_String::operator[](int32 index) const
{
if (index < 0 || index >= rep->size)
return '\0';
return rep->buffer[index];
}
#endif //UNIT_TEST_LOCAL_STRING_H