// ****************************************************************************
// InvtString.h version: 1.0 date: 12/12/2005
// ---------------------------------------------------------------------------
// Summary:
// ---------------------------------------------------------------------------
// Copyright (C) LYH_Studio @ 2005 - All Rights Reserved
// ****************************************************************************
//
// ****************************************************************************
#ifndef _LYH_STUDIO_INVTSTRING
#define _LYH_STUDIO_INVTSTRING
#include <string>
using std::string;
#include <cassert>
template<class T = char>
class InvtString : public string {
public:
//定义InvtString类的Exception类
class InvtStringException {
public:
explicit InvtStringException(const string msg) : m_msg(msg){}
virtual ~InvtStringException() {}
const string &GetErrMsg() const { return m_msg; };
private:
string m_msg;
};
InvtString() : string() {};
InvtString(const string &str) :string(str) {}
InvtString(const char *str) :string(str) {}
~InvtString() {}
/*-------------------------------------------------------------------------------*/
/*-->>The string transported to this class must have no divider in two points<<--*/
/*-------------------------------------------------------------------------------*/
/*--------------->Function @ GetSubStringNum @ discription <------------------*
**@name:int GetSubStringNum(const char ÷r); *
*@parameter:|#const char ÷r =====>>a divider which devide two sub string*
*@purpose:get the number of sub string. *
*@return value:the number of sub string * *
*-----------------------------------------------------------------------------*/
int GetSubStringNum(const char ÷r = ' ') const;
/*------------->Function @ GetSubString @ discription <-----------------------*
**@name:InvtString GetSubString(int idx); *
*@parameter:int idx *
* =====>>the index(base of one) of sub string which you to get *
*@purpose:get a specific sub string. *
*@return value:instance of sub string * *
*-----------------------------------------------------------------------------*/
InvtString GetSubString(int idx, const char ÷r = ' ') const throw(InvtStringException);
/*--------------->Function @ FindInSubString @ discription <------------------*
*@name: int FindInSubString(const string &element, const T ÷r = T()); *
*@parameter:(1)const string &element *
* =====>>the string contain some elements which you to find *
* (2)const T ÷r = T() ======>>The divider between sub string *
* *@purpose:find element number in sub strings *
* *@return value: int * *
*-----------------------------------------------------------------------------*/
int FindInSubString(const string &element, const char ÷r = ' ') const ;
/*--------------->Function @ IsSubCharSet @ discription <---------------------*
*@name:# bool IsSubCharSet(const string &superCharSet) const; *
*# bool IsSubCharSet(const char *superCharSet) const; *
*@parameter:const string &superCharSet =====>>super char set *
*@purpose:distinguish whether this char set is a sub set of superStr *
*@return value:bool *
*-----------------------------------------------------------------------------*/
bool IsSubCharSet(const string &superCharSet) const;
bool IsSubCharSet(const char *superCharSet) const;
/*---------------->Function @ IsSuperCharSet @ discription <------------------*
**@name:# bool IsSuperCharSet(const string &subCharSet) const; *
*# bool IsSuperString(const char *subCharSet) const; *
*@parameter:const char *subCharSet *
*@purpose:distinguish whether this string contain all charaters in subCharSet *
*@return value:bool *
*-----------------------------------------------------------------------------*/
bool IsSuperCharSet(const string &subCharSet) const;
bool IsSuperCharSet(const char *subCharSet) const;
/*------------------->Function @ operator+ @ discription <--------------------*
**@name:# stringEx operator+ (unsigned int number); *
*@parameter:unsigned int number *
*@purpose:add a string version of number in this string *
*@return value:stringEx& *
*-----------------------------------------------------------------------------*/
InvtString<T> &operator+ (unsigned int number);
/*--------------->Function @ ConvertSubStrToUINT @ discription <--------------*
**@name:# unsigned int ConvertSubStrToUINT(const unsigned int index, *
const char ÷r) const throw(InvtStringException; *
*@parameter:unsigned int index, const char ÷r *
*@purpose:convert sub string indicated by index(base on zero) to unsigned int *
*@return value:stringEx& *
*-----------------------------------------------------------------------------*/
unsigned int ConvertSubStrToUINT(const unsigned int index, const char ÷r)
const throw(InvtStringException);
/*------------------->Function @ replace @ discription <----------------------*
**@name:void replace(unsigned int index, InvtString<T> rstr, *
const char ÷r) throw(InvtStringException); *
*@parameter:unsigned int index, InvtString<T> rstr, const char ÷r *
*@purpose:replace the specify sub string with new string *
*@return value:void *
*-----------------------------------------------------------------------------*/
void replace(unsigned int index, InvtString<T> rstr, const char ÷r)
throw(InvtStringException);
/*------------------>Function @ Sort @ discription <--------------------------*
**@name:void Sort(const T &compositor, const char divider = T()); *
*@parameter:(1) const U &compositor =====>>a function's address *
* or something similar to function which can compare two object *
* and return boolean type as its type. *
* *
* (2) const T divider =====>>a divider which devide two sub string*
* *@purpose:Sort the sub string in this string *
* *@return value: void * *
*-----------------------------------------------------------------------------*/
template <class U>
void Sort(const U &compositor, const char ÷r = ' ') {
int len = length();
bool work = false;
char chTempChar;
char *tempStr = new char[len];
copy(tempStr, len);
for (int index = 0 , i; index < len; index = i + 1) {
for (i = index; tempStr[i] != divider; i++) {
for (int j = index; tempStr[j+1+i-index] != divider; j++) {
if (compositor(tempStr[j], tempStr[j+1])) {
chTempChar = tempStr[j];
tempStr[j] = tempStr[j+1];
tempStr[j+1] = chTempChar;
work = true;
}
}
if (!work) {
goto l1;
}
}
}
assign(tempStr);
l1: delete[] tempStr;
}
};
//特化InvtString类
typedef InvtString<char> stringEx;
template <class T>
int InvtString<T>::GetSubStringNum(const char ÷r /*= ' '*/) const {
int subNum = 1;
string::size_type index = 0; //搜索的Item的下标
while ((index = find(divider,index)) != string::npos) {
index ++;
subNum ++;
}
return subNum;
}
template <class T>
int InvtString<T>::FindInSubString(const string &element, const char ÷r) const {
int number = 0;
string::size_type index = 0, head = 0, tail = 0;
string::size_type temp; //暂时储存find的结果(即所找到的字符串下标)
while ((head = tail) != length()) {
tail = find(divider, head + 1); //确定子串的尾下标
if (tail == string::npos) {
tail = length();
}
while (((temp = find(element[index], head)) < tail && temp != string::npos)
&& index < element.length() ) {
index++;
}
if (index == element.length()) {
number++;
}
index = 0; //复位
}
return number;
}
template <class T>
InvtString<T> InvtString<T>::GetSubString(int idx, const char ÷r/*=' '*/) const throw(InvtString::InvtStringException) {
assert(idx > 0 && length() > 0);
string::size_type head = 0, tail = 0;
while ((tail = find(divider,head)) != string::npos) {
idx--;
if (idx == 0) {
break;
}
else {
head = tail + 1;
}
}
//如果是因为find函数返回string::npos值而结束循环。这种情况下idx的值不可能大于等于二
if (tail == string::npos) {
if (idx == 1) {
tail = length(); //把字符串的值赋给tail。
}
else {
//必定要有一个选项参数(选项字符串)
throw InvtStringException(errMsg[ERR_MSG_WANTING_PARAMETER]);
}
}
return substr(head, tail - head);
}
template <class T>
bool InvtString<T>::IsSubCharSet(const string &superCharSet) const {
int len = length();
int superLen = superCharSet.length();
//如果本字串是空串,则返回false值。因为这里认为空串不是字串的子串。
//当然,如果superCharSet本身就是空串的话就;应该毫不犹豫的返回false。
if (superLen == 0 && len == 0) {
return false;
}
for (int i = 0; i < len; i++) {
if (superCharSet.find(at(i)) == string::npos) {
return false;
}
}
return true;
}
template <class T>
bool InvtString<T>::IsSubCharSet(const char *superCharSet) const {
int len = length();
int superLen = strlen(superCharSet);
//如果本字串是空串,则返回false值。因为这里认为空串不是字串的子串。
//当然,如果superCharSet本身就是空串的话就;应该毫不犹豫的返回false。
if (superLen == 0 && len == 0) {
return false;
}
for (int i = 0; i < len; i++) {
if (strstr(superCharSet,c_str()) == NULL) {
return false;
}
}
return true;
}
template <class T>
bool InvtString<T>::IsSuperCharSet(const string &subCharSet) const {
int len = length();
int subLen = subCharSet.length();
//如果本字串是空串,则返回false值。因为这里认为空串不是字串的子串。
//当然,如果superStr本身就是空串的话就;应该毫不犹豫的返回false。
if (subLen == 0 && len == 0) {
return false;
}
for (int i = 0; i < subLen; i++) {
if (find(subCharSet[i]) == string::npos) {
return false;
}
}
return true;
}
template <class T>
bool InvtString<T>::IsSuperCharSet(const char *subCharSet) const {
int len = length();
int subLen = strlen(subCharSet);
//如果本字串是空串,则返回false值。因为这里认为空串不是字串的子串。
//当然,如果superStr本身就是空串的话就;应该毫不犹豫的返回false。
if (subLen == 0 && len == 0) {
return false;
}
for (int i = 0; i < subLen; i++) {
if (find(subCharSet[i]) == string::npos) {
return false;
}
}
return true;
}
template<class T>
InvtString<T> &InvtString<T>::operator+ (unsigned int number) {
InvtString<T> temp;
int mul = 10;
while ((number * 10 / mul) > 0) {
temp += static_cast<char>((number % mul) * 10 / mul + '0');
mul *= 10;
}
string::reverse_iterator pos = temp.rbegin();
string::reverse_iterator epos = temp.rend();
while (pos != epos) {
(*this) += *pos;
++pos;
}
return *this;
}
template <class T>
unsigned int InvtString<T>::ConvertSubStrToUINT(const unsigned int index, const char ÷r) const throw(InvtStringException) {
InvtString<char> temp(GetSubString(index, divider));
string::reverse_iterator pos = temp.rbegin();
string::reverse_iterator epos = temp.rend();
unsigned int number = 0;
unsigned int times = 1;
while (pos != epos) {
if (*pos < '0' || *pos > '9') {
throw InvtStringException(errMsg[ERR_MSG_WANTING_NUMBER]);
}
number += times * static_cast<unsigned int>(*pos - '0');
times *= 10;
++pos;
}
return number;
}
template <class T>
void InvtString<T>::replace(unsigned int index, InvtString<T> rstr, const char ÷r) throw(InvtString<T>::InvtStringException) {
assert(index > 0 && length() > 0);
string::size_type head = 0, tail = 0;
while ((tail = find(divider,head)) != string::npos) {
index--;
if (index == 0) {
break;
}
else {
head = tail + 1;
}
}
//如果是因为find函数返回string::npos值而结束循环。这种情况下idx的值不可能大于等于二
if (tail == string::npos) {
if (index == 1) {
tail = length(); //把字符串的值赋给tail。
}
else {
//必定要有一个选项参数(选项字符串)
throw InvtStringException(errMsg[ERR_MSG_OUTOF_RANGE]);
}
}
erase(head, tail - head);
insert(head, rstr);
}
#endif