fbcc7330e2a386c979aeb0469c406402b8dc7558
2 ** NetXMS - Network Management System
3 ** NetXMS Foundation Library
4 ** Copyright (C) 2003-2009 Victor Kirhenshtein
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "libnetxms.h"
31 const int String::npos
= -1;
44 String::String(const String
&src
)
46 m_dwBufSize
= src
.m_dwBufSize
;
47 m_pszBuffer
= (src
.m_pszBuffer
!= NULL
) ? (TCHAR
*)nx_memdup(src
.m_pszBuffer
, src
.m_dwBufSize
* sizeof(TCHAR
)) : NULL
;
50 String::String(const TCHAR
*init
)
52 m_dwBufSize
= (DWORD
)_tcslen(init
) + 1;
53 m_pszBuffer
= _tcsdup(init
);
63 safe_free(m_pszBuffer
);
71 const String
& String::operator =(const TCHAR
*pszStr
)
73 safe_free(m_pszBuffer
);
74 m_pszBuffer
= _tcsdup(CHECK_NULL_EX(pszStr
));
75 m_dwBufSize
= (DWORD
)_tcslen(CHECK_NULL_EX(pszStr
)) + 1;
84 const String
& String::operator +=(const TCHAR
*pszStr
)
90 dwLen
= (DWORD
)_tcslen(pszStr
);
91 m_pszBuffer
= (TCHAR
*)realloc(m_pszBuffer
, (m_dwBufSize
+ dwLen
) * sizeof(TCHAR
));
92 _tcscpy(&m_pszBuffer
[m_dwBufSize
- 1], pszStr
);
100 // Add formatted string to the end of buffer
103 void String::addFormattedString(const TCHAR
*format
, ...)
107 va_start(args
, format
);
108 addFormattedStringV(format
, args
);
112 void String::addFormattedStringV(const TCHAR
*format
, va_list args
)
120 vaswprintf(&buffer
, format
, args
);
121 #elif HAVE_VSCWPRINTF && HAVE_DECL_VA_COPY
123 va_copy(argsCopy
, args
);
125 len
= (int)vscwprintf(format
, args
) + 1;
126 buffer
= (WCHAR
*)malloc(len
* sizeof(WCHAR
));
128 vsnwprintf(buffer
, len
, format
, argsCopy
);
131 // No way to determine required buffer size, guess
132 len
= wcslen(format
) + CharCount(format
, L
'%') * 1000 + 1;
133 buffer
= (WCHAR
*)malloc(len
* sizeof(WCHAR
));
135 vsnwprintf(buffer
, len
, format
, args
);
141 vasprintf(&buffer
, format
, args
);
142 #elif HAVE_VSCPRINTF && HAVE_DECL_VA_COPY
144 va_copy(argsCopy
, args
);
146 len
= (int)vscprintf(format
, args
) + 1;
147 buffer
= (char *)malloc(len
);
149 vsnprintf(buffer
, len
, format
, argsCopy
);
151 #elif SNPRINTF_RETURNS_REQUIRED_SIZE && HAVE_DECL_VA_COPY
153 va_copy(argsCopy
, args
);
155 len
= (int)snprintf(NULL
, 0, format
, args
) + 1;
156 buffer
= (char *)malloc(len
);
158 vsnprintf(buffer
, len
, format
, argsCopy
);
161 // No way to determine required buffer size, guess
162 len
= strlen(format
) + NumChars(format
, '%') * 1000 + 1;
163 buffer
= (char *)malloc(len
);
165 vsnprintf(buffer
, len
, format
, args
);
176 // Add string to the end of buffer
179 void String::addString(const TCHAR
*pStr
, DWORD dwSize
)
181 m_pszBuffer
= (TCHAR
*)realloc(m_pszBuffer
, (m_dwBufSize
+ dwSize
) * sizeof(TCHAR
));
182 memcpy(&m_pszBuffer
[m_dwBufSize
- 1], pStr
, dwSize
* sizeof(TCHAR
));
183 m_dwBufSize
+= dwSize
;
184 m_pszBuffer
[m_dwBufSize
- 1] = 0;
189 // Add multibyte string to the end of buffer
192 void String::addMultiByteString(const char *pStr
, DWORD dwSize
, int nCodePage
)
195 m_pszBuffer
= (TCHAR
*)realloc(m_pszBuffer
, (m_dwBufSize
+ dwSize
) * sizeof(TCHAR
));
196 MultiByteToWideChar(nCodePage
, (nCodePage
== CP_UTF8
) ? 0 : MB_PRECOMPOSED
, pStr
, dwSize
, &m_pszBuffer
[m_dwBufSize
- 1], dwSize
);
197 m_dwBufSize
+= dwSize
;
198 m_pszBuffer
[m_dwBufSize
- 1] = 0;
200 addString(pStr
, dwSize
);
206 // Add widechar string to the end of buffer
209 void String::addWideCharString(const WCHAR
*pStr
, DWORD dwSize
)
212 addString(pStr
, dwSize
);
214 m_pszBuffer
= (TCHAR
*)realloc(m_pszBuffer
, (m_dwBufSize
+ dwSize
) * sizeof(TCHAR
));
215 WideCharToMultiByte(CP_ACP
, WC_COMPOSITECHECK
| WC_DEFAULTCHAR
, pStr
, dwSize
, &m_pszBuffer
[m_dwBufSize
- 1], dwSize
, NULL
, NULL
);
216 m_dwBufSize
+= dwSize
;
217 m_pszBuffer
[m_dwBufSize
- 1] = 0;
223 // Escape given character
226 void String::escapeCharacter(int ch
, int esc
)
231 if (m_pszBuffer
== NULL
)
234 nCount
= NumChars(m_pszBuffer
, ch
);
238 m_dwBufSize
+= nCount
;
239 m_pszBuffer
= (TCHAR
*)realloc(m_pszBuffer
, m_dwBufSize
* sizeof(TCHAR
));
240 for(i
= 0; m_pszBuffer
[i
] != 0; i
++)
242 if (m_pszBuffer
[i
] == ch
)
244 memmove(&m_pszBuffer
[i
+ 1], &m_pszBuffer
[i
], (m_dwBufSize
- i
- 1) * sizeof(TCHAR
));
245 m_pszBuffer
[i
] = esc
;
253 // Set dynamically allocated string as a new buffer
256 void String::setBuffer(TCHAR
*pszBuffer
)
258 safe_free(m_pszBuffer
);
259 m_pszBuffer
= pszBuffer
;
260 m_dwBufSize
= (m_pszBuffer
!= NULL
) ? (DWORD
)_tcslen(m_pszBuffer
) + 1 : 1;
265 // Translate given substring
268 void String::translate(const TCHAR
*pszSrc
, const TCHAR
*pszDst
)
270 DWORD i
, dwLenSrc
, dwLenDst
, dwDelta
;
272 if (m_pszBuffer
== NULL
)
275 dwLenSrc
= (DWORD
)_tcslen(pszSrc
);
276 dwLenDst
= (DWORD
)_tcslen(pszDst
);
278 if (m_dwBufSize
<= dwLenSrc
)
281 for(i
= 0; i
< m_dwBufSize
- dwLenSrc
; i
++)
283 if (!memcmp(pszSrc
, &m_pszBuffer
[i
], dwLenSrc
* sizeof(TCHAR
)))
285 if (dwLenSrc
== dwLenDst
)
287 memcpy(&m_pszBuffer
[i
], pszDst
, dwLenDst
* sizeof(TCHAR
));
290 else if (dwLenSrc
> dwLenDst
)
292 memcpy(&m_pszBuffer
[i
], pszDst
, dwLenDst
* sizeof(TCHAR
));
294 dwDelta
= dwLenSrc
- dwLenDst
;
295 m_dwBufSize
-= dwDelta
;
296 memmove(&m_pszBuffer
[i
], &m_pszBuffer
[i
+ dwDelta
], (m_dwBufSize
- i
) * sizeof(TCHAR
));
301 dwDelta
= dwLenDst
- dwLenSrc
;
302 m_pszBuffer
= (TCHAR
*)realloc(m_pszBuffer
, (m_dwBufSize
+ dwDelta
) * sizeof(TCHAR
));
303 memmove(&m_pszBuffer
[i
+ dwLenDst
], &m_pszBuffer
[i
+ dwLenSrc
], (m_dwBufSize
- i
- dwLenSrc
) * sizeof(TCHAR
));
304 m_dwBufSize
+= dwDelta
;
305 memcpy(&m_pszBuffer
[i
], pszDst
, dwLenDst
* sizeof(TCHAR
));
314 // Extract substring into buffer
317 TCHAR
*String::subStr(int nStart
, int nLen
, TCHAR
*pszBuffer
)
322 if ((nStart
< (int)m_dwBufSize
- 1) && (nStart
>= 0))
326 nCount
= (int)m_dwBufSize
- nStart
- 1;
330 nCount
= min(nLen
, (int)m_dwBufSize
- nStart
- 1);
332 pszOut
= (pszBuffer
!= NULL
) ? pszBuffer
: (TCHAR
*)malloc((nCount
+ 1) * sizeof(TCHAR
));
333 memcpy(pszOut
, &m_pszBuffer
[nStart
], nCount
* sizeof(TCHAR
));
338 pszOut
= (pszBuffer
!= NULL
) ? pszBuffer
: (TCHAR
*)malloc(sizeof(TCHAR
));
346 // Find substring in a string
349 int String::find(const TCHAR
*pszStr
, int nStart
)
353 if ((nStart
>= (int)m_dwBufSize
- 1) || (nStart
< 0))
356 p
= _tcsstr(&m_pszBuffer
[nStart
], pszStr
);
357 return (p
!= NULL
) ? (int)(((char *)p
- (char *)m_pszBuffer
) / sizeof(TCHAR
)) : npos
;
362 // Strip leading and trailing spaces, tabs, newlines
367 if (m_pszBuffer
!= NULL
)
370 m_dwBufSize
= (DWORD
)_tcslen(m_pszBuffer
) + 1;
376 // Shring string by removing trailing characters
379 void String::shrink(int chars
)
383 m_dwBufSize
-= min(m_dwBufSize
- 1, (DWORD
)chars
);
384 if (m_pszBuffer
!= NULL
)
385 m_pszBuffer
[m_dwBufSize
- 1] = 0;