2006-02-24 04:48:15 +00:00
|
|
|
#ifndef ZSTRING_H
|
|
|
|
#define ZSTRING_H
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "tarray.h"
|
|
|
|
|
|
|
|
//#define NOPOOLS
|
2006-05-03 22:45:01 +00:00
|
|
|
class FString
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
public:
|
2006-05-03 22:45:01 +00:00
|
|
|
FString () : Chars(NULL) {}
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// Copy constructors
|
2006-05-03 22:45:01 +00:00
|
|
|
FString (const FString &other) { Chars = NULL; *this = other; }
|
|
|
|
FString (const char *copyStr);
|
|
|
|
FString (const char *copyStr, size_t copyLen);
|
|
|
|
FString (char oneChar);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
// Concatenation constructors
|
2006-05-03 22:45:01 +00:00
|
|
|
FString (const FString &head, const FString &tail);
|
|
|
|
FString (const FString &head, const char *tail);
|
|
|
|
FString (const FString &head, char tail);
|
|
|
|
FString (const char *head, const FString &tail);
|
|
|
|
FString (const char *head, const char *tail);
|
|
|
|
FString (char head, const FString &tail);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
~FString ();
|
|
|
|
|
|
|
|
operator char *() { return Chars; }
|
|
|
|
operator const char *() const { return Chars; }
|
2006-02-24 04:48:15 +00:00
|
|
|
|
|
|
|
char *GetChars() const { return Chars; }
|
|
|
|
char &operator[] (int index) { return Chars[index]; }
|
2006-04-09 19:34:35 +00:00
|
|
|
char &operator[] (size_t index) { return Chars[index]; }
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
FString &operator = (const FString &other);
|
|
|
|
FString &operator = (const char *copyStr);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
FString operator + (const FString &tail) const;
|
|
|
|
FString operator + (const char *tail) const;
|
|
|
|
FString operator + (char tail) const;
|
|
|
|
friend FString operator + (const char *head, const FString &tail);
|
|
|
|
friend FString operator + (char head, const FString &tail);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
FString &operator += (const FString &tail);
|
|
|
|
FString &operator += (const char *tail);
|
|
|
|
FString &operator += (char tail);
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
FString Left (size_t numChars) const;
|
|
|
|
FString Right (size_t numChars) const;
|
|
|
|
FString Mid (size_t pos, size_t numChars) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
long IndexOf (const FString &substr, long startIndex=0) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
long IndexOf (const char *substr, long startIndex=0) const;
|
|
|
|
long IndexOf (char subchar, long startIndex=0) const;
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
long IndexOfAny (const FString &charset, long startIndex=0) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
long IndexOfAny (const char *charset, long startIndex=0) const;
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
long LastIndexOf (const FString &substr) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
long LastIndexOf (const char *substr) const;
|
|
|
|
long LastIndexOf (char subchar) const;
|
2006-05-03 22:45:01 +00:00
|
|
|
long LastIndexOf (const FString &substr, long endIndex) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
long LastIndexOf (const char *substr, long endIndex) const;
|
|
|
|
long LastIndexOf (char subchar, long endIndex) const;
|
|
|
|
long LastIndexOf (const char *substr, long endIndex, size_t substrlen) const;
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
long LastIndexOfAny (const FString &charset) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
long LastIndexOfAny (const char *charset) const;
|
2006-05-03 22:45:01 +00:00
|
|
|
long LastIndexOfAny (const FString &charset, long endIndex) const;
|
2006-02-24 04:48:15 +00:00
|
|
|
long LastIndexOfAny (const char *charset, long endIndex) const;
|
|
|
|
|
|
|
|
void ToUpper ();
|
|
|
|
void ToLower ();
|
|
|
|
void SwapCase ();
|
|
|
|
|
|
|
|
void StripLeft ();
|
2006-05-03 22:45:01 +00:00
|
|
|
void StripLeft (const FString &charset);
|
2006-02-24 04:48:15 +00:00
|
|
|
void StripLeft (const char *charset);
|
|
|
|
|
|
|
|
void StripRight ();
|
2006-05-03 22:45:01 +00:00
|
|
|
void StripRight (const FString &charset);
|
2006-02-24 04:48:15 +00:00
|
|
|
void StripRight (const char *charset);
|
|
|
|
|
|
|
|
void StripLeftRight ();
|
2006-05-03 22:45:01 +00:00
|
|
|
void StripLeftRight (const FString &charset);
|
2006-02-24 04:48:15 +00:00
|
|
|
void StripLeftRight (const char *charset);
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
void Insert (size_t index, const FString &instr);
|
2006-02-24 04:48:15 +00:00
|
|
|
void Insert (size_t index, const char *instr);
|
|
|
|
void Insert (size_t index, const char *instr, size_t instrlen);
|
|
|
|
|
|
|
|
void ReplaceChars (char oldchar, char newchar);
|
|
|
|
void ReplaceChars (const char *oldcharset, char newchar);
|
|
|
|
|
|
|
|
void StripChars (char killchar);
|
|
|
|
void StripChars (const char *killchars);
|
|
|
|
|
|
|
|
void MergeChars (char merger);
|
|
|
|
void MergeChars (char merger, char newchar);
|
|
|
|
void MergeChars (const char *charset, char newchar);
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
void Substitute (const FString &oldstr, const FString &newstr);
|
|
|
|
void Substitute (const char *oldstr, const FString &newstr);
|
|
|
|
void Substitute (const FString &oldstr, const char *newstr);
|
2006-02-24 04:48:15 +00:00
|
|
|
void Substitute (const char *oldstr, const char *newstr);
|
|
|
|
void Substitute (const char *oldstr, const char *newstr, size_t oldstrlen, size_t newstrlen);
|
|
|
|
|
|
|
|
void Format (const char *fmt, ...);
|
|
|
|
void VFormat (const char *fmt, va_list arglist);
|
|
|
|
|
|
|
|
bool IsInt () const;
|
|
|
|
bool IsFloat () const;
|
|
|
|
long ToLong (int base=0) const;
|
|
|
|
unsigned long ToULong (int base=0) const;
|
|
|
|
double ToDouble () const;
|
|
|
|
|
|
|
|
size_t Len() const { return Chars == NULL ? 0 : ((StringHeader *)(Chars - sizeof(StringHeader)))->Len; }
|
|
|
|
bool IsEmpty() const { return Len() == 0; }
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
void Resize (long newlen);
|
|
|
|
|
|
|
|
int Compare (const FString &other) const { return strcmp (Chars, other.Chars); }
|
2006-02-24 04:48:15 +00:00
|
|
|
int Compare (const char *other) const { return strcmp (Chars, other); }
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
int CompareNoCase (const FString &other) const { return stricmp (Chars, other.Chars); }
|
2006-02-24 04:48:15 +00:00
|
|
|
int CompareNoCase (const char *other) const { return stricmp (Chars, other); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
struct StringHeader
|
|
|
|
{
|
|
|
|
#ifndef NOPOOLS
|
2006-05-03 22:45:01 +00:00
|
|
|
FString *Owner; // FString this char array belongs to
|
2006-02-24 04:48:15 +00:00
|
|
|
#endif
|
2006-05-03 22:45:01 +00:00
|
|
|
size_t Len; // Length of FString, excluding terminating null
|
2006-02-24 04:48:15 +00:00
|
|
|
};
|
|
|
|
struct Pool;
|
|
|
|
struct PoolGroup
|
|
|
|
{
|
|
|
|
#ifndef NOPOOLS
|
|
|
|
~PoolGroup ();
|
|
|
|
Pool *Pools;
|
|
|
|
Pool *FindPool (char *chars) const;
|
|
|
|
static StringHeader *GetHeader (char *chars);
|
|
|
|
#endif
|
2006-05-03 22:45:01 +00:00
|
|
|
char *Alloc (FString *owner, size_t len);
|
|
|
|
char *Realloc (FString *owner, char *chars, size_t newlen);
|
2006-02-24 04:48:15 +00:00
|
|
|
void Free (char *chars);
|
|
|
|
};
|
|
|
|
|
2006-05-03 22:45:01 +00:00
|
|
|
FString (size_t len);
|
2006-02-24 04:48:15 +00:00
|
|
|
StringHeader *GetHeader () const;
|
|
|
|
|
|
|
|
static int FormatHelper (void *data, const char *str, int len);
|
|
|
|
static void StrCopy (char *to, const char *from, size_t len);
|
2006-05-03 22:45:01 +00:00
|
|
|
static void StrCopy (char *to, const FString &from);
|
2006-02-24 04:48:15 +00:00
|
|
|
static PoolGroup Pond;
|
|
|
|
|
|
|
|
char *Chars;
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
2006-05-03 22:45:01 +00:00
|
|
|
template<> friend void CopyForTArray<FString> (FString &dst, FString &src)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
// When a TArray is resized, we just need to update the Owner, because
|
|
|
|
// the old copy is going to go away very soon. No need to call the
|
|
|
|
// destructor, either, because full ownership is transferred to the
|
2006-05-03 22:45:01 +00:00
|
|
|
// new FString.
|
2006-02-24 04:48:15 +00:00
|
|
|
char *chars = src.Chars;
|
|
|
|
dst.Chars = chars;
|
|
|
|
if (chars != NULL)
|
|
|
|
{
|
2006-05-03 22:45:01 +00:00
|
|
|
((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
2006-05-03 22:45:01 +00:00
|
|
|
template<class FString> friend inline void CopyForTArray (FString &dst, FString &src);
|
2006-02-24 04:48:15 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
private:
|
2006-05-03 22:45:01 +00:00
|
|
|
void *operator new (size_t size, FString *addr)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
return addr;
|
|
|
|
}
|
2006-05-03 22:45:01 +00:00
|
|
|
void operator delete (void *, FString *)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
2006-05-03 22:45:01 +00:00
|
|
|
template<> inline void CopyForTArray<FString> (FString &dst, FString &src)
|
2006-02-24 04:48:15 +00:00
|
|
|
{
|
|
|
|
// When a TArray is resized, we just need to update the Owner, because
|
|
|
|
// the old copy is going to go away very soon. No need to call the
|
|
|
|
// destructor, either, because full ownership is transferred to the
|
2006-05-03 22:45:01 +00:00
|
|
|
// new FString.
|
2006-02-24 04:48:15 +00:00
|
|
|
char *chars = src.Chars;
|
|
|
|
dst.Chars = chars;
|
|
|
|
if (chars != NULL)
|
|
|
|
{
|
2006-05-03 22:45:01 +00:00
|
|
|
((FString::StringHeader *)(chars - sizeof(FString::StringHeader)))->Owner = &dst;
|
2006-02-24 04:48:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace StringFormat
|
|
|
|
{
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
// Format specification flags
|
|
|
|
F_MINUS = 1,
|
|
|
|
F_PLUS = 2,
|
|
|
|
F_ZERO = 4,
|
|
|
|
F_BLANK = 8,
|
|
|
|
F_HASH = 16,
|
|
|
|
|
|
|
|
F_SIGNED = 32,
|
|
|
|
F_NEGATIVE = 64,
|
|
|
|
F_ZEROVALUE = 128,
|
|
|
|
|
|
|
|
// Format specification size prefixes
|
|
|
|
F_HALFHALF = 0x1000, // hh
|
|
|
|
F_HALF = 0x2000, // h
|
|
|
|
F_LONG = 0x3000, // l
|
|
|
|
F_LONGLONG = 0x4000, // ll or I64
|
|
|
|
F_BIGI = 0x5000 // I
|
|
|
|
};
|
|
|
|
typedef int (*OutputFunc)(void *data, const char *str, int len);
|
|
|
|
|
|
|
|
int VWorker (OutputFunc output, void *outputData, const char *fmt, va_list arglist);
|
|
|
|
int Worker (OutputFunc output, void *outputData, const char *fmt, ...);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|