diff --git a/core/smn_keyvalues.cpp b/core/smn_keyvalues.cpp index 5da08c76..5fa49582 100644 --- a/core/smn_keyvalues.cpp +++ b/core/smn_keyvalues.cpp @@ -797,6 +797,32 @@ static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params) return g_HL2.KVLoadFromFile(kv, basefilesystem, path); } +static cell_t smn_StringToKeyValues(IPluginContext *pCtx, const cell_t *params) +{ + Handle_t hndl = static_cast(params[1]); + HandleError herr; + HandleSecurity sec; + KeyValueStack *pStk; + KeyValues *kv; + + sec.pOwner = NULL; + sec.pIdentity = g_pCoreIdent; + + if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk)) + != HandleError_None) + { + return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr); + } + + char *buffer; + char *resourceName; + pCtx->LocalToString(params[2], &buffer); + pCtx->LocalToString(params[3], &resourceName); + + kv = pStk->pCurRoot.front(); + return kv->LoadFromBuffer(resourceName, buffer); +} + static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params) { Handle_t hndl = static_cast(params[1]); @@ -1101,6 +1127,7 @@ REGISTER_NATIVES(keyvaluenatives) {"KvGetDataType", smn_KvGetDataType}, {"KeyValuesToFile", smn_KeyValuesToFile}, {"FileToKeyValues", smn_FileToKeyValues}, + {"StringToKeyValues", smn_StringToKeyValues}, {"KvSetEscapeSequences", smn_KvSetEscapeSequences}, {"KvDeleteThis", smn_KvDeleteThis}, {"KvDeleteKey", smn_KvDeleteKey}, @@ -1113,4 +1140,4 @@ REGISTER_NATIVES(keyvaluenatives) {"KvGetVector", smn_KvGetVector}, {"KvSetVector", smn_KvSetVector}, {NULL, NULL} -}; +}; \ No newline at end of file diff --git a/plugins/include/keyvalues.inc b/plugins/include/keyvalues.inc index c607d7d3..d293ecae 100644 --- a/plugins/include/keyvalues.inc +++ b/plugins/include/keyvalues.inc @@ -360,6 +360,18 @@ native bool:KeyValuesToFile(Handle:kv, const String:file[]); */ native bool:FileToKeyValues(Handle:kv, const String:file[]); +/** + * Converts a given string to a KeyValues tree. The string is read into + * the current postion of the tree. + * + * @param kv KeyValues Handle. + * @param buffer String buffer to load into the KeyValues. + * @param resourceName The resource name of the KeyValues, used for error tracking purposes. + * @return True on success, false otherwise. + * @error Invalid Handle. + */ +native bool:StringToKeyValues(Handle:kv, const String:buffer[], const String:resourceName[]="StringToKeyValues"); + /** * Sets whether or not the KeyValues parser will read escape sequences. * For example, \n would be read as a literal newline. This defaults diff --git a/plugins/testsuite/keyvalues.sp b/plugins/testsuite/keyvalues.sp new file mode 100644 index 00000000..bef02fe7 --- /dev/null +++ b/plugins/testsuite/keyvalues.sp @@ -0,0 +1,58 @@ + +#include + +public Plugin:myinfo = +{ + name = "KeyValues test", + author = "AlliedModders LLC", + description = "KeyValues test", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + + +public OnPluginStart() +{ + RegServerCmd("test_keyvalues", RunTests); +} + +public Action:RunTests(argc) +{ + new String:validKv[] = + "\"root\" \ + { \ + \"child\" \"value\" \ + \"subkey\" { \ + subchild subvalue \ + subfloat 1.0 \ + } \ + }"; + + new Handle:kv = CreateKeyValues(""); + + if (!StringToKeyValues(kv, validKv)) + ThrowError("Valid kv not read correctly!"); + + decl String:value[128]; + KvGetString(kv, "child", value, sizeof(value)); + + if (!StrEqual(value, "value")) + ThrowError("Child kv should have 'value' but has: '%s'", value); + + if (!KvJumpToKey(kv, "subkey")) + ThrowError("No sub kv subkey exists!"); + + KvGetString(kv, "subchild", value, sizeof(value)); + + if (!StrEqual(value, "subvalue")) + ThrowError("Subkv subvalue should have 'subvalue' but has: '%s'", value); + + new Float:subfloat = KvGetFloat(kv, "subfloat"); + + if (subfloat != 1.0) + ThrowError( "Subkv subfloat should have 1.0 but has: %f", subfloat) + + CloseHandle(kv); + + PrintToServer("KeyValue tests passed!"); +} diff --git a/tools/buildbot/PackageScript b/tools/buildbot/PackageScript index ae2396c5..59da49fe 100644 --- a/tools/buildbot/PackageScript +++ b/tools/buildbot/PackageScript @@ -413,6 +413,7 @@ CopyFiles('plugins/testsuite', 'addons/sourcemod/scripting/testsuite', 'structtest.sp', 'tf2-test.sp', 'tries.sp', + 'keyvalues.sp', ] ) CopyFiles('plugins/basecommands', 'addons/sourcemod/scripting/basecommands',