Table of Contents

About

These functions convert a CSV string to key-value data.

Code

LSL

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasCSVToKeyValueData(string csv) {
    list v = [];
    list l = [];
    list s = [];
    string m = "";
    do {
        string a = llGetSubString(csv, 0, 0);
        csv = llDeleteSubString(csv, 0, 0);
        if(a == ",") {
            if(llGetListLength(l) == 2) {
                v += llList2String(l, 0) + "=" + llList2String(l, 1);
                l = [];
            }
            if(llList2String(s, -1) != "\"") {
                l += m;
                m = "";
                jump continue;
            }
            m += a;
            jump continue;
        }
        if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
            m += a;
            csv = llDeleteSubString(csv, 0, 0);
            jump continue;
        }
        if(a == "\"") {
            if(llList2String(s, -1) != a) {
                s += a;
                jump continue;
            }
            s = llDeleteSubList(s, -1, -1);
            jump continue;
        }
        m += a;
@continue;
    } while(csv != "");
    // postcondition: length(s) = 0
    l += m;
    if(llGetListLength(l) == 2)
        v += llList2String(l, 0) + "=" + llList2String(l, 1);
    return llDumpList2String(v, "&");
}

C#

///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
/// <summary>
///     Converts a comma-separated values string to key-value data.
/// </summary>
/// <param name="csv">a comma-separated values string</param>
/// <returns>key-value data string</returns>
/// <remarks>compliant with RFC 4180</remarks>
public static string wasCSVToKeyValueData(string csv)
{
    List<string> v = new List<string>();
    Stack<char> s = new Stack<char>();
    StringBuilder m = new StringBuilder();
    List<string> p = new List<string>(2);
    int i = 0;
    do
    {
        switch (csv[i])
        {
            case ',':
                if (p.Count.Equals(2))
                {
                    v.Add(string.Format("{0}={1}", p[0], p[1]));
                    p.Clear();
                }
                if (s.Count.Equals(0) || !s.Peek().Equals('"'))
                {
                    p.Add(m.ToString());
                    m = new StringBuilder();
                    continue;
                }
                m.Append(csv[i]);
                continue;
            case '"':
                if (i + 1 < csv.Length && csv[i] == csv[i + 1])
                {
                    m.Append(csv[i]);
                    ++i;
                    continue;
                }
                if (s.Count.Equals(0) || !s.Peek().Equals(csv[i]))
                {
                    s.Push(csv[i]);
                    continue;
                }
                s.Pop();
                continue;
        }
        m.Append(csv[i]);
    } while (++i < csv.Length);
 
    p.Add(m.ToString());
    if (p.Count.Equals(2))
    {
        v.Add(string.Format("{0}={1}", p[0], p[1]));
    }
 
    return string.Join("&", v.ToArray());
}