wasSharp – Diff between revs 56 and 59

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 56 Rev 59
Line 1... Line 1...
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 using System.Collections.Generic; 7 using System.Collections.Generic;
8 using System.Linq; 8 using System.Linq;
9 using System.Text; 9 using System.Text;
10   10  
11 namespace wasSharp.Languages 11 namespace wasSharp.Languages
12 { 12 {
13 public static class CSV 13 public static class CSV
14 { 14 {
-   15 public static readonly char[] CSVEscapeCharacters = {'"', ' ', ',', '\r', '\n'};
-   16  
15 /////////////////////////////////////////////////////////////////////////// 17 ///////////////////////////////////////////////////////////////////////////
16 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 18 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
17 /////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////
18 /// <summary> 20 /// <summary>
19 /// Converts a list of strings to a comma-separated values string. 21 /// Converts a list of strings to a comma-separated values string.
20 /// </summary> 22 /// </summary>
21 /// <returns>a commma-separated list of values</returns> 23 /// <returns>a commma-separated list of values</returns>
22 /// <remarks>compliant with RFC 4180</remarks> 24 /// <remarks>compliant with RFC 4180</remarks>
23 public static string FromEnumerable(IEnumerable<string> input) 25 public static string FromEnumerable(IEnumerable<string> input)
24 { 26 {
25 return string.Join(",", 27 return string.Join(",",
26 input 28 input
27 .Select(o => o.Replace("\"", "\"\"")) 29 .Select(o => o.Replace("\"", "\"\""))
28 .Select(o => o.IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) ? o : "\"" + o + "\"")); 30 .Select(o => o.IndexOfAny(CSVEscapeCharacters) == -1 ? o : $"\"{o}\""));
29 } 31 }
30   32  
31 /////////////////////////////////////////////////////////////////////////// 33 ///////////////////////////////////////////////////////////////////////////
32 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // 34 // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 //
33 /////////////////////////////////////////////////////////////////////////// 35 ///////////////////////////////////////////////////////////////////////////
34 /// <summary> 36 /// <summary>
35 /// Converts a dictionary of strings to a comma-separated values string. 37 /// Converts a dictionary of strings to a comma-separated values string.
36 /// </summary> 38 /// </summary>
37 /// <returns>a commma-separated list of values</returns> 39 /// <returns>a commma-separated list of values</returns>
38 /// <remarks>compliant with RFC 4180</remarks> 40 /// <remarks>compliant with RFC 4180</remarks>
39 public static string FromDictionary<K, V>(Dictionary<K, V> input) 41 public static string FromDictionary<TK, TV>(Dictionary<TK, TV> input)
40 { 42 {
41 return string.Join(",", input.Keys.Select(o => o.ToString()).Zip(input.Values.Select(o => o.ToString()), 43 return string.Join(",", input.Keys.Select(o => o.ToString()).Zip(input.Values.Select(o => o.ToString()),
42 (o, p) => 44 (o, p) =>
43 string.Join(",", 45 string.Join(",",
44 o.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) 46 o.Replace("\"", "\"\"").IndexOfAny(CSVEscapeCharacters) == -1
45 ? o 47 ? o
46 : "\"" + o + "\"", 48 : $"\"{o}\"",
47 p.Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) 49 p.Replace("\"", "\"\"").IndexOfAny(CSVEscapeCharacters) == -1
48 ? p 50 ? p
49 : "\"" + p + "\""))); 51 : $"\"{p}\"")));
50 } 52 }
51   53  
52 /////////////////////////////////////////////////////////////////////////// 54 ///////////////////////////////////////////////////////////////////////////
53 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 55 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
54 /////////////////////////////////////////////////////////////////////////// 56 ///////////////////////////////////////////////////////////////////////////
55 /// <summary> 57 /// <summary>
56 /// Converts successive comma-separated values to key-value pairs. 58 /// Converts successive comma-separated values to key-value pairs.
57 /// </summary> 59 /// </summary>
58 /// <returns>key-value pairs of successive comma-separate values</returns> 60 /// <returns>key-value pairs of successive comma-separate values</returns>
59 public static IEnumerable<KeyValuePair<string, string>> ToKeyValue(string input) 61 public static IEnumerable<KeyValuePair<string, string>> ToKeyValue(string input)
60 { 62 {
61 return ToEnumerable(input).AsParallel().Select((o, p) => new { o, p }) 63 return ToEnumerable(input).AsParallel().Select((o, p) => new {o, p})
62 .GroupBy(q => q.p / 2, q => q.o) 64 .GroupBy(q => q.p / 2, q => q.o)
63 .Select(o => o.ToArray()) 65 .Select(o => o.ToArray())
64 .TakeWhile(o => o.Length % 2 == 0) 66 .TakeWhile(o => o.Length % 2 == 0)
65 .Where(o => !string.IsNullOrEmpty(o[0])) 67 .Where(o => !string.IsNullOrEmpty(o[0]))
66 .Select(o => new KeyValuePair<string, string>(o[0], o[1])); 68 .Select(o => new KeyValuePair<string, string>(o[0], o[1]));
67 } 69 }
68   70  
69 /////////////////////////////////////////////////////////////////////////// 71 ///////////////////////////////////////////////////////////////////////////
70 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 72 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
71 /////////////////////////////////////////////////////////////////////////// 73 ///////////////////////////////////////////////////////////////////////////
72 /// <summary> 74 /// <summary>
73 /// Converts a generic key value pair to a CSV. 75 /// Converts a generic key value pair to a CSV.
74 /// </summary> 76 /// </summary>
75 /// <returns>a commma-separated list of values</returns> 77 /// <returns>a commma-separated list of values</returns>
76 /// <remarks>compliant with RFC 4180</remarks> 78 /// <remarks>compliant with RFC 4180</remarks>
77 public static string FromKeyValue<K, V>(KeyValuePair<K, V> input) 79 public static string FromKeyValue<TK, TV>(KeyValuePair<TK, TV> input)
78 { 80 {
79 var key = input.Key.ToString(); 81 var key = input.Key.ToString();
80 var value = input.Value.ToString(); 82 var value = input.Value.ToString();
81   83  
82 return string.Join(",", key 84 return string.Join(",", key
83 .Replace("\"", "\"\"").IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }).Equals(-1) 85 .Replace("\"", "\"\"").IndexOfAny(CSVEscapeCharacters) == -1
84 ? key 86 ? key
85 : "\"" + key + "\"", value 87 : $"\"{key}\"", value
86 .Replace("\"", "\"\"") 88 .Replace("\"", "\"\"")
87 .IndexOfAny(new[] { '"', ' ', ',', '\r', '\n' }) 89 .IndexOfAny(CSVEscapeCharacters) == -1
88 .Equals(-1) -  
89 ? value 90 ? value
90 : "\"" + value + "\""); 91 : $"\"{value}\"");
91 } 92 }
92   93  
93 /////////////////////////////////////////////////////////////////////////// 94 ///////////////////////////////////////////////////////////////////////////
94 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 95 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
95 /////////////////////////////////////////////////////////////////////////// 96 ///////////////////////////////////////////////////////////////////////////
96 /// <summary> 97 /// <summary>
97 /// Converts a comma-separated list of values to a list of strings. 98 /// Converts a comma-separated list of values to a list of strings.
98 /// </summary> 99 /// </summary>
99 /// <param name="csv">a comma-separated list of values</param> 100 /// <param name="csv">a comma-separated list of values</param>
100 /// <returns>a list of strings</returns> 101 /// <returns>a list of strings</returns>
101 /// <remarks>compliant with RFC 4180</remarks> 102 /// <remarks>compliant with RFC 4180</remarks>
102 public static IEnumerable<string> ToEnumerable(string csv) 103 public static IEnumerable<string> ToEnumerable(string csv)
103 { 104 {
104 if (csv == null) 105 if (string.IsNullOrEmpty(csv))
105 { -  
106 yield return string.Empty; -  
107 yield break; 106 yield break;
108 } -  
109   107  
110 var s = new Stack<char>(); 108 var s = new Stack<char>();
111 var m = new StringBuilder(); 109 var m = new StringBuilder();
112 for (var i = 0; i < csv.Length; ++i) 110 for (var i = 0; i < csv.Length; ++i)
113 { 111 {
114 switch (csv[i]) 112 switch (csv[i])
115 { 113 {
116 case ',': 114 case ',':
117 if (!s.Any() || !s.Peek().Equals('"')) 115 if (!s.Any() || !s.Peek().Equals('"'))
118 { 116 {
119 yield return m.ToString(); 117 yield return m.ToString();
120 m = new StringBuilder(); 118 m = new StringBuilder();
121 continue; 119 continue;
122 } 120 }
-   121  
123 m.Append(csv[i]); 122 m.Append(csv[i]);
124 continue; 123 continue;
125 case '"': 124 case '"':
126 if (i + 1 < csv.Length && csv[i].Equals(csv[i + 1])) 125 if (i + 1 < csv.Length && csv[i].Equals(csv[i + 1]))
127 { 126 {
128 m.Append(csv[i]); 127 m.Append(csv[i]);
129 ++i; 128 ++i;
130 continue; 129 continue;
131 } 130 }
-   131  
132 if (!s.Any() || !s.Peek().Equals(csv[i])) 132 if (!s.Any() || !s.Peek().Equals(csv[i]))
133 { 133 {
134 s.Push(csv[i]); 134 s.Push(csv[i]);
135 continue; 135 continue;
136 } 136 }
-   137  
137 s.Pop(); 138 s.Pop();
138 continue; 139 continue;
139 } 140 }
-   141  
140 m.Append(csv[i]); 142 m.Append(csv[i]);
141 } 143 }
142   144  
143 yield return m.ToString(); 145 yield return m.ToString();
144 } 146 }
145 } 147 }
146 } 148 }
147   149