Updated some CS:GO gamedata.
2 * vim: set ts=4 sw=4 tw=99 et :
3 * =============================================================================
5 * Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
35 #include <sm_platform.h>
36 #include "stringutil.h"
38 // We're in logic so we don't have this from the SDK.
40 #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
43 const char *stristr(const char *str, const char *substr)
50 char *needle = (char *)substr;
51 char *prevloc = (char *)str;
52 char *haystack = (char *)str;
56 if (tolower(*haystack) == tolower(*needle))
67 needle = (char *)substr;
74 unsigned int strncopy(char *dest, const char *src, size_t count)
82 while ((*src) && (--count))
88 return (dest - start);
91 unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search, const char *replace, bool caseSensitive)
93 size_t searchLen = strlen(search);
94 size_t replaceLen = strlen(replace);
97 unsigned int total = 0;
98 while ((ptr = UTIL_ReplaceEx(ptr, maxlength, search, searchLen, replace, replaceLen, caseSensitive)) != NULL)
111 * NOTE: Do not edit this for the love of god unless you have
112 * read the test cases and understand the code behind each one.
113 * While I don't guarantee there aren't mistakes, I do guarantee
114 * that plugins will end up relying on tiny idiosyncrasies of this
115 * function, just like they did with AMX Mod X.
117 * There are explicitly more cases than the AMX Mod X version because
118 * we're not doing a blind copy. Each case is specifically optimized
119 * for what needs to be done. Even better, we don't have to error on
120 * bad buffer sizes. Instead, this function will smartly cut off the
121 * string in a way that pushes old data out.
123 char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive)
127 size_t textLen = strlen(subject);
129 /* It's not possible to search or replace */
130 if (searchLen > textLen)
135 /* Handle the case of one byte replacement.
136 * It's only valid in one case.
140 /* If the search matches and the replace length is 0,
141 * we can just terminate the string and be done.
143 if ((caseSensitive ? strcmp(subject, search) : strcasecmp(subject, search)) == 0 && replaceLen == 0)
154 /* Subtract one off the maxlength so we can include the null terminator */
157 while (*ptr != '\0' && (browsed <= textLen - searchLen))
159 /* See if we get a comparison */
160 if ((caseSensitive ? strncmp(ptr, search, searchLen) : strncasecmp(ptr, search, searchLen)) == 0)
162 if (replaceLen > searchLen)
164 /* First, see if we have enough space to do this operation */
165 if (maxLen - textLen < replaceLen - searchLen)
167 /* First, see if the replacement length goes out of bounds. */
168 if (browsed + replaceLen >= maxLen)
174 * Replace: DDDDDDDDDD
175 * OUTPUT : AADDDDDDDDD
178 /* If it does, we'll just bound the length and do a strcpy. */
179 replaceLen = maxLen - browsed;
180 /* Note, we add one to the final result for the null terminator */
181 strncopy(ptr, replace, replaceLen+1);
190 * OUTPUT : AADDDDDDDCC
193 /* We're going to have some bytes left over... */
194 size_t origBytesToCopy = (textLen - (browsed + searchLen)) + 1;
195 size_t realBytesToCopy = (maxLen - (browsed + replaceLen)) + 1;
196 char *moveFrom = ptr + searchLen + (origBytesToCopy - realBytesToCopy);
197 char *moveTo = ptr + replaceLen;
199 /* First, move our old data out of the way. */
200 memmove(moveTo, moveFrom, realBytesToCopy);
202 /* Now, do our replacement. */
203 memcpy(ptr, replace, replaceLen);
216 /* Yes, we have enough space. Do a normal move operation. */
217 char *moveFrom = ptr + searchLen;
218 char *moveTo = ptr + replaceLen;
220 /* First move our old data out of the way. */
221 size_t bytesToCopy = (textLen - (browsed + searchLen)) + 1;
222 memmove(moveTo, moveFrom, bytesToCopy);
224 /* Now do our replacement. */
225 memcpy(ptr, replace, replaceLen);
228 else if (replaceLen < searchLen)
238 /* If the replacement does not grow the string length, we do not
239 * need to do any fancy checking at all. Yay!
241 char *moveFrom = ptr + searchLen; /* Start after the search pointer */
242 char *moveTo = ptr + replaceLen; /* Copy to where the replacement ends */
244 /* Copy our replacement in, if any */
247 memcpy(ptr, replace, replaceLen);
250 /* Figure out how many bytes to move down, including null terminator */
251 size_t bytesToCopy = (textLen - (browsed + searchLen)) + 1;
253 /* Move the rest of the string down */
254 memmove(moveTo, moveFrom, bytesToCopy);
266 /* We don't have to move anything around, just do a straight copy */
267 memcpy(ptr, replace, replaceLen);
270 return ptr + replaceLen;
279 size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr)
282 size_t length = strlen(hexstr);
284 for (size_t i = 0; i < length; i++)
286 if (written >= maxlength)
288 buffer[written++] = hexstr[i];
289 if (hexstr[i] == '\\' && hexstr[i + 1] == 'x')
293 /* Get the hex part. */
296 s_byte[0] = hexstr[i + 2];
297 s_byte[1] = hexstr[i + 3];
299 /* Read it as an integer */
300 sscanf(s_byte, "%x", &r_byte);
302 buffer[written - 1] = r_byte;
311 #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
313 void UTIL_StripExtension(const char *in, char *out, int outSize)
315 // Find the last dot. If it's followed by a dot or a slash, then it's part of a
316 // directory specifier like ../../somedir/./blah.
318 // scan backward for '.'
319 int end = strlen(in) - 1;
320 while (end > 0 && in[end] != '.' && !PATHSEPARATOR(in[end]))
325 if (end > 0 && !PATHSEPARATOR(in[end]) && end < outSize)
327 int nChars = MIN(end, outSize-1);
330 memcpy(out, in, nChars);
339 strncopy(out, in, outSize);