Table of Contents

About

Modifies or creates a key k with value v and returns the result as a key-value pair string. Setting is performed in an "add or replace" fashion where keys that do not exist are added.

Examples

Changing a Variable

Suppose that the object's description is:

time=1365161695&toggle=true&position=<1,1,0>

and the function is called with:

llSetObjectDesc(wasKeyValueSet("toggle", "false", llGetObjectDesc()));

then the object's description will be set to:

time=1365161695&toggle=false&position=<1,1,0>

Adding a Variable

Suppose that the object's description is:

toggle=true&position=<1,1,0>

and the function is called with:

llSetObjectDesc(wasKeyValueSet("time", "now", llGetObjectDesc()));

then the object's description will be set to:

toggle=true&position=<1,1,0>&time=now

Code

LSL

This script was tested and works on OpenSim version 0.7.4!

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if(llStringLength(k) == 0) return "";
    if(llStringLength(v) == 0) return "";
    if(llStringLength(data) == 0) return k + "=" + v;
    integer i = llListFindList(
        llList2ListStrided(
            llParseString2List(data, ["&", "="], []), 
            0, -1, 2
        ), 
    [ k ]);
    if(i != -1) return llDumpList2String(
        llListReplaceList(
            llParseString2List(data, ["&"], []), 
            [ k + "=" + v ], 
        i, i), 
    "&");
    return data + "&" + k + "=" + v;
}

C

Using the following headers:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

the code is:

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
char *wasKeyValueSet(char *key, char *value, char *data) {
    if (key == NULL || value == NULL || strcmp(key, "") == 0 || strcmp(value, "") == 0) return "";
    char *result = (char*)malloc(1);
    if (data == NULL || strcmp(data, "") == 0) {
        result = (char*)realloc(result, strlen(key) + strlen(value) + 1);
        snprintf(result, sizeof(result) + sizeof(key) + sizeof(value) + 1, "%s=%s", key, value);
        return result;
    }
    char *p, *k, *v, **tuples = (char**)malloc(1);
    int i = 0, e = 0;
    data = strdup(data);
    while ((p = strsep(&data, "&")) != NULL) {
        k = strtok(p, "=");
        v = strtok(NULL, " ");
        if (strcmp(k, key) == 0) {
            tuples = (char**)realloc(tuples, i + 1);
            tuples[i] = (char*)malloc(strlen(key) + strlen(value) + 1);
            snprintf(tuples[i] + strlen(tuples[i]), sizeof(tuples[i]) + sizeof(key) + sizeof(value) + 1, "%s=%s", key, value);
            ++e;
            ++i;
            continue;
        }
        tuples = (char**)realloc(tuples, i + 1);
        tuples[i] = (char*)malloc(strlen(p));
        snprintf(tuples[i] + strlen(tuples[i]), sizeof(tuples[i]) + sizeof(k) + sizeof(v) + 1, "%s=%s", k, v);
        ++i;
    }
    if (!e) {
        tuples = (char**)realloc(tuples, i + 1);
        tuples[i] = (char*)malloc(strlen(key) + strlen(value) + 1);
        snprintf(tuples[i] + strlen(tuples[i]), sizeof(tuples[i]) + sizeof(key) + sizeof(value) + 1, "%s=%s", key, value);
        ++i;
    }
    int j = 0;
    while (j < i) {
        result = (char*)realloc(result, strlen(result) + strlen(tuples[j]) + 1);
        snprintf(result + strlen(result), sizeof(result) + sizeof(tuples[j]), "%s", tuples[j]);
        if (j != i - 1) {
            result = (char*)realloc(result, strlen(result) + 1);
            snprintf(result + strlen(result), sizeof(result) + 1, "&");
        }
        ++j;
    }
    free(tuples);
    free(data);
    return result;
}

C#

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
/// <summary>
///     Returns a key-value data string with a key set to a given value.
/// </summary>
/// <param name="key">the key of the value</param>
/// <param name="value">the value to set the key to</param>
/// <param name="data">the key-value data segment</param>
/// <returns>
///     a key-value data string or the empty string if either key or
///     value are empty
/// </returns>
private static string wasKeyValueSet(string key, string value, string data)
{
    List<string> output = new List<string>();
    foreach (string tuples in data.Split('&'))
    {
        string[] tuple = tuples.Split('=');
        if (!tuple.Length.Equals(2))
        {
            continue;
        }
        if (tuple[0].Equals(key, StringComparison.Ordinal))
        {
            tuple[1] = value;
        }
        output.Add(string.Join("=", tuple));
    }
    string add = string.Join("=", new[] {key, value});
    if (!output.Contains(add))
    {
        output.Add(add);
    }
    return string.Join("&", output.ToArray());
}

PHP

###########################################################################
##  Copyright (C) Wizardry and Steamworks 2015 - License: CC BY 2.0      ##
###########################################################################
function wasKeyValueSet($key, $value, $data) {
    $data = explode("&", $data);
    $data = array_filter(
        array_combine(
            array_map(
                function($o) {
                    return array_shift(explode("=", $o));
                }, 
                $data
            ), 
            array_map(
                function($o) {
                    return array_pop(explode("=", $o));
                }, 
                $data
            )
        )
    );
    $data[$key] = $value;
    array_walk($data,
        function(&$value, $key) {
            $value = $key."=".$value;
        }
    );
    return implode('&', $data);
}