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