透明的String类是一个能自己定义长度的类,类中重载了很多操作符,还增加了其它的字符格式化功能,操作起来和c++内库的string基本一样。这个String类提供了拷贝栈中的数据,没有什么其它的引用,在多线程处理消息队列的时安全性好。
template< uint32_t _size = 32 >
class String
{
public:
String();
String(const String &str);
String(const char *str);
String(const std::string &str);
public:
const char *data() const;
const char *c_str() const;
std::string getStr() const;
uint32_t size() const;
uint32_t length() const;
uint32_t usableSize() const;
bool full() const;
bool empty() const;
void format(const char *format, ...);
void appendFormat(const char *format, ...);
String &append(char ch);
String &append(const char *str);
String &append(const char *str, uint32_t len);
String &append(const String &str);
String &append(const std::string &str);
public:
operator std::string() const;
String &operator = (char ch);
String &operator = (const char *str);
String &operator = (const String &str);
String &operator = (const std::string &str);
String &operator += (char ch);
String &operator += (const char *str);
String &operator += (const String &str);
String &operator += (const std::string &str);
bool operator == (const char *str) const;
bool operator == (const String &str) const;
bool operator == (const std::string &str) const;
bool operator != (const char *str) const;
bool operator != (const String &str) const;
bool operator != (const std::string &str) const;
bool operator < (const String &str) const;
bool operator > (const String &str) const;
char operator [] (int index) const;
private:
void clear()
{
_length = 0;
_buffer[ _length ] = '\0';
};
private:
uint32_t _length;
char _buffer[_size];
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template< uint32_t _size>
String<_size>::String()
{
clear();
}
template< uint32_t _size>
String<_size>::String(const String &str)
{
_length = _size < str.size() ? _size - 1 : str.length();
memcpy(_buffer , str.c_str() , _length);
_buffer[_length] = '\0';
}
template< uint32_t _size>
String<_size>::String(const char *str)
{
uint32_t len = (uint32_t)strlen(str);
_length = len < _size ? len : _size - 1;
memcpy(_buffer , str, _length);
_buffer[_length] = '\0';
}
template< uint32_t _size>
String<_size>::String(const std::string &str)
{
uint32_t len = (uint32_t)strlen( str.c_str() );
_length = len < _size ? len : _size - 1;
memcpy(_buffer , str.c_str(), _length);
_buffer[_length] = '\0';
}
template< uint32_t _size>
const char * String<_size>::data() const
{
return _buffer;
}
template< uint32_t _size>
const char * String<_size>::c_str() const
{
return _buffer;
}
template< uint32_t _size>
std::string String<_size>::getStr() const
{
return string(_buffer );
}
template< uint32_t _size>
uint32_t String<_size>::size() const
{
return _length + 1;
}
template< uint32_t _size>
uint32_t String<_size>::length() const
{
return _length;
}
template<uint32_t _size>
uint32_t String<_size>::usableSize() const
{
return _size - _length - 1;
}
template<uint32_t _size>
bool String<_size>::full() const
{
return _length < _size - 1 ? false : true;
}
template<uint32_t _size>
bool String<_size>::empty() const
{
return _length != 0 ? false : true;
}
template<uint32_t _size>
void String<_size>::format(const char *format, ...)
{
va_list list;
va_start(list, format);
int len = _vsnprintf(_buffer, _size, format, list);
if( len < 0)
{
_length = 0;
}
else
{
_length = (uint32_t)len;
}
_buffer[_length] = '\0';
va_end(list);
}
template<uint32_t _size>
void String<_size>::appendFormat(const char *format, ...)
{
va_list list;
va_start(list, format);
int len = _vsnprintf(_buffer + _length, _size - _length, format, list);
if( len < 0)
{
_length = 0;
}
else
{
_length += (uint32_t)len;
}
_buffer[_length] = '\0';
va_end(list);
}
template<uint32_t _size>
String<_size>& String<_size>::append(char ch)
{
if( _length < _size - 1)
{
memcpy(_buffer + _length , &ch , 1);
++_length;
_buffer[_length] = '\0';
}
return *this;
}
template<uint32_t _size>
String<_size>& String<_size>::append(const char *str)
{
return append(str, strlen(str) );
}
template <uint32_t _size>
String<_size>& String<_size>::append(const char *str, uint32_t len)
{
uint32_t lenAll = (uint32_t)strlen(str);
len = lenAll < len ? lenAll : len;
if( _length + len < _size - 1)
{
memcpy(_buffer + _length , str , len);
_length += len;
}
else
{
memcpy(_buffer + _length , str , _size - 1 - _length);
_length = _size - 1;
}
_buffer[_length] = '\0';
return *this;
}
template <uint32_t _size>
String<_size>& String<_size>::append(const String &str)
{
return append( str.c_str() , str.length() );
}
template <uint32_t _size>
String<_size>& String<_size>::append(const std::string &str)
{
return append( str.c_str() , str.length() );
}
template <uint32_t _size>
String<_size>::operator std::string() const
{
return std::string(_buffer);
}
template <uint32_t _size>
String<_size>& String<_size>::operator = (char ch)
{
clear();
return append(&ch, 1);
}
template <uint32_t _size>
String<_size>& String<_size>::operator = (const char *str)
{
clear();
return append(str, strlen(str) );
}
template <uint32_t _size>
String<_size>& String<_size>::operator = (const String &str)
{
clear();
return append(str.c_str(), str.length() );
}
template <uint32_t _size>
String<_size>& String<_size>::operator = (const std::string &str)
{
clear();
return append(str.c_str(), str.length() );
}
template <uint32_t _size>
String<_size>& String<_size>::operator += (char ch)
{
return append(&ch, 1);
}
template <uint32_t _size>
String<_size>& String<_size>::operator += (const char *str)
{
return append(str, strlen(str) );
}
template <uint32_t _size>
String<_size>& String<_size>::operator += (const String &str)
{
return append(str.c_str(), str.length() );
}
template <uint32_t _size>
String<_size>& String<_size>::operator += (const std::string &str)
{
return append(str.c_str(), str.length() );
}
template <uint32_t _size>
bool String<_size>::operator == (const char *str) const
{
uint32_t len = (uint32_t)strlen(str);
if( len != _length )
{
return false;
}
for(uint32_t i = 0 ; i < _size && i < len ; i++)
{
if( _buffer[i] != str[i] )
{
return false;
}
}
return true;
}
template<uint32_t _size>
bool String<_size>::operator == (const String &str) const
{
return *this == str.c_str();
}
template<uint32_t _size>
bool String<_size>::operator == (const std::string &str) const
{
return *this == str.c_str();
}
template <uint32_t _size>
bool String<_size>::operator != (const char *str) const
{
return *this == str ? false : true;
}
template<uint32_t _size>
bool String<_size>::operator != (const String &str) const
{
return *this == str.c_str() ? false : true;
}
template<uint32_t _size>
bool String<_size>::operator != (const std::string &str) const
{
return *this == str.c_str() ? false : true;
}
template<uint32_t _size>
char String<_size>::operator [] (int index) const
{
return index < _length ? _buffer[index] : '\0';
}