仿Android 工具类String8写的
#ifndef __STRING8_H__
#define __STRING8_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <stdarg.h>
#include <stdint.h>
#include <ctype.h>
namespace Alias {
#define MAXSIZE (1024 * 8)
class String8 {
public:
String8();
String8(const String8& other);
String8(const char* other);
String8(const char* other, const size_t numChars);
String8(const std::string& other);
~String8();
const char* c_str() const;
std::string toStdString() const;
bool isEmpty() const;
size_t length() const;
void clear();
int append(const String8& other);
int append(const char* other);
int append(const char* other, size_t numChars);
static String8 format(const char* fmt, ...) __attribute__((format(printf, 1, 2)));
int appendFormat(const char* fmt, ...) __attribute__((format (printf, 2, 3)));
String8& operator=(const String8& other);
String8& operator=(const char* other);
String8& operator+=(const String8& other);
String8 operator+(const String8& other) const;
String8& operator+=(const char* other);
String8 operator+(const char* other) const;
int compare(const String8& other) const;
int compare(const char* other) const;
int StrCaseCmp(const String8& other) const;
int StrCaseCmp(const char* other) const;
bool operator<(const String8& other) const;
bool operator<=(const String8& other) const;
bool operator==(const String8& other) const;
bool operator!=(const String8& other) const;
bool operator>=(const String8& other) const;
bool operator>(const String8& other) const;
bool operator<(const char* other) const;
bool operator<=(const char* other) const;
bool operator==(const char* other) const;
bool operator!=(const char* other) const;
bool operator>=(const char* other) const;
bool operator>(const char* other) const;
size_t find(const char* other, size_t start = 0) const;
bool contains(const char* other) const;
bool removeAll(const char* other);
void toLower();
void toLower(size_t start, size_t numChars);
void toUpper();
void toUpper(size_t start, size_t numChars);
private:
char* getBuffer(size_t numChars = 0);
void release();
static String8 formatV(const char* fmt, va_list args);
int appendFormatV(const char* fmt, va_list args);
void setTo(const String8& other);
int setTo(const char* other);
int setTo(const char* other, size_t numChars);
private:
char *mString = nullptr;
};
}
#endif
#include "string8.h"
namespace Alias {
char *String8::getBuffer(size_t numChars)
{
char *ret = nullptr;
if (numChars <= 0) {
ret = (char *)malloc(1);
if (ret) {
*ret = '\0';
}
return ret;
} else if (numChars > 0) {
ret = (char *)malloc(numChars + 1);
if (ret) {
memset(ret, 0, numChars + 1);
}
return ret;
}
}
void String8::release()
{
if (mString == nullptr) {
return;
}
free(mString);
mString = nullptr;
}
String8::String8()
{
mString = getBuffer();
}
String8::String8(const String8& other)
{
if (other.length() == 0) {
mString = getBuffer();
return;
}
mString = getBuffer(other.length());
memcpy(mString, other.mString, other.length());
}
String8::String8(const char* other)
{
if (other == nullptr) {
mString = getBuffer();
return;
}
size_t length = strlen(other);
mString = getBuffer(length);
memcpy(mString, other, length);
}
String8::String8(const char* other, const size_t numChars)
{
if (other == nullptr) {
mString = getBuffer();
return;
}
size_t length = strlen(other);
if (length > numChars) {
length = numChars;
}
mString = getBuffer(length);
memcpy(mString, other, length);
}
String8::String8(const std::string& other)
{
size_t length = other.length();
mString = getBuffer(length);
memcpy(mString, other.c_str(), length);
}
String8::~String8()
{
release();
}
size_t String8::find(const char* other, size_t start) const
{
const char *tmp = strstr(mString + start, other);
return tmp ? tmp - mString : -1;
}
const char* String8::c_str() const
{
return mString;
}
std::string String8::toStdString() const
{
return std::string(mString);
}
bool String8::isEmpty() const
{
return length() == 0;
}
size_t String8::length() const
{
return strlen(mString);
}
void String8::clear()
{
memset(mString, 0, strlen(mString));
}
int String8::append(const String8& other)
{
return append(other.mString, other.length());
}
int String8::append(const char* other)
{
return append(other, strlen(other));
}
int String8::append(const char* other, size_t numChars)
{
if (other == nullptr) {
return -1;
}
size_t size = strlen(other);
if (size > numChars) {
size = numChars;
}
if (size == 0) {
return 0;
}
size_t totalSize = size + length();
char *buf = getBuffer(totalSize);
if (buf) {
memcpy(buf, mString, length());
memcpy(buf + length(), other, size);
this->release();
mString = buf;
return size;
}
return 0;
}
String8& String8::operator=(const String8& other)
{
setTo(other);
return *this;
}
String8& String8::operator=(const char* other)
{
setTo(other);
return *this;
}
String8& String8::operator+=(const String8& other)
{
this->append(other);
return *this;
}
String8 String8::operator+(const String8& other) const
{
String8 tmp(*this);
tmp += other;
return tmp;
}
String8& String8::operator+=(const char* other)
{
this->append(other);
return *this;
}
String8 String8::operator+(const char* other) const
{
String8 tmp(*this);
tmp += other;
return tmp;
}
int String8::compare(const String8& other) const
{
return strcmp(mString, other.mString);
}
int String8::compare(const char* other) const
{
return strcmp(mString, other);
}
int String8::StrCaseCmp(const String8& other) const
{
return strcasecmp(mString, other.mString);
}
int String8::StrCaseCmp(const char* other) const
{
return strcasecmp(mString, other);
}
bool String8::operator<(const String8& other) const
{
return strcmp(mString, other.mString) < 0;
}
bool String8::operator<=(const String8& other) const
{
return strcmp(mString, other.mString) <= 0;
}
bool String8::operator==(const String8& other) const
{
return strcmp(mString, other.mString) == 0;
}
bool String8::operator!=(const String8& other) const
{
return strcmp(mString, other.mString) != 0;
}
bool String8::operator>=(const String8& other) const
{
return strcmp(mString, other.mString) >= 0;
}
bool String8::operator>(const String8& other) const
{
return strcmp(mString, other.mString) > 0;
}
bool String8::operator<(const char* other) const
{
return strcmp(mString, other) < 0;
}
bool String8::operator<=(const char* other) const
{
return strcmp(mString, other) <= 0;
}
bool String8::operator==(const char* other) const
{
return strcmp(mString, other) == 0;
}
bool String8::operator!=(const char* other) const
{
return strcmp(mString, other) != 0;
}
bool String8::operator>=(const char* other) const
{
return strcmp(mString, other) >= 0;
}
bool String8::operator>(const char* other) const
{
return strcmp(mString, other) > 0;
}
void String8::setTo(const String8& other)
{
setTo(other.mString, other.length());
}
int String8::setTo(const char* other)
{
return setTo(other, strlen(other));
}
int String8::setTo(const char* other, size_t numChars)
{
if (other == nullptr) {
return -1;
}
numChars = numChars > strlen(other) ? strlen(other) : numChars;
if (strlen(mString) >= numChars) {
memset(mString, 0, strlen(mString));
memcpy(mString, other, numChars);
} else {
release();
mString = getBuffer(numChars);
memcpy(mString, other, numChars);
}
}
bool String8::contains(const char* other) const
{
return nullptr != strstr(mString, other);
}
bool String8::removeAll(const char* other)
{
size_t start = 0;
if (other && ((start = find(other)) >= 0)) {
size_t end = strlen(other) + start;
if (end >= length()) {
mString[start] = '\0';
return true;
} else {
size_t bufferSize = length() - (end - start);
char *newString = getBuffer(bufferSize);
if (newString == nullptr) {
return false;
}
memcpy(newString, mString, start);
memcpy(newString + start, mString + end, length() - end);
free(mString);
mString = newString;
return true;
}
}
return false;
}
void String8::toLower()
{
toLower(0, length());
}
void String8::toLower(size_t start, size_t numChars)
{
size_t size = length();
if (size > start) {
for (size_t i = start; i < numChars && i < size; ++i) {
mString[i] = static_cast<char>(tolower(mString[i]));
}
}
}
void String8::toUpper()
{
toUpper(0, length());
}
void String8::toUpper(size_t start, size_t numChars)
{
size_t size = length();
if (size > start) {
for (size_t i = start; i < numChars && i < size; ++i) {
mString[i] = static_cast<char>(toupper(mString[i]));
}
}
}
String8 String8::format(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
String8 result(formatV(fmt, args));
va_end(args);
return result;
}
String8 String8::formatV(const char* fmt, va_list args)
{
String8 result;
result.appendFormatV(fmt, args);
return result;
}
int String8::appendFormat(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
int numChars = appendFormatV(fmt, args);
va_end(args);
return numChars;
}
int String8::appendFormatV(const char* fmt, va_list args)
{
int n;
va_list tmp_args;
va_copy(tmp_args, args);
n = vsnprintf(nullptr, 0, fmt, tmp_args);
va_end(tmp_args);
if (n < 0) {
return n;
}
if (n > 0) {
size_t oldLength = length();
if ((size_t)n > MAXSIZE - 1 ||
oldLength > MAXSIZE - (size_t)n - 1) {
return -1;
}
char *buf = (char *)malloc(oldLength + n);
if (buf == nullptr) {
return -1;
}
memcpy(buf, mString, oldLength);
release();
vsnprintf(buf + oldLength, n + 1, fmt, args);
mString = buf;
}
return n;
}
}
测试(未测试全)
#include <iostream>
#include <stdio.h>
#include "string8.h"
int main()
{
Alias::String8 str1;
str1 = "123456789";
str1.append("abcde", 3);
std::cout << str1.c_str() << "\n";
str1.appendFormat(" %p", str1.c_str());
std::cout << "ptr = " << str1.c_str() << "\n";
str1.clear();
str1.appendFormat("[%d.%d.%d.%d]", 192, 168, 124, 7);
std::cout << str1.c_str() << "\n";
Alias::String8 str2 = str1;
str2.appendFormat(" %p", str2.c_str());
std::cout << "str2: "<< str2.c_str() << "\n";
std::cout << str2.find("168.124.7") << "\n";
std::cout << str2.contains("168.124.7") << "\n";
std::cout << str2.compare(str1) << "\n";
str2 = "ABcdEF";
str2.toLower();
std::cout << "toLower str2: "<< str2.c_str() << "\n";
Alias::String8 str3(str1);
std::cout << "str3: "<< str3.c_str() << "\n";
std::cout << (str3 == str2) << "\n";
str3 = "AbcdEF";
std::cout << str3.StrCaseCmp(str2) << "\n";
str3.toLower();
std::cout << "toLower str3: "<< str3.c_str() << "\n";
std::cout << "str3 == str2 -> " << (str3 == str2) << "\n";
str3.removeAll("abcdef");
str3 += str2;
std::cout << "str3: "<< str3.c_str() << "\n";
Alias::String8 str4 = str1 + str2 + str3;
std::cout << str4.toStdString() << std::endl;
Alias::String8 str5 = Alias::String8::format("%s", str4.c_str());
std::cout << str5.toStdString() << std::endl;
return 0;
}
