sm-zombiereloaded-3/src/zr/paramtools.inc

219 lines
6.5 KiB
SourcePawn

/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: paramtools.inc
* Type: Core
* Description: Provides functions for parsing strings with parameters in
* key=value format.
*
* Note: Does not support spaces or quoted strings.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ============================================================================
*/
/**
* Counts number of parameters in a string.
*/
stock GetParameterCount(const String:rawString[])
{
new lenRawString = strlen(rawString);
new paramCount;
new searchPos;
new splitPos;
// Check if the raw string is empty.
if (lenRawString == 0)
{
return 0;
}
// Count number of "=".
for (splitPos = 0; splitPos < lenRawString; splitPos++)
{
// Find next "=".
searchPos = StrContains(rawString[splitPos], "=", false);
// Note: searchPos is an offset from rawString[splitPos]. If searchPos
// is 0, then the real position is splitPos.
// Check if "=" was found.
if (searchPos >= 0)
{
// Parameter found.
paramCount++;
// Update split position.
splitPos += searchPos;
}
else
{
// No need to continue. "=" not found.
break;
}
}
return paramCount;
}
/**
* Gets a value from a string in key=value format and writes it to a buffer.
*
* Note: No spaces in values or parameter names. Only spaces between each
* key/value set.
*
* Example raw string: "key1=val1 key2=5.3 key3=1"
*
* @param buffer Destination string bufffer.
* @param maxlen Length of destination buffer.
* @param rawString Source string to read from.
* @param parameter Parameter to read.
*
* @return Number of cells written. -1 if the parameter wasn't
* found.
*/
stock GetParameterValue(String:buffer[], maxlen, const String:rawString[], const String:parameter[])
{
new paramPos;
new paramLen;
new valuePos;
new valueLen;
new nextPos;
new splitPos;
// Get the position of parameter.
paramPos = StrContains(rawString, parameter, false);
splitPos = paramPos;
// Check if found.
if (paramPos >= 0)
{
// Get parameter length.
paramLen = strlen(parameter);
// Get the position of the next parameter by finding the next space.
nextPos = StrContains(rawString[splitPos], " ");
// Check if the next parameter was found.
if (nextPos >= 0)
{
// Calculate value starting position.
valuePos = paramPos + paramLen + 1;
// Calculate value length. Note: Adding 1 for space to the null
// terminator.
valueLen = nextPos + splitPos - valuePos + 1;
// Check if value length is longer than buffer size.
if (valueLen > maxlen)
{
valueLen = maxlen;
}
// Copy value to buffer.
return strcopy(buffer, valueLen, rawString[valuePos]);
}
else
{
// It's the last or only parameter, get the rest of the string.
return strcopy(buffer, maxlen, rawString[paramPos + paramLen + 1]);
}
}
else
{
return -1;
}
}
/**
* Gets the name of the parameter at the specified index.
*
* @param buffer Destination string bufffer.
* @param maxlen Length of destination buffer.
* @param rawString Source string to read from.
* @param parameterIndex The zero-based parameter index to read.
*
* @return Number of cells written. -1 if failed.
*/
stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parameterIndex)
{
new paramPos;
new valuePos;
new nextValuePos;
new splitPos;
// Check if the raw string is empty.
if (strlen(rawString) == 0)
{
return -1;
}
if (parameterIndex > 0)
{
// Get the value starting position for the previous index.
for (new index = 0; index < parameterIndex - 1; index++)
{
valuePos = StrContains(rawString[splitPos], "=");
splitPos += valuePos;
}
// Find the next space from splitPos where the specified parameter
// starts.
paramPos = StrContains(rawString[splitPos], " ") + splitPos + 1;
// Update split position.
splitPos += paramPos;
// Find the next value position from splitPos to get the end position
// of the parameter name.
nextValuePos = StrContains(rawString[splitPos], "=") + splitPos;
// Check if a value is specified.
if (nextValuePos > 0)
{
// Return the parameter name between paramPos and nextValuePos.
return strcopy(buffer, nextValuePos - paramPos + 1, rawString[paramPos]); // + 1 to include null terminator.
}
else
{
// No value specified. Return the rest of rawString from paramPos.
return strcopy(buffer, maxlen, rawString[paramPos]);
}
}
else
{
// It's the first parameter. Read the string until '=' is found.
valuePos = StrContains(rawString, "=");
// Check if a value is specified.
if (valuePos > 0)
{
// Return the parameter name.
return strcopy(buffer, valuePos + 1, rawString); // + 1 to include null terminator.
}
else
{
// No value specified, return the entire raw string.
return strcopy(buffer, maxlen, rawString);
}
}
}