1 #ifndef __GSTRING_SMART_STRING_CLASS__ 2 #define __GSTRING_SMART_STRING_CLASS__ 1 3 4 // This is just a streamlined version of std::string. 5 // It cleans itself up automatically, it can copy itself, 6 // test for equality, etc. 7 // and you can use .c_str() to get the string const, so it's 8 // sytactically the same (usage-wise) as std::string. 9 // Written by Ryan Geiss. 10 11 #include <windows.h> 12 13 class GString 14 { 15 public: GString()16 GString() 17 { 18 m_data = new wchar_t[1]; 19 m_data[0] = 0; 20 m_size = 1; 21 } 22 GString(const wchar_t * src)23 GString(const wchar_t* src) 24 { 25 m_data = NULL; 26 m_size = 0; 27 operator=(src); 28 } 29 GString(const GString & src_string)30 GString(const GString &src_string) 31 { 32 m_data = NULL; 33 m_size = 0; 34 operator=(src_string); 35 } 36 ~GString()37 ~GString() 38 { 39 delete m_data; // note: delete is safe on NULL ptrs 40 m_data = NULL; 41 m_size = 0; 42 } 43 44 inline GString& operator=(const wchar_t* src) 45 { 46 if (src != m_data) // don't do anything on "x = x.c_str();" 47 { 48 delete m_data; // note: delete is safe on NULL ptrs 49 if (src) 50 { 51 m_size = wcslen(src)+1; 52 m_data = new wchar_t[m_size]; 53 memcpy(m_data, src, m_size*2); 54 } 55 else 56 { 57 m_size = 1; 58 m_data = new wchar_t[1]; 59 m_data[0] = 0; 60 } 61 } 62 return *this; 63 } 64 65 inline GString& operator=(const GString &src_string) 66 { 67 if (&src_string != this) // don't do anything on "x = x;" 68 { 69 if (src_string.GetSize() != m_size) //optimization 70 { 71 delete m_data; 72 m_size = src_string.GetSize(); 73 m_data = new wchar_t[m_size]; 74 } 75 memcpy(m_data, src_string.c_str(), m_size*2); 76 } 77 return *this; 78 } 79 80 inline wchar_t operator[](int index) const 81 { 82 return m_data[index]; 83 } 84 85 inline bool operator==(const wchar_t* comp) 86 { 87 return (wcscmp(m_data,comp) == 0); 88 } 89 90 inline bool operator==(const GString &comp) 91 { 92 if (m_size != comp.m_size) // shortcut 93 return false; 94 return (wcscmp(m_data,comp.c_str()) == 0); //return operator==(comp.m_data); 95 } 96 c_str()97 inline const wchar_t* c_str() const 98 { 99 return m_data; 100 } 101 102 // This is actually unsafe, but we need it for convenience, unless we really 103 // feel like copying all data twice. BE WARNED! When this class reallocates 104 // memory, all old references to _data are invalid! 105 //operator const char*() const { return _data; } GetSize()106 inline int GetSize() const //in bytes - including terminating NULL char. 107 { 108 return m_size; 109 } 110 GetLength()111 inline int GetLength() const 112 { 113 return (m_size >= 1) ? m_size-1 : 0; 114 } 115 116 private: 117 wchar_t* m_data; 118 int m_size; 119 }; 120 121 class GStringA 122 { 123 public: GStringA()124 GStringA() 125 { 126 m_data = new char[1]; 127 m_data[0] = 0; 128 m_size = 1; 129 } 130 GStringA(const char * src)131 GStringA(const char* src) 132 { 133 m_data = NULL; 134 m_size = 0; 135 operator=(src); 136 } 137 GStringA(const GStringA & src_string)138 GStringA(const GStringA &src_string) 139 { 140 m_data = NULL; 141 m_size = 0; 142 operator=(src_string); 143 } 144 ~GStringA()145 ~GStringA() 146 { 147 delete m_data; // note: delete is safe on NULL ptrs 148 m_data = NULL; 149 m_size = 0; 150 } 151 152 inline GStringA& operator=(const char* src) 153 { 154 if (src != m_data) // don't do anything on "x = x.c_str();" 155 { 156 delete m_data; // note: delete is safe on NULL ptrs 157 if (src) 158 { 159 m_size = strlen(src)+1; 160 m_data = new char[m_size]; 161 memcpy(m_data, src, m_size); 162 } 163 else 164 { 165 m_size = 1; 166 m_data = new char[1]; 167 m_data[0] = 0; 168 } 169 } 170 return *this; 171 } 172 173 inline GStringA& operator=(const GStringA &src_string) 174 { 175 if (&src_string != this) // don't do anything on "x = x;" 176 { 177 if (src_string.GetSize() != m_size) //optimization 178 { 179 delete m_data; 180 m_size = src_string.GetSize(); 181 m_data = new char[m_size]; 182 } 183 memcpy(m_data, src_string.c_str(), m_size); 184 } 185 return *this; 186 } 187 188 inline char operator[](int index) const 189 { 190 return m_data[index]; 191 } 192 193 inline bool operator==(const char* comp) 194 { 195 return (strcmp(m_data,comp) == 0); 196 } 197 198 inline bool operator==(const GStringA &comp) 199 { 200 if (m_size != comp.m_size) // shortcut 201 return false; 202 return (strcmp(m_data,comp.c_str()) == 0); //return operator==(comp.m_data); 203 } 204 c_str()205 inline const char* c_str() const 206 { 207 return m_data; 208 } 209 210 // This is actually unsafe, but we need it for convenience, unless we really 211 // feel like copying all data twice. BE WARNED! When this class reallocates 212 // memory, all old references to _data are invalid! 213 //operator const char*() const { return _data; } GetSize()214 inline int GetSize() const //in bytes - including terminating NULL char. 215 { 216 return m_size; 217 } 218 GetLength()219 inline int GetLength() const 220 { 221 return (m_size >= 1) ? m_size-1 : 0; 222 } 223 224 private: 225 char* m_data; 226 int m_size; 227 }; 228 229 #endif