diff --git a/core/smn_keyvalues.cpp b/core/smn_keyvalues.cpp index 5fa49582..a3b997c5 100644 --- a/core/smn_keyvalues.cpp +++ b/core/smn_keyvalues.cpp @@ -1101,6 +1101,18 @@ static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params) return 1; } +static cell_t KeyValues_Import(IPluginContext *pContext, const cell_t *params) +{ + // This version takes (dest, src). The original is (src, dest). + cell_t new_params[3] = { + 2, + params[2], + params[1], + }; + + return smn_CopySubkeys(pContext, new_params); +} + static KeyValueNatives s_KeyValueNatives; REGISTER_NATIVES(keyvaluenatives) @@ -1139,5 +1151,42 @@ REGISTER_NATIVES(keyvaluenatives) {"KvGetSectionSymbol", smn_KvGetSectionSymbol}, {"KvGetVector", smn_KvGetVector}, {"KvSetVector", smn_KvSetVector}, + + // Transitional syntax support. + {"KeyValues.KeyValues", smn_CreateKeyValues}, + {"KeyValues.SetString", smn_KvSetString}, + {"KeyValues.SetNum", smn_KvSetNum}, + {"KeyValues.SetUInt64", smn_KvSetUInt64}, + {"KeyValues.SetFloat", smn_KvSetFloat}, + {"KeyValues.SetColor", smn_KvSetColor}, + {"KeyValues.GetString", smn_KvGetString}, + {"KeyValues.GetNum", smn_KvGetNum}, + {"KeyValues.GetFloat", smn_KvGetFloat}, + {"KeyValues.GetColor", smn_KvGetColor}, + {"KeyValues.GetUInt64", smn_KvGetUInt64}, + {"KeyValues.JumpToKey", smn_KvJumpToKey}, + {"KeyValues.JumpToKeySymbol", smn_KvJumpToKeySymbol}, + {"KeyValues.GotoNextKey", smn_KvGotoNextKey}, + {"KeyValues.GotoFirstSubKey", smn_KvGotoFirstSubKey}, + {"KeyValues.GoBack", smn_KvGoBack}, + {"KeyValues.Rewind", smn_KvRewind}, + {"KeyValues.GetSectionName", smn_KvGetSectionName}, + {"KeyValues.SetSectionName", smn_KvSetSectionName}, + {"KeyValues.GetDataType", smn_KvGetDataType}, + {"KeyValues.SetEscapeSequences", smn_KvSetEscapeSequences}, + {"KeyValues.DeleteThis", smn_KvDeleteThis}, + {"KeyValues.DeleteKey", smn_KvDeleteKey}, + {"KeyValues.NodesInStack", smn_KvNodesInStack}, + {"KeyValues.SavePosition", smn_KvSavePosition}, + {"KeyValues.FindKeyById", smn_FindKeyById}, + {"KeyValues.GetNameSymbol", smn_GetNameSymbol}, + {"KeyValues.GetSectionSymbol", smn_KvGetSectionSymbol}, + {"KeyValues.GetVector", smn_KvGetVector}, + {"KeyValues.SetVector", smn_KvSetVector}, + {"KeyValues.Import", KeyValues_Import}, + {"KeyValues.ImportFromFile", smn_FileToKeyValues}, + {"KeyValues.ImportFromString", smn_StringToKeyValues}, + {"KeyValues.ExportToFile", smn_KeyValuesToFile}, + {NULL, NULL} -}; \ No newline at end of file +}; diff --git a/plugins/adminmenu/dynamicmenu.sp b/plugins/adminmenu/dynamicmenu.sp index 27a7698b..594b046c 100644 --- a/plugins/adminmenu/dynamicmenu.sp +++ b/plugins/adminmenu/dynamicmenu.sp @@ -74,16 +74,15 @@ new Handle:g_DataArray; BuildDynamicMenu() { - new itemInput[Item]; + int itemInput[Item]; g_DataArray = CreateArray(sizeof(itemInput)); - new String:executeBuffer[32]; + char executeBuffer[32]; - new Handle:kvMenu; - kvMenu = CreateKeyValues("Commands"); - KvSetEscapeSequences(kvMenu, true); + KeyValues kvMenu = KeyValues("Commands"); + kvMenu.SetEscapeSequences(true); - new String:file[256]; + char file[256]; /* As a compatibility shim, we use the old file if it exists. */ BuildPath(Path_SM, file, 255, "configs/dynamicmenu/menu.ini"); @@ -102,10 +101,8 @@ BuildDynamicMenu() new String:name[NAME_LENGTH]; new String:buffer[NAME_LENGTH]; - if (!KvGotoFirstSubKey(kvMenu)) - { + if (!kvMenu.GotoFirstSubKey()) return; - } decl String:admin[30]; @@ -113,9 +110,9 @@ BuildDynamicMenu() do { - KvGetSectionName(kvMenu, buffer, sizeof(buffer)); + kvMenu.GetSectionName(buffer, sizeof(buffer)); - KvGetString(kvMenu, "admin", admin, sizeof(admin),"sm_admin"); + kvMenu.GetString("admin", admin, sizeof(admin),"sm_admin"); if ((categoryId = hAdminMenu.FindCategory(buffer)) == INVALID_TOPMENUOBJECT) { @@ -130,16 +127,16 @@ BuildDynamicMenu() decl String:category_name[NAME_LENGTH]; strcopy(category_name, sizeof(category_name), buffer); - if (!KvGotoFirstSubKey(kvMenu)) + if (!kvMenu.GotoFirstSubKey()) { return; } do { - KvGetSectionName(kvMenu, buffer, sizeof(buffer)); + kvMenu.GetSectionName(buffer, sizeof(buffer)); - KvGetString(kvMenu, "admin", admin, sizeof(admin),""); + kvMenu.GetString("admin", admin, sizeof(admin),""); if (admin[0] == '\0') { @@ -147,14 +144,14 @@ BuildDynamicMenu() //Use the first argument of the 'cmd' string instead decl String:temp[64]; - KvGetString(kvMenu, "cmd", temp, sizeof(temp),""); + kvMenu.GetString("cmd", temp, sizeof(temp),""); BreakString(temp, admin, sizeof(admin)); } - KvGetString(kvMenu, "cmd", itemInput[Item_cmd], sizeof(itemInput[Item_cmd])); - KvGetString(kvMenu, "execute", executeBuffer, sizeof(executeBuffer)); + kvMenu.GetString("cmd", itemInput[Item_cmd], sizeof(itemInput[Item_cmd])); + kvMenu.GetString("execute", executeBuffer, sizeof(executeBuffer)); if (StrEqual(executeBuffer, "server")) { @@ -172,7 +169,7 @@ BuildDynamicMenu() decl String:inputBuffer[48]; - while (KvJumpToKey(kvMenu, countBuffer)) + while (kvMenu.JumpToKey(countBuffer)) { new submenuInput[Submenu]; @@ -181,7 +178,7 @@ BuildDynamicMenu() itemInput[Item_submenus] = CreateArray(sizeof(submenuInput)); } - KvGetString(kvMenu, "type", inputBuffer, sizeof(inputBuffer)); + kvMenu.GetString("type", inputBuffer, sizeof(inputBuffer)); if (strncmp(inputBuffer,"group",5)==0) { @@ -198,7 +195,7 @@ BuildDynamicMenu() { submenuInput[Submenu_type] = SubMenu_MapCycle; - KvGetString(kvMenu, "path", inputBuffer, sizeof(inputBuffer),"mapcycle.txt"); + kvMenu.GetString("path", inputBuffer, sizeof(inputBuffer),"mapcycle.txt"); submenuInput[Submenu_listdata] = CreateDataPack(); WritePackString(submenuInput[Submenu_listdata], inputBuffer); @@ -230,13 +227,13 @@ BuildDynamicMenu() do { Format(temp,3,"%i",i); - KvGetString(kvMenu, temp, value, sizeof(value), ""); + kvMenu.GetString(temp, value, sizeof(value), ""); Format(temp,5,"%i.",i); - KvGetString(kvMenu, temp, text, sizeof(text), value); + kvMenu.GetString(temp, text, sizeof(text), value); Format(temp,5,"%i*",i); - KvGetString(kvMenu, temp, subadm, sizeof(subadm),""); + kvMenu.GetString(temp, subadm, sizeof(subadm),""); if (value[0]=='\0') { @@ -260,7 +257,7 @@ BuildDynamicMenu() if ((submenuInput[Submenu_type] == SubMenu_Player) || (submenuInput[Submenu_type] == SubMenu_GroupPlayer)) { - KvGetString(kvMenu, "method", inputBuffer, sizeof(inputBuffer)); + kvMenu.GetString("method", inputBuffer, sizeof(inputBuffer)); if (StrEqual(inputBuffer, "clientid")) { @@ -288,7 +285,7 @@ BuildDynamicMenu() } } - KvGetString(kvMenu, "title", inputBuffer, sizeof(inputBuffer)); + kvMenu.GetString("title", inputBuffer, sizeof(inputBuffer)); strcopy(submenuInput[Submenu_title], sizeof(submenuInput[Submenu_title]), inputBuffer); count++; @@ -296,7 +293,7 @@ BuildDynamicMenu() PushArrayArray(itemInput[Item_submenus], submenuInput[0]); - KvGoBack(kvMenu); + kvMenu.GoBack(); } /* Save this entire item into the global items array and add it to the menu */ @@ -316,13 +313,13 @@ BuildDynamicMenu() LogError("Duplicate command name \"%s\" in adminmenu_custom.txt category \"%s\"", buffer, category_name); } - } while (KvGotoNextKey(kvMenu)); + } while (kvMenu.GotoNextKey()); - KvGoBack(kvMenu); + kvMenu.GoBack(); - } while (KvGotoNextKey(kvMenu)); + } while (kvMenu.GotoNextKey()); - CloseHandle(kvMenu); + delete kvMenu; } ParseConfigs() diff --git a/plugins/basebans.sp b/plugins/basebans.sp index a1087aa4..38d354d4 100644 --- a/plugins/basebans.sp +++ b/plugins/basebans.sp @@ -53,7 +53,7 @@ new g_BanTargetUserId[MAXPLAYERS+1]; new g_BanTime[MAXPLAYERS+1]; new g_IsWaitingForChatReason[MAXPLAYERS+1]; -new Handle:g_hKvBanReasons; +KeyValues g_hKvBanReasons; new String:g_BanReasonsPath[PLATFORM_MAX_PATH]; #include "basebans/ban.sp" @@ -84,15 +84,6 @@ public OnPluginStart() } } -public OnPluginEnd() -{ - //Close kv-handle - if(g_hKvBanReasons != INVALID_HANDLE) - { - CloseHandle(g_hKvBanReasons); - } -} - public OnMapStart() { //(Re-)Load BanReasons @@ -106,30 +97,27 @@ public OnClientDisconnect(client) LoadBanReasons() { - if (g_hKvBanReasons != INVALID_HANDLE) - { - CloseHandle(g_hKvBanReasons); - } + delete g_hKvBanReasons; - g_hKvBanReasons = CreateKeyValues("banreasons"); + g_hKvBanReasons = KeyValues("banreasons"); - if(FileToKeyValues(g_hKvBanReasons, g_BanReasonsPath)) + if (g_hKvBanReasons.ImportFromFile(g_BanReasonsPath)) { - decl String:sectionName[255]; - if(!KvGetSectionName(g_hKvBanReasons, sectionName, sizeof(sectionName))) + char sectionName[255]; + if (!g_hKvBanReasons.GetSectionName(sectionName, sizeof(sectionName))) { SetFailState("Error in %s: File corrupt or in the wrong format", g_BanReasonsPath); return; } - if(strcmp(sectionName, "banreasons") != 0) + if (strcmp(sectionName, "banreasons") != 0) { SetFailState("Error in %s: Couldn't find 'banreasons'", g_BanReasonsPath); return; } //Reset kvHandle - KvRewind(g_hKvBanReasons); + g_hKvBanReasons.Rewind(); } else { SetFailState("Error in %s: File not found, corrupt or in the wrong format", g_BanReasonsPath); return; diff --git a/plugins/basebans/ban.sp b/plugins/basebans/ban.sp index e0522f4e..86f9bec8 100644 --- a/plugins/basebans/ban.sp +++ b/plugins/basebans/ban.sp @@ -132,19 +132,19 @@ DisplayBanReasonMenu(client) decl String:reasonFull[255]; //Iterate through the kv-file - KvGotoFirstSubKey(g_hKvBanReasons, false); + g_hKvBanReasons.GotoFirstSubKey(false); do { - KvGetSectionName(g_hKvBanReasons, reasonName, sizeof(reasonName)); - KvGetString(g_hKvBanReasons, NULL_STRING, reasonFull, sizeof(reasonFull)); + g_hKvBanReasons.GetSectionName(reasonName, sizeof(reasonName)); + g_hKvBanReasons.GetString(NULL_STRING, reasonFull, sizeof(reasonFull)); //Add entry AddMenuItem(menu, reasonFull, reasonName); - } while (KvGotoNextKey(g_hKvBanReasons, false)); + } while (g_hKvBanReasons.GotoNextKey(false)); //Reset kvHandle - KvRewind(g_hKvBanReasons); + g_hKvBanReasons.Rewind(); DisplayMenu(menu, client, MENU_TIME_FOREVER); } diff --git a/plugins/basechat.sp b/plugins/basechat.sp index 983d7da8..d359bfaf 100644 --- a/plugins/basechat.sp +++ b/plugins/basechat.sp @@ -368,14 +368,14 @@ SendDialogToOne(client, color, const String:text[], any:...) new String:message[100]; VFormat(message, sizeof(message), text, 4); - new Handle:kv = CreateKeyValues("Stuff", "title", message); - KvSetColor(kv, "color", g_Colors[color][0], g_Colors[color][1], g_Colors[color][2], 255); - KvSetNum(kv, "level", 1); - KvSetNum(kv, "time", 10); + KeyValues kv = KeyValues("Stuff", "title", message); + kv.SetColor("color", g_Colors[color][0], g_Colors[color][1], g_Colors[color][2], 255); + kv.SetNum("level", 1); + kv.SetNum("time", 10); CreateDialog(client, kv, DialogType_Msg); - - CloseHandle(kv); + + delete kv; } SendPrivateChat(client, target, const String:message[]) diff --git a/plugins/include/halflife.inc b/plugins/include/halflife.inc index b0d2b464..6df545df 100644 --- a/plugins/include/halflife.inc +++ b/plugins/include/halflife.inc @@ -568,15 +568,15 @@ native ShowHudText(client, channel, const String:message[], any:...); */ stock ShowMOTDPanel(client, const String:title[], const String:msg[], type=MOTDPANEL_TYPE_INDEX) { - decl String:num[3]; - new Handle:Kv = CreateKeyValues("data"); + char num[3]; IntToString(type, num, sizeof(num)); - KvSetString(Kv, "title", title); - KvSetString(Kv, "type", num); - KvSetString(Kv, "msg", msg); - ShowVGUIPanel(client, "info", Kv); - CloseHandle(Kv); + KeyValues kv = KeyValues("data"); + kv.SetString("title", title); + kv.SetString("type", num); + kv.SetString("msg", msg); + ShowVGUIPanel(client, "info", kv); + delete kv; } /** @@ -590,13 +590,14 @@ stock ShowMOTDPanel(client, const String:title[], const String:msg[], type=MOTDP */ stock DisplayAskConnectBox(client, Float:time, const String:ip[], const String:password[] = "") { - decl String:destination[288]; + char destination[288]; FormatEx(destination, sizeof(destination), "%s/%s", ip, password); - new Handle:Kv = CreateKeyValues("data"); - KvSetFloat(Kv, "time", time); - KvSetString(Kv, "title", destination); - CreateDialog(client, Kv, DialogType_AskConnect); - CloseHandle(Kv); + + KeyValues kv = KeyValues("data"); + kv.SetFloat("time", time); + kv.SetString("title", destination); + CreateDialog(client, kv, DialogType_AskConnect); + delete kv; } /** diff --git a/plugins/include/keyvalues.inc b/plugins/include/keyvalues.inc index d293ecae..15fe5832 100644 --- a/plugins/include/keyvalues.inc +++ b/plugins/include/keyvalues.inc @@ -1,7 +1,7 @@ /** - * vim: set ts=4 : + * vim: set ts=4 sw=4 tw=99 noet : * ============================================================================= - * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * SourceMod (C)2004-2014 AlliedModders LLC. All rights reserved. * ============================================================================= * * This file is part of the SourceMod/SourcePawn SDK. @@ -52,6 +52,275 @@ enum KvDataTypes KvData_NUMTYPES, }; +methodmap KeyValues < Handle +{ + // Creates a new KeyValues structure. The Handle must be closed with + // CloseHandle() or delete. + // + // @param name Name of the root section. + // @param firstKey If non-empty, specifies the first key value. + // @param firstValue If firstKey is non-empty, specifies the first key's value. + public native KeyValues(const char[] name, const char[] firstKey="", const char[] firstValue=""); + + // Exports a KeyValues tree to a file. The tree is dumped from the current position. + // + // @param file File to dump write to. + // @return True on success, false otherwise. + public native bool ExportToFile(const char[] file); + + // Imports a file in KeyValues format. The file is read into the current + // position of the tree. + // + // @param file File to read from. + // @return True on success, false otherwise. + public native bool ImportFromFile(const char[] file); + + // Converts a given string to a KeyValues tree. The string is read into + // the current postion of the tree. + // + // @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. + public native bool ImportFromString(const char[] buffer, const char[] resourceName="StringToKeyValues"); + + // Imports subkeys in the given KeyValues, at the current position in that + // KeyValues, into the current position in this KeyValues. Note that this + // copies keys; it does not embed a reference to them. + // + // @param other Origin KeyValues Handle. + public native void Import(KeyValues other); + + // Sets a string value of a KeyValues key. + // + // @param kv KeyValues Handle. + // @param key Name of the key, or NULL_STRING. + // @param value String value. + public native void SetString(const char[] key, const char[] value); + + // Sets an integer value of a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param value Value number. + public native void SetNum(const char[] key, int value); + + // Sets a large integer value of a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param value Large integer value (0=High bits, 1=Low bits) + public native void SetUInt64(const char[] key, const value[2]); + + // Sets a floating point value of a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param value Floating point value. + public native void SetFloat(const char[] key, float value); + + // Sets a set of color values of a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param r Red value. + // @param g Green value. + // @param b Blue value. + // @param a Alpha value. + public native void SetColor(const char[] key, int r, int g, int b, int a=0); + + // Sets a set of color values of a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param color Red, green, blue and alpha channels. + public void SetColor4(const char[] key, const int color[4]) { + this.SetColor(key, color[0], color[1], color[2], color[3]); + } + + // Sets a vector value of a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param vec Vector value. + public native void SetVector(const char[] key, const float vec[3]); + + // Retrieves a string value from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param value Buffer to store key value in. + // @param maxlength Maximum length of the value buffer. + // @param defvalue Optional default value to use if the key is not found. + public native void GetString(const char[] key, char[] value, int maxlength, const char[] defvalue=""); + + // Retrieves an integer value from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param defvalue Optional default value to use if the key is not found. + // @return Integer value of the key. + public native int GetNum(const char[] key, int defvalue=0); + + // Retrieves a floating point value from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param defvalue Optional default value to use if the key is not found. + // @return Floating point value of the key. + public native float GetFloat(const char[] key, float defvalue=0.0); + + // Retrieves a set of color values from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param r Red value, set by reference. + // @param g Green value, set by reference. + // @param b Blue value, set by reference. + // @param a Alpha value, set by reference. + public native void GetColor(const char[] key, &r, &g, &b, &a); + + // Retrives a set of color values from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param color Red, green, blue, and alpha channels. + public void GetColor4(const char[] key, int color[4]) { + int r, g, b, a; + this.GetColor(key, r, g, b, a); + color[0] = r; + color[1] = g; + color[2] = b; + color[3] = a; + } + + // Retrieves a large integer value from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param value Array to represent the large integer. + // @param defvalue Optional default value to use if the key is not found. + public native void GetUInt64(const char[] key, int value[2], int defvalue[2]={0,0}); + + // Retrieves a vector value from a KeyValues key. + // + // @param key Name of the key, or NULL_STRING. + // @param vec Destination vector to store the value in. + // @param defvalue Optional default value to use if the key is not found. + public native void GetVector(const char[] key, float vec[3], const float defvalue[3]={0.0, 0.0, 0.0}); + + // Sets the current position in the KeyValues tree to the given key. + // + // @param key Name of the key. + // @param create If true, and the key does not exist, it will be created. + // @return True if the key exists, false if it does not and was not created. + public native bool JumpToKey(const char[] key, bool create=false); + + // Sets the current position in the KeyValues tree to the given key. + // + // @param id KeyValues id. + // @return True if the key exists, false if it does not. + public native bool JumpToKeySymbol(int id); + + // Sets the current position in the KeyValues tree to the first sub key. + // This native adds to the internal traversal stack. + // + // @param keyOnly If false, non-keys will be traversed (values). + // @return True on success, false if there was no first sub key. + public native bool GotoFirstSubKey(bool keyOnly=true); + + // Sets the current position in the KeyValues tree to the next sub key. + // This native does NOT add to the internal traversal stack, and thus + // GoBack() is not needed for each successive call to this function. + // + // @param keyOnly If false, non-keys will be traversed (values). + // @return True on success, false if there was no next sub key. + public native bool GotoNextKey(bool keyOnly=true); + + // Saves the current position in the traversal stack onto the traversal + // stack. This can be useful if you wish to use KvGotoNextKey() and + // have the previous key saved for backwards traversal. + // + // @param kv KeyValues Handle. + public native void SavePosition(); + + // Jumps back to the previous position. Returns false if there are no + // previous positions (i.e., at the root node). This should be called + // once for each successful Jump call, in order to return to the top node. + // This function pops one node off the internal traversal stack. + // + // @return True on success, false if there is no higher node. + public native bool GoBack(); + + // Removes the given key from the current position. + // + // @param key Name of the key. + // @return True on success, false if key did not exist. + public native bool DeleteKey(const char[] key); + + // Removes the current sub-key and attempts to set the position + // to the sub-key after the removed one. If no such sub-key exists, + // the position will be the parent key in the traversal stack. + // Given the sub-key having position "N" in the traversal stack, the + // removal will always take place from position "N-1." + // + // @param kv KeyValues Handle. + // @return 1 if removal succeeded and there was another key. + // 0 if the current node was not contained in the + // previous node, or no previous node exists. + // -1 if removal succeeded and there were no more keys, + // thus the state is as if KvGoBack() was called. + public native int DeleteThis(); + + // Sets the position back to the top node, emptying the entire node + // traversal history. This can be used instead of looping KvGoBack() + // if recursive iteration is not important. + // + // @param kv KeyValues Handle. + public native void Rewind(); + + // Retrieves the current section name. + // + // @param section Buffer to store the section name. + // @param maxlength Maximum length of the name buffer. + // @return True on success, false on failure. + public native bool GetSectionName(char[] section, int maxlength); + + // Sets the current section name. + // + // @param section Section name. + public native void SetSectionName(const char[] section); + + // Returns the data type at a key. + // + // @param key Key name. + // @return KvDataType value of the key. + public native KvDataTypes GetDataType(const char[] key); + + // Sets whether or not the KeyValues parser will read escape sequences. + // For example, \n would be read as a literal newline. This defaults + // to false for new KeyValues structures. + // + // @param useEscapes Whether or not to read escape sequences. + public native void SetEscapeSequences(bool useEscapes); + + // Returns the position in the jump stack; I.e. the number of calls + // required for KvGoBack to return to the root node. If at the root node, + // 0 is returned. + // + // @return Number of non-root nodes in the jump stack. + public native int NodesInStack(); + + // Finds a KeyValues name by id. + // + // @param id KeyValues id. + // @param name Buffer to store the name. + // @param maxlength Maximum length of the value buffer. + // @return True on success, false if id not found. + public native bool FindKeyById(int id, char[] name, int maxlength); + + // Finds a KeyValues id inside a KeyValues tree. + // + // @param key Key name. + // @param id Id of the found KeyValue. + // @return True on success, false if key not found. + public native bool GetNameSymbol(const char[] key, int &id); + + // Retrieves the current section id. + // + // @param kv KeyValues Handle. + // @param id Id of the current section. + // @return True on success, false on failure. + public native bool GetSectionSymbol(int &id); +}; + /** * Creates a new KeyValues structure. The Handle must always be closed. * @@ -60,7 +329,7 @@ enum KvDataTypes * @param firstValue If firstKey is non-empty, specifies the first key's value. * @return A Handle to a new KeyValues structure. */ -native Handle:CreateKeyValues(const String:name[], const String:firstKey[]="", const String:firstValue[]=""); +native KeyValues CreateKeyValues(const char[] name, const char[] firstKey="", const char[] firstValue=""); /** * Sets a string value of a KeyValues key. @@ -68,10 +337,9 @@ native Handle:CreateKeyValues(const String:name[], const String:firstKey[]="", c * @param kv KeyValues Handle. * @param key Name of the key, or NULL_STRING. * @param value String value. - * @noreturn * @error Invalid Handle. */ -native KvSetString(Handle:kv, const String:key[], const String:value[]); +native void KvSetString(Handle kv, const char[] key, const char[] value); /** * Sets an integer value of a KeyValues key. @@ -79,10 +347,9 @@ native KvSetString(Handle:kv, const String:key[], const String:value[]); * @param kv KeyValues Handle. * @param key Name of the key, or NULL_STRING. * @param value Value number. - * @noreturn * @error Invalid Handle. */ -native KvSetNum(Handle:kv, const String:key[], value); +native void KvSetNum(Handle kv, const char[] key, int value); /** * Sets a large integer value of a KeyValues key. @@ -90,10 +357,9 @@ native KvSetNum(Handle:kv, const String:key[], value); * @param kv KeyValues Handle. * @param key Name of the key, or NULL_STRING. * @param value Large integer value (0=High bits, 1=Low bits) - * @noreturn * @error Invalid Handle. */ -native KvSetUInt64(Handle:kv, const String:key[], const value[2]); +native void KvSetUInt64(Handle kv, const char[] key, const value[2]); /** * Sets a floating point value of a KeyValues key. @@ -101,10 +367,9 @@ native KvSetUInt64(Handle:kv, const String:key[], const value[2]); * @param kv KeyValues Handle. * @param key Name of the key, or NULL_STRING. * @param value Floating point value. - * @noreturn * @error Invalid Handle. */ -native KvSetFloat(Handle:kv, const String:key[], Float:value); +native void KvSetFloat(Handle kv, const char[] key, float value); /** * Sets a set of color values of a KeyValues key. @@ -115,10 +380,9 @@ native KvSetFloat(Handle:kv, const String:key[], Float:value); * @param g Green value. * @param b Blue value. * @param a Alpha value. - * @noreturn * @error Invalid Handle. */ -native KvSetColor(Handle:kv, const String:key[], r, g, b, a=0); +native void KvSetColor(Handle kv, const char[] key, int r, int g, int b, int a=0); /** * Sets a vector value of a KeyValues key. @@ -126,10 +390,9 @@ native KvSetColor(Handle:kv, const String:key[], r, g, b, a=0); * @param kv KeyValues Handle. * @param key Name of the key, or NULL_STRING. * @param vec Vector value. - * @noreturn * @error Invalid Handle. */ -native KvSetVector(Handle:kv, const String:key[], const Float:vec[3]); +native void KvSetVector(Handle kv, const char[] key, const float vec[3]); /** * Retrieves a string value from a KeyValues key. @@ -139,10 +402,9 @@ native KvSetVector(Handle:kv, const String:key[], const Float:vec[3]); * @param value Buffer to store key value in. * @param maxlength Maximum length of the value buffer. * @param defvalue Optional default value to use if the key is not found. - * @noreturn * @error Invalid Handle. */ -native KvGetString(Handle:kv, const String:key[], String:value[], maxlength, const String:defvalue[]=""); +native void KvGetString(Handle kv, const char[] key, char[] value, int maxlength, const char[] defvalue=""); /** * Retrieves an integer value from a KeyValues key. @@ -153,7 +415,7 @@ native KvGetString(Handle:kv, const String:key[], String:value[], maxlength, con * @return Integer value of the key. * @error Invalid Handle. */ -native KvGetNum(Handle:kv, const String:key[], defvalue=0); +native int KvGetNum(Handle kv, const char[] key, int defvalue=0); /** * Retrieves a floating point value from a KeyValues key. @@ -164,7 +426,7 @@ native KvGetNum(Handle:kv, const String:key[], defvalue=0); * @return Floating point value of the key. * @error Invalid Handle. */ -native Float:KvGetFloat(Handle:kv, const String:key[], Float:defvalue=0.0); +native float KvGetFloat(Handle kv, const char[] key, float defvalue=0.0); /** * Retrieves a set of color values from a KeyValues key. @@ -175,10 +437,9 @@ native Float:KvGetFloat(Handle:kv, const String:key[], Float:defvalue=0.0); * @param g Green value, set by reference. * @param b Blue value, set by reference. * @param a Alpha value, set by reference. - * @noreturn * @error Invalid Handle. */ -native KvGetColor(Handle:kv, const String:key[], &r, &g, &b, &a); +native void KvGetColor(Handle kv, const char[] key, int &r, int &g, int &b, int &a); /** * Retrieves a large integer value from a KeyValues key. @@ -187,10 +448,9 @@ native KvGetColor(Handle:kv, const String:key[], &r, &g, &b, &a); * @param key Name of the key, or NULL_STRING. * @param value Array to represent the large integer. * @param defvalue Optional default value to use if the key is not found. - * @noreturn * @error Invalid Handle. */ -native KvGetUInt64(Handle:kv, const String:key[], value[2], defvalue[2]={0,0}); +native void KvGetUInt64(Handle kv, const char[] key, int value[2], int defvalue[2]={0,0}); /** * Retrieves a vector value from a KeyValues key. @@ -199,10 +459,9 @@ native KvGetUInt64(Handle:kv, const String:key[], value[2], defvalue[2]={0,0}); * @param key Name of the key, or NULL_STRING. * @param vec Destination vector to store the value in. * @param defvalue Optional default value to use if the key is not found. - * @noreturn * @error Invalid Handle. */ -native KvGetVector(Handle:kv, const String:key[], Float:vec[3], const Float:defvalue[3]={0.0, 0.0, 0.0}); +native void KvGetVector(Handle kv, const char[] key, float vec[3], const float defvalue[3]={0.0, 0.0, 0.0}); /** * Sets the current position in the KeyValues tree to the given key. @@ -212,7 +471,7 @@ native KvGetVector(Handle:kv, const String:key[], Float:vec[3], const Float:defv * @param create If true, and the key does not exist, it will be created. * @return True if the key exists, false if it does not and was not created. */ -native bool:KvJumpToKey(Handle:kv, const String:key[], bool:create=false); +native bool KvJumpToKey(Handle kv, const char[] key, bool create=false); /** * Sets the current position in the KeyValues tree to the given key. @@ -221,7 +480,7 @@ native bool:KvJumpToKey(Handle:kv, const String:key[], bool:create=false); * @param id KeyValues id. * @return True if the key exists, false if it does not. */ -native bool:KvJumpToKeySymbol(Handle:kv, id); +native bool KvJumpToKeySymbol(Handle kv, int id); /** * Sets the current position in the KeyValues tree to the first sub key. @@ -232,7 +491,7 @@ native bool:KvJumpToKeySymbol(Handle:kv, id); * @return True on success, false if there was no first sub key. * @error Invalid Handle. */ -native bool:KvGotoFirstSubKey(Handle:kv, bool:keyOnly=true); +native bool KvGotoFirstSubKey(Handle kv, bool keyOnly=true); /** * Sets the current position in the KeyValues tree to the next sub key. @@ -244,7 +503,7 @@ native bool:KvGotoFirstSubKey(Handle:kv, bool:keyOnly=true); * @return True on success, false if there was no next sub key. * @error Invalid Handle. */ -native bool:KvGotoNextKey(Handle:kv, bool:keyOnly=true); +native bool KvGotoNextKey(Handle kv, bool keyOnly=true); /** * Saves the current position in the traversal stack onto the traversal @@ -252,10 +511,9 @@ native bool:KvGotoNextKey(Handle:kv, bool:keyOnly=true); * have the previous key saved for backwards traversal. * * @param kv KeyValues Handle. - * @noreturn * @error Invalid Handle. */ -native KvSavePosition(Handle:kv); +native void KvSavePosition(Handle kv); /** * Removes the given key from the current position. @@ -265,7 +523,7 @@ native KvSavePosition(Handle:kv); * @return True on success, false if key did not exist. * @error Invalid Handle. */ -native bool:KvDeleteKey(Handle:kv, const String:key[]); +native bool KvDeleteKey(Handle kv, const char[] key); /** * Removes the current sub-key and attempts to set the position @@ -282,7 +540,7 @@ native bool:KvDeleteKey(Handle:kv, const String:key[]); * thus the state is as if KvGoBack() was called. * @error Invalid Handle. */ -native KvDeleteThis(Handle:kv); +native int KvDeleteThis(Handle kv); /** * Jumps back to the previous position. Returns false if there are no @@ -294,7 +552,7 @@ native KvDeleteThis(Handle:kv); * @return True on success, false if there is no higher node. * @error Invalid Handle. */ -native bool:KvGoBack(Handle:kv); +native bool KvGoBack(Handle kv); /** * Sets the position back to the top node, emptying the entire node @@ -302,10 +560,9 @@ native bool:KvGoBack(Handle:kv); * if recursive iteration is not important. * * @param kv KeyValues Handle. - * @noreturn * @error Invalid Handle. */ -native KvRewind(Handle:kv); +native void KvRewind(Handle kv); /** * Retrieves the current section name. @@ -316,17 +573,16 @@ native KvRewind(Handle:kv); * @return True on success, false on failure. * @error Invalid Handle. */ -native bool:KvGetSectionName(Handle:kv, String:section[], maxlength); +native bool KvGetSectionName(Handle kv, char[] section, int maxlength); /** * Sets the current section name. * * @param kv KeyValues Handle. * @param section Section name. - * @noreturn * @error Invalid Handle. */ -native KvSetSectionName(Handle:kv, const String:section[]); +native void KvSetSectionName(Handle kv, const char[] section); /** * Returns the data type at a key. @@ -336,7 +592,7 @@ native KvSetSectionName(Handle:kv, const String:section[]); * @return KvDataType value of the key. * @error Invalid Handle. */ -native KvDataTypes:KvGetDataType(Handle:kv, const String:key[]); +native KvDataTypes KvGetDataType(Handle kv, const char[] key); /** * Converts a KeyValues tree to a file. The tree is dumped @@ -347,7 +603,7 @@ native KvDataTypes:KvGetDataType(Handle:kv, const String:key[]); * @return True on success, false otherwise. * @error Invalid Handle. */ -native bool:KeyValuesToFile(Handle:kv, const String:file[]); +native bool KeyValuesToFile(Handle kv, const char[] file); /** * Converts a file to a KeyValues tree. The file is read into @@ -358,7 +614,7 @@ native bool:KeyValuesToFile(Handle:kv, const String:file[]); * @return True on success, false otherwise. * @error Invalid Handle. */ -native bool:FileToKeyValues(Handle:kv, const String:file[]); +native bool FileToKeyValues(Handle kv, const char[] file); /** * Converts a given string to a KeyValues tree. The string is read into @@ -370,7 +626,7 @@ native bool:FileToKeyValues(Handle:kv, const String:file[]); * @return True on success, false otherwise. * @error Invalid Handle. */ -native bool:StringToKeyValues(Handle:kv, const String:buffer[], const String:resourceName[]="StringToKeyValues"); +native bool StringToKeyValues(Handle kv, const char[] buffer, const char[] resourceName="StringToKeyValues"); /** * Sets whether or not the KeyValues parser will read escape sequences. @@ -379,10 +635,9 @@ native bool:StringToKeyValues(Handle:kv, const String:buffer[], const String:res * * @param kv KeyValues Handle. * @param useEscapes Whether or not to read escape sequences. - * @noreturn * @error Invalid Handle. */ -native KvSetEscapeSequences(Handle:kv, bool:useEscapes); +native void KvSetEscapeSequences(Handle kv, bool useEscapes); /** * Returns the position in the jump stack; I.e. the number of calls @@ -393,7 +648,7 @@ native KvSetEscapeSequences(Handle:kv, bool:useEscapes); * @return Number of non-root nodes in the jump stack. * @error Invalid Handle. */ -native KvNodesInStack(Handle:kv); +native int KvNodesInStack(Handle kv); /** * Makes a new copy of all subkeys in the origin KeyValues to @@ -402,10 +657,9 @@ native KvNodesInStack(Handle:kv); * * @param origin Origin KeyValues Handle. * @param dest Destination KeyValues Handle. - * @noreturn * @error Invalid Handle. */ -native KvCopySubkeys(Handle:origin, Handle:dest); +native void KvCopySubkeys(Handle origin, Handle dest); /** * Finds a KeyValues name by id. @@ -417,7 +671,7 @@ native KvCopySubkeys(Handle:origin, Handle:dest); * @return True on success, false if id not found. * @error Invalid Handle. */ -native bool:KvFindKeyById(Handle:kv, id, String:name[], maxlength); +native bool KvFindKeyById(Handle kv, int id, char[] name, int maxlength); /** * Finds a KeyValues id inside a KeyValues tree. @@ -428,7 +682,7 @@ native bool:KvFindKeyById(Handle:kv, id, String:name[], maxlength); * @return True on success, false if key not found. * @error Invalid Handle. */ -native bool:KvGetNameSymbol(Handle:kv, const String:key[], &id); +native bool KvGetNameSymbol(Handle kv, const char[] key, int &id); /** * Retrieves the current section id. @@ -438,4 +692,4 @@ native bool:KvGetNameSymbol(Handle:kv, const String:key[], &id); * @return True on success, false on failure. * @error Invalid Handle. */ -native bool:KvGetSectionSymbol(Handle:kv, &id); +native bool KvGetSectionSymbol(Handle kv, int &id); diff --git a/plugins/testsuite/keyvalues.sp b/plugins/testsuite/keyvalues.sp index bef02fe7..12cbd436 100644 --- a/plugins/testsuite/keyvalues.sp +++ b/plugins/testsuite/keyvalues.sp @@ -28,31 +28,31 @@ public Action:RunTests(argc) } \ }"; - new Handle:kv = CreateKeyValues(""); + KeyValues kv = CreateKeyValues(""); - if (!StringToKeyValues(kv, validKv)) + if (!kv.ImportFromString(validKv)) ThrowError("Valid kv not read correctly!"); - decl String:value[128]; - KvGetString(kv, "child", value, sizeof(value)); + char value[128]; + kv.GetString("child", value, sizeof(value)); if (!StrEqual(value, "value")) ThrowError("Child kv should have 'value' but has: '%s'", value); - if (!KvJumpToKey(kv, "subkey")) + if (!kv.JumpToKey("subkey")) ThrowError("No sub kv subkey exists!"); - KvGetString(kv, "subchild", value, sizeof(value)); + kv.GetString("subchild", value, sizeof(value)); if (!StrEqual(value, "subvalue")) ThrowError("Subkv subvalue should have 'subvalue' but has: '%s'", value); - new Float:subfloat = KvGetFloat(kv, "subfloat"); + float subfloat = kv.GetFloat("subfloat"); if (subfloat != 1.0) ThrowError( "Subkv subfloat should have 1.0 but has: %f", subfloat) - CloseHandle(kv); + delete kv; PrintToServer("KeyValue tests passed!"); }