Table of Contents

About

Unescapes the keys and values of a key-value data string and making them compliant with RFC3986.

In other words, wasKeyValueURIUnescape will take as input a percent-encoded string of keys and values and return an unescaped string of keys and values. This is useful in order to be able to decode URI-encoded strings.

Example Usage

When called with:

string data = "hello%21=there&how=are%20you";
wasKeyValueURIUnescape($data);

the function will return the string:

hello!=there&how=are you

Code

LSL

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueURIUnescape(string data) {
    list i = llParseString2List(data, ["&", "="], []);
    list output = [];
    do {
        output += llUnescapeURL(llList2String(i, 0)) + "=" + 
            llUnescapeURL(llList2String(i, 1));
        i = llDeleteSubList(i, 0, 1);
    } while(llGetListLength(i) != 0);
    return llDumpList2String(output, "&");
}

C#

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0      //
///////////////////////////////////////////////////////////////////////////
/// <summary>URI unescapes an RFC3986 URI escaped string</summary>
/// <param name="data">a string to unescape</param>
/// <returns>the resulting string</returns>
private static string wasUriUnescapeDataString(string data)
{
    return
        Regex.Matches(data, @"%([0-9A-Fa-f]+?){2}")
            .Cast<Match>()
            .Select(m => m.Value)
            .Distinct()
            .Aggregate(data,
                (current, match) =>
                    current.Replace(match,
                        ((char)
                            int.Parse(match.Substring(1), NumberStyles.AllowHexSpecifier,
                                CultureInfo.InvariantCulture)).ToString(
                                    CultureInfo.InvariantCulture)));
}