
#ifndef __CSTRING_H__
#define __CSTRING_H__

#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include "exception.h"

class CStrArray;

class V2_CLASS_API CString 
{
private:
	char *m_szData;
	int m_iSize;
	int m_iBufferSize;

	void MakeEmptyString();
	void ConcatInPlace(const char *aszSrc);

public:
	CString();
	CString(const char *aszData);
	CString(const CString &auValue);
	~CString();

	void Clear();
	int Format(const char *szFormat, ...);
	int Set(const char *aszData);
	int Set(const CString &auValue);
	int GetLength() const;
	int GetSize() const;
	void Empty();
	int IsEmpty() const;
	void SetNull() { Empty(); }
	bool IsValid() const { return (IsEmpty()) ? false : true; }
	char *ToStr() const;
	int ToInt() const;
	double ToDbl() const;

	int Compare(const char *aszValue) const;
	int CompareNoCase(const char *aszValue) const;

	char *GetBuffer(int aiLen);
	void ReleaseBuffer(int aiLen = -1);

	void MakeLower();
	void MakeUpper();

	CString Left(int aiCount) const;
	CString Mid(int aiFirst, int aiCount = -1) const;
	CString Right(int aiCount) const;

	void TrimLeft();
	void TrimLeft(char ch);
	void TrimLeft(const char *aszCmp);
	void TrimRight();
	void TrimRight(char ch);
	void TrimRight(const char * aszCmp);
	void Trim();
	void Trim(char ch);
	void Trim(const char *aszCmp);

	int Replace(char achOld, char achNew);
	int Replace(const char *aszOld, const char *aszNew);
	int Insert(int aiIndex, char ach);
	int Insert(int aiIndex, const char *aszSrc);

	int Delete(int aiIndex, int aiCount = 1);
	int Remove(char ach);

	int Find(char ach, int aiPos = 0) const;
	int Find(const char *aszSub, int aiPos = 0) const;
	int ReverseFind(char ach) const;
	int FindOneOf(char *aszCharSet) const;

	void Split(char ach, CStrArray *p_saArr, bool p_bTrim = true) const;
	void Split(const char *p_seps, CStrArray *p_pArr, bool p_bTrim = true) const;
	CString Repr() const;

	bool StartsWith(const char *aszStr) const;
	bool EndsWith(const char *aszStr) const;

	char operator[](int aiIndex) const;
	operator char*() const { return ToStr(); }
	operator const char *() const { return ToStr(); }
	CString &operator=(const CString &auValue);
	CString &operator=(const char *aszValue);
	CString &operator+=(const CString &auValue);
	CString &operator+=(const char *aszValue);
	CString operator+(const CString &auValue);
	CString operator+(const char *aszValue);

	friend CString operator+(const char *aszValue, const CString &auValue);
	friend bool operator==(const CString &s1, const CString &s2);
	friend bool operator==(const CString &s1, const char *s2);
	friend bool operator==(const char *s1, const CString &s2);
	
	friend bool operator!=(const CString &s1, const CString &s2);
	friend bool operator!=(const CString &s1, const char *s2);
	friend bool operator!=(const char *s1, const CString &s2);
	
	friend bool operator>(const CString &s1, const CString &s2);
	friend bool operator>(const CString &s1, const char *s2);
	friend bool operator>(const char *s1, const CString &s2);
	
	friend bool operator<(const CString &s1, const CString &s2);
	friend bool operator<(const CString &s1, const char *s2);
	friend bool operator<(const char *s1, const CString &s2);
	
	friend bool operator>=(const CString &s1, const CString &s2);
	friend bool operator>=(const CString &s1, const char *s2);
	friend bool operator>=(const char *s1, const CString &s2);
	
	friend bool operator<=(const CString &s1, const CString &s2);
	friend bool operator<=(const CString &s1, const char *s2);
	friend bool operator<=(const char *s1, const CString &s2);
};

extern V2_CLASS_API CString CFormat(const char *szFormat, ...);

typedef CString CStr;

#endif // __CSTRING_H__
