/Languages/CSV.cs |
@@ -12,6 +12,8 @@ |
{ |
public static class CSV |
{ |
public static readonly char[] CSVEscapeCharacters = {'"', ' ', ',', '\r', '\n'}; |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -25,7 +27,7 @@ |
return string.Join(",", |
input |
.Select(o => o.Replace("\"", "\"\"")) |
.Select(o => o.IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) ? o : "\"" + o + "\"")); |
.Select(o => o.IndexOfAny(CSVEscapeCharacters) == -1 ? o : $"\"{o}\"")); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -36,17 +38,17 @@ |
/// </summary> |
/// <returns>a commma-separated list of values</returns> |
/// <remarks>compliant with RFC 4180</remarks> |
public static string FromDictionary<K, V>(Dictionary<K, V> input) |
public static string FromDictionary<TK, TV>(Dictionary<TK, TV> input) |
{ |
return string.Join(",", input.Keys.Select(o => o.ToString()).Zip(input.Values.Select(o => o.ToString()), |
(o, p) => |
string.Join(",", |
o.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) |
o.Replace("\"", "\"\"").IndexOfAny(CSVEscapeCharacters) == -1 |
? o |
: "\"" + o + "\"", |
p.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) |
: $"\"{o}\"", |
p.Replace("\"", "\"\"").IndexOfAny(CSVEscapeCharacters) == -1 |
? p |
: "\"" + p + "\""))); |
: $"\"{p}\""))); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -74,20 +76,19 @@ |
/// </summary> |
/// <returns>a commma-separated list of values</returns> |
/// <remarks>compliant with RFC 4180</remarks> |
public static string FromKeyValue<K, V>(KeyValuePair<K, V> input) |
public static string FromKeyValue<TK, TV>(KeyValuePair<TK, TV> input) |
{ |
var key = input.Key.ToString(); |
var value = input.Value.ToString(); |
|
return string.Join(",", key |
.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) |
.Replace("\"", "\"\"").IndexOfAny(CSVEscapeCharacters) == -1 |
? key |
: "\"" + key + "\"", value |
: $"\"{key}\"", value |
.Replace("\"", "\"\"") |
.IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }) |
.Equals(-1) |
.IndexOfAny(CSVEscapeCharacters) == -1 |
? value |
: "\"" + value + "\""); |
: $"\"{value}\""); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -101,11 +102,8 @@ |
/// <remarks>compliant with RFC 4180</remarks> |
public static IEnumerable<string> ToEnumerable(string csv) |
{ |
if (csv == null) |
{ |
yield return string.Empty; |
if (string.IsNullOrEmpty(csv)) |
yield break; |
} |
|
var s = new Stack<char>(); |
var m = new StringBuilder(); |
@@ -120,6 +118,7 @@ |
m = new StringBuilder(); |
continue; |
} |
|
m.Append(csv[i]); |
continue; |
case '"': |
@@ -129,14 +128,17 @@ |
++i; |
continue; |
} |
|
if (!s.Any() || !s.Peek().Equals(csv[i])) |
{ |
s.Push(csv[i]); |
continue; |
} |
|
s.Pop(); |
continue; |
} |
|
m.Append(csv[i]); |
} |
|
/Languages/KeyValue.cs |
@@ -25,7 +25,7 @@ |
return data.Split('&') |
.AsParallel() |
.Select(o => o.Split('=')) |
.Where(o => o.Length.Equals(2) && string.Equals(o[0], key, StringComparison.Ordinal)) |
.Where(o => o.Length.Equals(2) && o[0] == key) |
.Select(o => o[1]) |
.FirstOrDefault(); |
} |
@@ -45,8 +45,8 @@ |
return string.Join("&", string.Join("&", data.Split('&') |
.AsParallel() |
.Select(o => o.Split('=')) |
.Where(o => o.Length.Equals(2) && !string.Equals(o[0], key, StringComparison.Ordinal)) |
.Select(o => string.Join("=", o[0], o[1]))), string.Join("=", key, value)); |
.Where(o => o.Length.Equals(2) && o[0] == key) |
.Select(o => o[0] + "=" + o[1])), key + "=" + value); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -61,8 +61,8 @@ |
return string.Join("&", data.Split('&') |
.AsParallel() |
.Select(o => o.Split('=')) |
.Where(o => o.Length.Equals(2) && !string.Equals(o[0], key, StringComparison.Ordinal)) |
.Select(o => string.Join("=", o[0], o[1]))); |
.Where(o => o.Length.Equals(2) && o[0] == key) |
.Select(o => o[0] + "=" + o[1])); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -96,7 +96,7 @@ |
/// <returns>a key-value data encoded string</returns> |
public static string Encode(Dictionary<string, string> data) |
{ |
return string.Join("&", data.Select(o => string.Join("=", o.Key, o.Value))); |
return string.Join("&", data.Select(o => o.Key + "=" + o.Value)); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -109,7 +109,7 @@ |
/// <returns>a key-value data encoded string</returns> |
public static string Encode(IEnumerable<KeyValuePair<string, string>> data) |
{ |
return string.Join("&", data.Select(o => string.Join("=", o.Key, o.Value))); |
return string.Join("&", data.Select(o => o.Key + "=" + o.Value)); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -122,7 +122,7 @@ |
/// <returns>a key-value data encoded string</returns> |
public static string Encode(IEnumerable<KeyValuePair<Task<string>, Task<string>>> data) |
{ |
return string.Join("&", data.Select(o => string.Join("=", o.Key.Result, o.Value.Result))); |
return string.Join("&", data.Select(o => o.Key.Result + "=" + o.Value.Result)); |
} |
|
/////////////////////////////////////////////////////////////////////////// |