plugins/include/string.inc
author David Anderson <dvander@alliedmods.net>
Mon Aug 13 01:46:58 2007 +0000 (2007-08-13)
changeset 1316 5d3283c02c54
parent 1268 9360f5ea2289
child 1330 ab94316bb52b
permissions -rw-r--r--
initial import of sql admins prefetch plugin and associated table schemas
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     7  *  This file is part of the SourceMod/SourcePawn SDK.  This file may only be used 
     8  * or modified under the Terms and Conditions of its License Agreement, which is found 
     9  * in LICENSE.txt.  The Terms and Conditions for making SourceMod extensions/plugins 
    10  * may change at any time.  To view the latest information, see:
    11  *   http://www.sourcemod.net/license.php
    12  *
    13  * Version: $Id$
    14  */
    15  
    16 #if defined _string_included
    17  #endinput
    18 #endif
    19 #define _string_included
    20 
    21 /**
    22  * @global Unless otherwise noted, all string functions which take in a 
    23  * writable buffer and maximum length should have the null terminator INCLUDED
    24  * in the length.  This means that this is valid: 
    25  * strcopy(string, sizeof(string), ...)
    26  */
    27  
    28 /**
    29  * Calculates the length of a string.
    30  *
    31  * @param str			String to check.
    32  * @return				Length of string, in cells (NOT characters).
    33  */
    34 native strlen(const String:str[]);
    35 
    36 /**
    37  * Tests whether a string is found inside another string.
    38  *
    39  * @param str			String to search in.
    40  * @param substr		Substring to find inside the original string.
    41  * @param caseSensitive	If true (default), search is case sensitive.
    42  *						If false, search is case insensitive.
    43  * @return				-1 on failure (no match found). Any other value
    44  *						indicates a position in the string where the match starts.
    45  */
    46 native StrContains(const String:str[], const String:substr[], bool:caseSensitive=true);
    47 
    48 /**
    49  * Compares two strings lexographically.
    50  *
    51  * @param str1			First string (left).
    52  * @param str2			Second string (right).
    53  * @param caseSensitive	If true (default), comparison is case sensitive.
    54  *						If false, comparison is case insensitive.
    55  * @return				-1 if str1 < str2
    56  *						0 if str1 == str2
    57  *						1 if str1 > str2
    58  */
    59 native strcmp(const String:str1[], const String:str2[], bool:caseSensitive=true);
    60 
    61 /**
    62  * Compares two strings parts lexographically.
    63  *
    64  * @param str1			First string (left).
    65  * @param str2			Second string (right).
    66  * @param num			Number of characters to compare.
    67  * @param caseSensitive	If true (default), comparison is case sensitive.
    68  *						If false, comparison is case insensitive.
    69  * @return				-1 if str1 < str2
    70  *						0 if str1 == str2
    71  *						1 if str1 > str2
    72  */
    73 native strncmp(const String:str1[], const String:str2[], num, bool:caseSensitive=true);
    74 
    75 /**
    76  * Backwards compatible stock - StrCompare is now strcmp
    77  * @deprecated		Renamed to strcmp
    78  */
    79 #pragma deprecated Use strcmp() instead
    80 stock StrCompare(const String:str1[], const String:str2[], bool:caseSensitive=true)
    81 {
    82 	return strcmp(str1, str2, caseSensitive);
    83 }
    84 
    85 /**
    86  * Returns whether two strings are equal.
    87  *
    88  * @param str1			First string (left).
    89  * @param str2			Second string (right).
    90  * @param caseSensitive	If true (default), comparison is case sensitive.
    91  * 						If false, comparison is case insensitive.
    92  * @return				True if equal, false otherwise.
    93  */
    94 stock bool:StrEqual(const String:str1[], const String:str2[], bool:caseSensitive=true)
    95 {
    96 	return (strcmp(str1, str2, caseSensitive) == 0);
    97 }
    98 
    99 /**
   100  * Copies one string to another string.
   101  * @note If the destination buffer is too small to hold the source string, the 
   102  *       destination will be truncated.
   103  *
   104  * @param dest			Destination string buffer to copy to.
   105  * @param destlen		Destination buffer length (includes null terminator).
   106  * @param source		Source string buffer to copy from.
   107  * @return				Number of cells written.
   108  */
   109 native strcopy(String:dest[], destLen, const String:source[]);
   110 
   111 /**
   112  * Backwards compatibility stock - use strcopy
   113  * @deprecated			Renamed to strcopy
   114  */
   115 #pragma deprecated Use strcopy() instead
   116 stock StrCopy(String:dest[], destLen, const String:source[])
   117 {
   118 	return strcopy(dest, destLen, source);
   119 }
   120 
   121 /**
   122  * Formats a string according to the SourceMod format rules (see documentation).
   123  *
   124  * @param buffer		Destination string buffer.
   125  * @param maxlength		Maximum length of output string buffer.
   126  * @param format		Formatting rules.
   127  * @param ...			Variable number of format parameters.
   128  * @return				Number of cells written.
   129  */
   130 native Format(String:buffer[], maxlength, const String:format[], any:...);
   131 
   132 /**
   133  * Formats a string according to the SourceMod format rules (see documentation).
   134  * @note This is the same as Format(), except none of the input buffers can 
   135  *       overlap the same memory as the output buffer.  Since this security 
   136  *       check is removed, it is slightly faster.
   137  *
   138  * @param buffer		Destination string buffer.
   139  * @param maxlength		Maximum length of output string buffer.
   140  * @param format		Formatting rules.
   141  * @param ...			Variable number of format parameters.
   142  * @return				Number of cells written.
   143  */
   144 native FormatEx(String:buffer[], maxlength, const String:format[], any:...);
   145 
   146 /**
   147  * Formats a string according to the SourceMod format rules (see documentation).
   148  * @note This is the same as Format(), except it grabs parameters from a 
   149  *       parent parameter stack, rather than a local.  This is useful for 
   150  *       implementing your own variable argument functions.
   151  *
   152  * @param buffer		Destination string buffer.
   153  * @param maxlength		Maximum length of output string buffer.
   154  * @param format		Formatting rules.
   155  * @param varpos		Argument number which contains the '...' symbol.
   156  *						Note: Arguments start at 1.
   157  * @return 				Number of bytes written.
   158  */
   159 native VFormat(String:buffer[], maxlength, const String:format[], varpos);
   160 
   161 /**
   162  * Converts a string to an integer.
   163  *
   164  * @param str			String to convert.
   165  * @param nBase			Numerical base to use.  10 is default.
   166  * @return				Integer conversion of string, or 0 on failure.
   167  */
   168 native StringToInt(const String:str[], nBase=10);
   169 
   170 /**
   171  * Converts a string to an integer with some more options.
   172  *
   173  * @param str			String to convert.
   174  * @param result		Variable to store the result in.
   175  * @param nBase			Numerical base to use.  10 is default.
   176  * @return				Number of characters consumed.
   177  */
   178 native StringToIntEx(const String:str[], &result, nBase=10);
   179 
   180 /**
   181  * Converts an integer to a string.
   182  *
   183  * @param num			Integer to convert.
   184  * @param str			Buffer to store string in.
   185  * @param maxlength		Maximum length of string buffer.
   186  * @return				Number of cells written to buffer.
   187  */
   188 native IntToString(num, String:str[], maxlength);
   189 
   190 /** 
   191  * Converts a string to a floating point number.
   192  *
   193  * @param str			String to convert to a foat.
   194  * @return				Floating point result, or 0.0 on error.
   195  */
   196 native Float:StringToFloat(const String:str[]);
   197 
   198 /** 
   199  * Converts a string to a floating point number with some more options.
   200  *
   201  * @param str			String to convert to a foat.
   202  * @param result		Variable to store result in.
   203  * @return				Number of characters consumed.
   204  */
   205 native StringToFloatEx(const String:str[], &Float:result);
   206 
   207 /**
   208  * Converts a floating point number to a string.
   209  *
   210  * @param num			Floating point number to convert.
   211  * @param str			Buffer to store string in.
   212  * @param maxlength		Maximum length of string buffer.
   213  * @return				Number of cells written to buffer.
   214  */
   215 native FloatToString(Float:num, String:str[], maxlength);
   216 
   217 /**
   218  * Finds the first "argument" in a string; either a set of space
   219  * terminated characters, or a fully quoted string.  After the 
   220  * argument is found, whitespace is read until the next portion
   221  * of the string is reached.  If nothing remains, -1 is returned.
   222  * Otherwise, the index to the first character is returned.
   223  *
   224  * @param source		Source input string.
   225  * @param arg			Stores argument read from string.
   226  * @param argLen		Maximum length of argument buffer.
   227  * @return				Index to next piece of string, or -1 if none.
   228  */
   229 native BreakString(const String:source[], String:arg[], argLen);
   230 
   231 /**
   232  * Backwards compatibility stock - use BreakString
   233  * @deprecated			Renamed to BreakString.
   234  */
   235 #pragma deprecated Use BreakString() instead
   236 stock StrBreak(const String:source[], String:arg[], argLen)
   237 {
   238 	return BreakString(source, arg, argLen);
   239 }
   240 
   241 /**
   242  * Removes whitespace characters from the beginning and end of a string.
   243  *
   244  * @param str			The string to trim.
   245  * @return				Number of bytes written (UTF-8 safe).
   246  */
   247 native TrimString(String:str[]);
   248 
   249 /**
   250  * Returns text in a string up until a certain character sequence is reached.
   251  *
   252  * @param source		Source input string.
   253  * @param split			A string which specifies a search point to break at.
   254  * @param part			Buffer to store string part.
   255  * @param partLen		Maximum length of the string part buffer.
   256  * @return				-1 if no match was found; otherwise, an index into source
   257  *						marking the first index after the searched text.  The
   258  *						index is always relative to the start of the input string.
   259  */
   260 native SplitString(const String:source[], const String:split[], String:part[], partLen);
   261 
   262 /**
   263  * Given a string, replaces all occurrences of a search string with a 
   264  * replacement string.
   265  *
   266  * @param text			String to perform search and replacements on.
   267  * @param maxlength		Maximum length of the string buffer.
   268  * @param search		String to search for.
   269  * @param replace		String to replace the search string with.
   270  * @return				Number of replacements that were performed.
   271  */
   272 native ReplaceString(String:text[], maxlength, const String:search[], const String:replace[]);
   273 
   274 /**
   275  * Given a string, replaces the first occurrence of a search string with a 
   276  * replacement string.
   277  *
   278  * @param text			String to perform search and replacements on.
   279  * @param maxlength		Maximum length of the string buffer.
   280  * @param search		String to search for.
   281  * @param replace		String to replace the search string with.
   282  * @param searchLen		If higher than -1, its value will be used instead of
   283  *						a strlen() call on the search parameter.
   284  * @param replaceLen	If higher than -1, its value will be used instead of
   285  *						a strlen() call on the replace parameter.
   286  * @return				Index into the buffer (relative to the start) from where
   287  *						the last replacement ended, or -1 if no replacements were
   288  *						made.
   289  */
   290 native ReplaceStringEx(String:text[], maxlength, const String:search[], const String:replace[], searchLen=-1, replaceLen=-1);
   291 
   292 /** 
   293  * Returns the number of bytes a character is using.  This is
   294  * for multi-byte characters (UTF-8).  For normal ASCII characters,
   295  * this will return 1.
   296  *
   297  * @param source		Source input string.
   298  * @return				Number of bytes the current character uses.
   299  */
   300 native GetCharBytes(const String:source[]);
   301 
   302 /**
   303  * Returns whether a character is an ASCII alphabet character.
   304  *
   305  * @note Multi-byte characters will always return false.
   306  *
   307  * @param char			Character to test.
   308  * @return				True if character is alphabetical, otherwise false.
   309  */
   310 native bool:IsCharAlpha(chr);
   311 
   312 /**
   313  * Returns whether a character is numeric.
   314  *
   315  * @note Multi-byte characters will always return false.
   316  *
   317  * @param char			Character to test.
   318  * @return				True if character is numeric, otherwise false.
   319  */
   320 native bool:IsCharNumeric(chr);
   321 
   322 /**
   323  * Returns whether a character is whitespace.
   324  *
   325  * @note Multi-byte characters will always return false.
   326  *
   327  * @param char			Character to test.
   328  * @return				True if character is whitespace, otherwise false.
   329  */
   330 native bool:IsCharSpace(chr);
   331 
   332 /**
   333  * Returns if a character is multi-byte or not.
   334  *
   335  * @param char			Character to test.
   336  * @return				0 for a normal 7-bit ASCII character,
   337  *						otherwise number of bytes in multi-byte character.
   338  */
   339 native IsCharMB(chr);
   340 
   341 /**
   342  * Returns whether an alphabetic character is uppercase.
   343  *
   344  * @note Multi-byte characters will always return false.
   345  *
   346  * @param char			Character to test.
   347  * @return				True if character is uppercase, otherwise false.
   348  */
   349 native bool:IsCharUpper(chr);
   350 
   351 /**
   352  * Returns whether an alphabetic character is lowercase.
   353  *
   354  * @note Multi-byte characters will always return false.
   355  *
   356  * @param char			Character to test.
   357  * @return				True if character is lowercase, otherwise false.
   358  */
   359 native bool:IsCharLower(chr);
   360 
   361 /**
   362  * Returns an uppercase character to a lowercase character.
   363  *
   364  * @param chr			Characer to convert.
   365  * @return				Lowercase character on success, 
   366  *						no change on failure.
   367  */
   368 stock CharToUpper(chr)
   369 {
   370 	if (IsCharLower(chr))
   371 	{
   372 		return (chr & ~(1<<5));
   373 	}
   374 	return chr;
   375 }
   376 
   377 /**
   378  * Returns a lowercase character to an uppercase character.
   379  *
   380  * @param chr			Characer to convert.
   381  * @return				Uppercase character on success, 
   382  *						no change on failure.
   383  */
   384 stock CharToLower(chr)
   385 {
   386 	if (IsCharUpper(chr))
   387 	{
   388 		return (chr | (1<<5));
   389 	}
   390 	return chr;
   391 }
   392 
   393 /**
   394  * Concatenates one string onto another.
   395  *
   396  * @param buffer		String to append to.
   397  * @param maxlength		Maximum length of entire buffer.
   398  * @param source		Source string to concatenate.
   399  * @return				Number of bytes written.
   400  */
   401 stock StrCat(String:buffer[], maxlength, const String:source[])
   402 {
   403 	new len = strlen(buffer);
   404 	if (len >= maxlength)
   405 	{
   406 		return 0;
   407 	}
   408 	
   409 	return Format(buffer[len], maxlength-len, "%s", source);
   410 }
   411 
   412 /**
   413  * Breaks a string into pieces and stores each piece into an array of buffers.
   414  *
   415  * @param text				The string to split.
   416  * @param split				The string to use as a split delimiter.
   417  * @param buffers			An array of string buffers (2D array).
   418  * @param maxStrings		Number of string buffers (first dimension size).
   419  * @param maxStringLength	Maximum length of each string buffer.
   420  * @return					Number of strings retrieved.
   421  */
   422 stock ExplodeString(const String:text[], const String:split[], String:buffers[][], maxStrings, maxStringLength)
   423 {
   424 	new reloc_idx, idx, total;
   425 	
   426 	if (maxStrings < 1 || split[0] == '\0')
   427 	{
   428 		return 0;
   429 	}
   430 	
   431 	while ((idx = SplitString(text[reloc_idx], split, buffers[total], maxStringLength)) != -1)
   432 	{
   433 		reloc_idx += idx;
   434 		if (text[reloc_idx] == '\0')
   435 		{
   436 			break;
   437 		}
   438 		if (++total >= maxStrings)
   439 		{
   440 			return total;
   441 		}
   442 	}
   443 	
   444 	if (text[reloc_idx] != '\0' && total <= maxStrings - 1)
   445 	{
   446 		strcopy(buffers[total++], maxStringLength, text[reloc_idx]);
   447 	}
   448 	
   449 	return total;
   450 }
   451 
   452 /**
   453  * Joins an array of strings into one string, with a "join" string inserted in
   454  * between each given string.  This function complements ExplodeString.
   455  *
   456  * @param strings		An array of strings.
   457  * @param numStrings	Number of strings in the array.
   458  * @param join			The join string to insert between each string.
   459  * @param buffer		Output buffer to write the joined string to.
   460  * @param maxLength		Maximum length of the output buffer.
   461  * @return				Number of bytes written to the output buffer.
   462  */
   463 stock ImplodeStrings(const String:strings[][], numStrings, const String:join[], String:buffer[], maxLength)
   464 {
   465 	new total, length, part_length;
   466 	new join_length = strlen(join);
   467 	for (new i=0; i<numStrings; i++)
   468 	{
   469 		length = strcopy(buffer[total], maxLength-total, strings[i]);
   470 		total += length;
   471 		if (length < part_length)
   472 		{
   473 			break;
   474 		}
   475 		if (i != numStrings - 1)
   476 		{
   477 			length = strcopy(buffer[total], maxLength-total, join);
   478 			total += length;
   479 			if (length < join_length)
   480 			{
   481 				break;
   482 			}
   483 		}
   484 	}
   485 	return total;
   486 }