Raised This Month: $12 Target: $400
 3% 

[STOCK] merge KeyValues


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
statistician
Member
Join Date: Jan 2016
Location: Finland
Old 02-04-2016 , 02:14   [STOCK] merge KeyValues
Reply With Quote #1

Here's a stock to merge two KeyValues together (and a couple others that are used).

Code:
#define MAX_SECTION_LENGTH    128

/**
 * Returns whether ot not the current key is an empty tree (section).
 *
 * @param kv    KeyValues handle.
 * @return      True if current key is a tree and is empty, false otherwise.
 */
stock bool KvIsEmptyTree(Handle kv) {
    if (KvGotoFirstSubKey(kv, false)) {
        KvGoBack(kv);
        return false;
    }

    char value[128];
    KvGetString(kv, NULL_STRING, value, sizeof(value), "#novalue");
    return StrEqual(value, "#novalue"); // is it an empty tree
}

/**
 * Returns whether ot not the current key is a tree (section).
 *
 * @param kv    KeyValues handle.
 * @return      True if current key is a tree (section), false otherwise.
 */
stock bool KvIsTree(Handle kv) {
    if (KvGotoFirstSubKey(kv, false)) {
        KvGoBack(kv);
        return true;
    }

    char value[128];
    KvGetString(kv, NULL_STRING, value, sizeof(value), "#novalue");
    return StrEqual(value, "#novalue"); // is it an empty tree
}

/**
 * Jumps to a key that is on the same level as the current one,
 * if such a key exists.
 *
 * @param kv    KeyValues handle.
 * @return      True if the key existed, false otherwise.
 */
stock bool KvJumpToSiblingKey(Handle kv, char[] target) {
    char start[MAX_SECTION_LENGTH];
    KvGetSectionName(kv, start, sizeof(start));

    if (KvNodesInStack(kv) == 0)
        return StrEqual(start, target);

    KvGoBack(kv);
    if (KvJumpToKey(kv, target))
        return true;

    KvJumpToKey(kv, start);
    return false;
}

/**
 * Merges two KeyValues into one.
 *
 * @param kv_to         KeyValues handle to which new information should be written.
 * @param kv_form       KeyValues handle from which new information should be copied.
 * @noreturn
 */
stock void KvMerge(Handle kv_to, Handle kv_from) {
    char key_from[MAX_SECTION_LENGTH], value_from[MAX_SECTION_LENGTH];
    do {
        KvGetSectionName(kv_from, key_from, sizeof(key_from));

        if (KvIsEmptyTree(kv_from)) {
            KvGoBack(kv_to);
            KvJumpToKey(kv_to, key_from, true); 
        } else if (KvIsTree(kv_from)) {
            KvGotoFirstSubKey(kv_from, false);

            if (!KvJumpToSiblingKey(kv_to, key_from)) {
                KvJumpToKey(kv_to, key_from, true);
                KvGetSectionName(kv_from, key_from, sizeof(key_from));
                if (KvIsTree(kv_from)) {
                    KvJumpToKey(kv_to, key_from, true);
                    KvGoBack(kv_to);
                } else {
                    KvGetString(kv_from, NULL_STRING, value_from, sizeof(value_from));
                    KvSetString(kv_to, key_from, value_from);
                }
            }

            KvGotoFirstSubKey(kv_to, false);

            KvMerge(kv_to, kv_from);

            KvGoBack(kv_from);
            KvGoBack(kv_to);
        } else {
            KvGetString(kv_from, NULL_STRING, value_from, sizeof(value_from));
            KvGoBack(kv_to);
            KvSetString(kv_to, key_from, value_from);
            KvGotoFirstSubKey(kv_to, false);
        }
    } while (KvGotoNextKey(kv_from, false));
}
I haven't tested merging extensively, but it worked for the cases I did test. Let me know if you have suggestions or notice any problems.

Example:

kv1:

Code:
"KeyValues"
{
    "key1"    "value"

    "names" {
        "name1"    "bob"
        "name2"    "james"
    }
}
kv2:

Code:
"KeyValues"
{
    "key2"    "value"

    "names" {
        "name3"    "mike"
        "name4"    "henry"
    }
}
If I do KvMerge(kv1, kv2), kv1 is now:

Code:
"KeyValues"
{
    "key1"    "value"
    "key2"    "value"

    "names" {
        "name1"    "bob"
        "name2"    "james"
        "name3"    "mike"
        "name4"    "henry"
    }
}

Last edited by statistician; 02-04-2016 at 02:44.
statistician is offline
eyal282
Veteran Member
Join Date: Aug 2011
Old 02-10-2019 , 05:20   Re: [STOCK] merge KeyValues
Reply With Quote #2

This seems not to work for merging from a specific point. After all it nulls your current position after using the stock. Any way to support merging from a position?
__________________
I am available to make plugins for pay.

Discord: Eyal282#1334
eyal282 is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:41.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode