2 Copyright (c) 2001, Loki software, inc.
\r
5 Redistribution and use in source and binary forms, with or without modification,
\r
6 are permitted provided that the following conditions are met:
\r
8 Redistributions of source code must retain the above copyright notice, this list
\r
9 of conditions and the following disclaimer.
\r
11 Redistributions in binary form must reproduce the above copyright notice, this
\r
12 list of conditions and the following disclaimer in the documentation and/or
\r
13 other materials provided with the distribution.
\r
15 Neither the name of Loki software nor the names of its contributors may be used
\r
16 to endorse or promote products derived from this software without specific prior
\r
17 written permission.
\r
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
\r
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
22 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
\r
23 DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
\r
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
36 // loose replacement for CString from MFC
\r
52 #define strcasecmp strcmpi
\r
55 // NOTE TTimo __StrDup was initially implemented in pakstuff.cpp
\r
56 // causing a bunch of issues for broader targets that use Str.h (such as plugins and modules)
\r
57 // Q_StrDup should be used now, using a #define __StrDup for easy transition
\r
59 #define __StrDup Q_StrDup
\r
61 inline char* Q_StrDup(char* pStr)
\r
66 return strcpy(new char[strlen(pStr)+1], pStr);
\r
69 inline char* Q_StrDup(const char* pStr)
\r
74 return strcpy(new char[strlen(pStr)+1], pStr);
\r
77 #if defined (__linux__) || defined (__APPLE__)
\r
78 #define strcmpi strcasecmp
\r
79 #define stricmp strcasecmp
\r
80 #define strnicmp strncasecmp
\r
82 inline char* strlwr(char* string)
\r
85 for (cp = string; *cp; ++cp)
\r
87 if ('A' <= *cp && *cp <= 'Z')
\r
94 inline char* strupr(char* string)
\r
97 for (cp = string; *cp; ++cp)
\r
99 if ('a' <= *cp && *cp <= 'z')
\r
107 static char *g_pStrWork = NULL;
\r
112 bool m_bIgnoreCase;
\r
118 m_bIgnoreCase = true;
\r
119 m_pStr = new char[1];
\r
125 m_bIgnoreCase = true;
\r
126 m_pStr = __StrDup(p);
\r
131 m_bIgnoreCase = true;
\r
132 m_pStr = __StrDup(p);
\r
135 Str(const unsigned char *p)
\r
137 m_bIgnoreCase = true;
\r
138 m_pStr = __StrDup((const char *)p);
\r
143 m_bIgnoreCase = true;
\r
144 m_pStr = new char[2];
\r
149 const char* GetBuffer() const
\r
156 m_bIgnoreCase = true;
\r
157 m_pStr = __StrDup(s.GetBuffer());
\r
166 void Allocate(int n)
\r
169 m_pStr = new char[n];
\r
175 m_pStr = __StrDup("");
\r
181 // NOTE TTimo: someone explain this g_pStrWork to me?
\r
183 delete []g_pStrWork;
\r
205 char* lpsz = m_pStr;
\r
206 char* lpszLast = NULL;
\r
207 while (*lpsz != '\0')
\r
209 if (isspace(*lpsz))
\r
211 if (lpszLast == NULL)
\r
219 if (lpszLast != NULL)
\r
221 // truncate at trailing space start
\r
228 // find first non-space character
\r
229 char* lpsz = m_pStr;
\r
230 while (isspace(*lpsz))
\r
233 // fix up data and length
\r
234 int nDataLength = GetLength() - (lpsz - m_pStr);
\r
235 memmove(m_pStr, lpsz, (nDataLength+1));
\r
238 int Find(const char *p)
\r
240 char *pf = strstr(m_pStr, p);
\r
241 return (pf) ? (pf - m_pStr) : -1;
\r
244 // search starting at a given offset
\r
245 int Find(const char *p, int offset)
\r
247 char *pf = strstr(m_pStr+offset, p);
\r
248 return (pf) ? (pf - m_pStr) : -1;
\r
251 int Find(const char ch)
\r
253 char *pf = strchr (m_pStr, ch);
\r
254 return (pf) ? (pf - m_pStr) : -1;
\r
257 int ReverseFind(const char ch)
\r
259 char *pf = strrchr(m_pStr, ch);
\r
260 return (pf) ? (pf - m_pStr) : -1;
\r
263 int Compare (const char* str) const
\r
265 return strcmp (m_pStr, str);
\r
268 int CompareNoCase (const char* str) const
\r
270 return strcasecmp (m_pStr, str);
\r
275 return (m_pStr) ? strlen(m_pStr) : 0;
\r
278 const char* Left(int n)
\r
280 delete []g_pStrWork;
\r
283 g_pStrWork = new char[n+1];
\r
284 strncpy(g_pStrWork, m_pStr, n);
\r
285 g_pStrWork[n] = '\0';
\r
290 g_pStrWork = new char[1];
\r
291 g_pStrWork[0] = '\0';
\r
296 const char* Right(int n)
\r
298 delete []g_pStrWork;
\r
301 g_pStrWork = new char[n+1];
\r
302 int nStart = GetLength() - n;
\r
303 strncpy(g_pStrWork, &m_pStr[nStart], n);
\r
304 g_pStrWork[n] = '\0';
\r
308 g_pStrWork = new char[1];
\r
309 g_pStrWork[0] = '\0';
\r
314 const char* Mid(int nFirst) const
\r
316 return Mid(nFirst, strlen (m_pStr) - nFirst);
\r
319 const char* Mid(int first, int n) const
\r
321 delete []g_pStrWork;
\r
324 g_pStrWork = new char[n+1];
\r
325 strncpy(g_pStrWork, m_pStr+first, n);
\r
326 g_pStrWork[n] = '\0';
\r
331 g_pStrWork = new char[1];
\r
332 g_pStrWork[0] = '\0';
\r
338 void Format(const char* fmt, ...)
\r
343 va_start (args, fmt);
\r
344 buffer = g_strdup_vprintf (fmt, args);
\r
348 m_pStr = __StrDup(buffer);
\r
352 void Format(const char* fmt, ...)
\r
355 m_pStr = new char[1024];
\r
357 va_start (args, fmt);
\r
358 vsprintf (m_pStr, fmt, args);
\r
363 void SetAt(int n, char ch)
\r
365 if (n >= 0 && n < GetLength ())
\r
369 // NOTE: unlike CString, this looses the pointer
\r
370 void ReleaseBuffer(int n = -1)
\r
375 char* tmp = m_pStr;
\r
377 m_pStr = __StrDup(tmp);
\r
381 char* GetBufferSetLength(int n)
\r
386 char *p = new char[n+1];
\r
387 strncpy (p, m_pStr, n);
\r
394 // char& operator *() { return *m_pStr; }
\r
395 // char& operator *() const { return *const_cast<Str*>(this)->m_pStr; }
\r
396 operator void*() { return m_pStr; }
\r
397 operator char*() { return m_pStr; }
\r
398 operator const char*(){ return reinterpret_cast<const char*>(m_pStr); }
\r
399 operator unsigned char*() { return reinterpret_cast<unsigned char*>(m_pStr); }
\r
400 operator const unsigned char*() { return reinterpret_cast<const unsigned char*>(m_pStr); }
\r
401 Str& operator =(const Str& rhs)
\r
406 m_pStr = __StrDup(rhs.m_pStr);
\r
411 Str& operator =(const char* pStr)
\r
413 if (m_pStr != pStr)
\r
416 m_pStr = __StrDup(pStr);
\r
421 Str& operator +=(const char ch)
\r
423 int len = GetLength ();
\r
424 char *p = new char[len + 1 + 1];
\r
434 m_pStr[len+1] = '\0';
\r
439 Str& operator +=(const char *pStr)
\r
445 char *p = new char[strlen(m_pStr) + strlen(pStr) + 1];
\r
453 m_pStr = __StrDup(pStr);
\r
460 bool operator ==(const Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) == 0 : strcmp(m_pStr, rhs.m_pStr) == 0; }
\r
461 bool operator ==(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) == 0 : strcmp(m_pStr, pStr) == 0; }
\r
462 bool operator ==(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) == 0 : strcmp(m_pStr, pStr) == 0; }
\r
463 bool operator !=(Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) != 0 : strcmp(m_pStr, rhs.m_pStr) != 0; }
\r
464 bool operator !=(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) != 0 : strcmp(m_pStr, pStr) != 0; }
\r
465 bool operator !=(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) != 0 : strcmp(m_pStr, pStr) != 0; }
\r
466 bool operator <(const Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) < 0 : strcmp(m_pStr, rhs.m_pStr) < 0; }
\r
467 bool operator <(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) < 0 : strcmp(m_pStr, pStr) < 0; }
\r
468 bool operator <(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) < 0 : strcmp(m_pStr, pStr) < 0; }
\r
469 bool operator >(const Str& rhs) const { return (m_bIgnoreCase) ? stricmp(m_pStr, rhs.m_pStr) > 0 : strcmp(m_pStr, rhs.m_pStr) > 0; }
\r
470 bool operator >(char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) > 0 : strcmp(m_pStr, pStr) > 0; }
\r
471 bool operator >(const char* pStr) const { return (m_bIgnoreCase) ? stricmp(m_pStr, pStr) > 0 : strcmp(m_pStr, pStr) > 0; }
\r
472 char& operator [](int nIndex) { return m_pStr[nIndex]; }
\r
473 char& operator [](int nIndex) const { return m_pStr[nIndex]; }
\r
474 const char GetAt (int nIndex) { return m_pStr[nIndex]; }
\r