wasSharp – Diff between revs 54 and 55
?pathlinks?
Rev 54 | Rev 55 | |||
---|---|---|---|---|
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; |
7 | using System; |
|
8 | using System.Collections.Generic; |
8 | using System.Collections.Generic; |
|
9 | using System.Linq; |
9 | using System.Linq; |
|
10 | using System.Linq.Expressions; |
10 | using System.Linq.Expressions; |
|
11 | using System.Text; |
11 | using System.Text; |
|
12 | using System.Text.RegularExpressions; |
12 | using System.Text.RegularExpressions; |
|
13 | using System.Threading.Tasks; |
13 | using System.Threading.Tasks; |
|
14 | using System.Xml.Linq; |
14 | using System.Xml.Linq; |
|
15 | |
15 | |
|
16 | namespace wasSharp |
16 | namespace wasSharp.Languages |
|
17 | { |
17 | { |
|
18 | public static class XML |
18 | public static class XML |
|
19 | { |
19 | { |
|
20 | private static readonly Func<string, bool> directIsSafeXML = |
20 | private static readonly Func<string, bool> directIsSafeXML = |
|
21 | ((Expression<Func<string, bool>>) |
21 | ((Expression<Func<string, bool>>) |
|
22 | (data => |
22 | (data => |
|
23 | Regex.Replace(data, |
23 | Regex.Replace(data, |
|
24 | @"(" + string.Join(@"|", @"&", @"<", @">", @""", @"'") + @")", |
24 | @"(" + string.Join(@"|", @"&", @"<", @">", @""", @"'") + @")", |
|
25 | @"", RegexOptions.IgnoreCase | RegexOptions.Multiline) |
25 | @"", RegexOptions.IgnoreCase | RegexOptions.Multiline) |
|
26 | .IndexOfAny(new[] { '&', '<', '>', '"', '\'' }) |
26 | .IndexOfAny(new[] { '&', '<', '>', '"', '\'' }) |
|
27 | .Equals(-1))).Compile(); |
27 | .Equals(-1))).Compile(); |
|
28 | |
28 | |
|
29 | /////////////////////////////////////////////////////////////////////////// |
29 | /////////////////////////////////////////////////////////////////////////// |
|
30 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
30 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
31 | /////////////////////////////////////////////////////////////////////////// |
31 | /////////////////////////////////////////////////////////////////////////// |
|
32 | /// <summary> |
32 | /// <summary> |
|
33 | /// Unescapes a string used in XML. |
33 | /// Unescapes a string used in XML. |
|
34 | /// </summary> |
34 | /// </summary> |
|
35 | /// <param name="s">the string to unescape</param> |
35 | /// <param name="s">the string to unescape</param> |
|
36 | /// <returns>an XML unescaped string</returns> |
36 | /// <returns>an XML unescaped string</returns> |
|
37 | public static string UnescapeXML(string s) |
37 | public static string UnescapeXML(string s) |
|
38 | { |
38 | { |
|
39 | var t = new Queue<char>(); |
39 | var t = new Queue<char>(); |
|
40 | var m = new StringBuilder(); |
40 | var m = new StringBuilder(); |
|
41 | foreach (var c in s) |
41 | foreach (var c in s) |
|
42 | { |
42 | { |
|
43 | switch (c) |
43 | switch (c) |
|
44 | { |
44 | { |
|
45 | case '&': |
45 | case '&': |
|
46 | if (!t.Count().Equals(0)) |
46 | if (!t.Count().Equals(0)) |
|
47 | { |
47 | { |
|
48 | m.Append(string.Join("", t.ToArray())); |
48 | m.Append(string.Join("", t.ToArray())); |
|
49 | t.Clear(); |
49 | t.Clear(); |
|
50 | } |
50 | } |
|
51 | t.Enqueue(c); |
51 | t.Enqueue(c); |
|
52 | break; |
52 | break; |
|
53 | |
53 | |
|
54 | case ';': |
54 | case ';': |
|
55 | if (!t.Count().Equals(0)) |
55 | if (!t.Count().Equals(0)) |
|
56 | { |
56 | { |
|
57 | t.Enqueue(c); |
57 | t.Enqueue(c); |
|
58 | var special = string.Join("", t.ToArray()); |
58 | var special = string.Join("", t.ToArray()); |
|
59 | switch (special) |
59 | switch (special) |
|
60 | { |
60 | { |
|
61 | case "'": |
61 | case "'": |
|
62 | m.Append('\''); |
62 | m.Append('\''); |
|
63 | break; |
63 | break; |
|
64 | |
64 | |
|
65 | case """: |
65 | case """: |
|
66 | m.Append('"'); |
66 | m.Append('"'); |
|
67 | break; |
67 | break; |
|
68 | |
68 | |
|
69 | case ">": |
69 | case ">": |
|
70 | m.Append('>'); |
70 | m.Append('>'); |
|
71 | break; |
71 | break; |
|
72 | |
72 | |
|
73 | case "<": |
73 | case "<": |
|
74 | m.Append('<'); |
74 | m.Append('<'); |
|
75 | break; |
75 | break; |
|
76 | |
76 | |
|
77 | case "&": |
77 | case "&": |
|
78 | m.Append('&'); |
78 | m.Append('&'); |
|
79 | break; |
79 | break; |
|
80 | |
80 | |
|
81 | default: // Unrecognized escape sequence |
81 | default: // Unrecognized escape sequence |
|
82 | m.Append(special); |
82 | m.Append(special); |
|
83 | break; |
83 | break; |
|
84 | } |
84 | } |
|
85 | t.Clear(); |
85 | t.Clear(); |
|
86 | break; |
86 | break; |
|
87 | } |
87 | } |
|
88 | m.Append(c); |
88 | m.Append(c); |
|
89 | break; |
89 | break; |
|
90 | |
90 | |
|
91 | default: |
91 | default: |
|
92 | if (!t.Count().Equals(0)) |
92 | if (!t.Count().Equals(0)) |
|
93 | { |
93 | { |
|
94 | t.Enqueue(c); |
94 | t.Enqueue(c); |
|
95 | if (t.Count() >= 6) |
95 | if (t.Count() >= 6) |
|
96 | { |
96 | { |
|
97 | m.Append(string.Join("", t.ToArray())); |
97 | m.Append(string.Join("", t.ToArray())); |
|
98 | t.Clear(); |
98 | t.Clear(); |
|
99 | } |
99 | } |
|
100 | break; |
100 | break; |
|
101 | } |
101 | } |
|
102 | m.Append(c); |
102 | m.Append(c); |
|
103 | break; |
103 | break; |
|
104 | } |
104 | } |
|
105 | } |
105 | } |
|
106 | return m.ToString(); |
106 | return m.ToString(); |
|
107 | } |
107 | } |
|
108 | |
108 | |
|
109 | /////////////////////////////////////////////////////////////////////////// |
109 | /////////////////////////////////////////////////////////////////////////// |
|
110 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
110 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
111 | /////////////////////////////////////////////////////////////////////////// |
111 | /////////////////////////////////////////////////////////////////////////// |
|
112 | /// <summary> |
112 | /// <summary> |
|
113 | /// Escapes a string to be used in XML. |
113 | /// Escapes a string to be used in XML. |
|
114 | /// </summary> |
114 | /// </summary> |
|
115 | /// <param name="s">the string to escape</param> |
115 | /// <param name="s">the string to escape</param> |
|
116 | /// <returns>an XML escaped string</returns> |
116 | /// <returns>an XML escaped string</returns> |
|
117 | public static string EscapeXML(string s) |
117 | public static string EscapeXML(string s) |
|
118 | { |
118 | { |
|
119 | if (string.IsNullOrEmpty(s)) return s; |
119 | if (string.IsNullOrEmpty(s)) return s; |
|
120 | |
120 | |
|
121 | var result = new string[s.Length]; |
121 | var result = new string[s.Length]; |
|
122 | Parallel.ForEach(Enumerable.Range(0, s.Length), o => |
122 | Parallel.ForEach(Enumerable.Range(0, s.Length), o => |
|
123 | { |
123 | { |
|
124 | switch (s[o]) |
124 | switch (s[o]) |
|
125 | { |
125 | { |
|
126 | case '&': |
126 | case '&': |
|
127 | result[o] = @"&"; |
127 | result[o] = @"&"; |
|
128 | break; |
128 | break; |
|
129 | |
129 | |
|
130 | case '<': |
130 | case '<': |
|
131 | result[o] = @"<"; |
131 | result[o] = @"<"; |
|
132 | break; |
132 | break; |
|
133 | |
133 | |
|
134 | case '>': |
134 | case '>': |
|
135 | result[o] = @">"; |
135 | result[o] = @">"; |
|
136 | break; |
136 | break; |
|
137 | |
137 | |
|
138 | case '"': |
138 | case '"': |
|
139 | result[o] = @"""; |
139 | result[o] = @"""; |
|
140 | break; |
140 | break; |
|
141 | |
141 | |
|
142 | case '\'': |
142 | case '\'': |
|
143 | result[o] = @"'"; |
143 | result[o] = @"'"; |
|
144 | break; |
144 | break; |
|
145 | |
145 | |
|
146 | default: |
146 | default: |
|
147 | result[o] = s[o].ToString(); |
147 | result[o] = s[o].ToString(); |
|
148 | break; |
148 | break; |
|
149 | } |
149 | } |
|
150 | }); |
150 | }); |
|
151 | return string.Join("", result); |
151 | return string.Join("", result); |
|
152 | } |
152 | } |
|
153 | |
153 | |
|
154 | /////////////////////////////////////////////////////////////////////////// |
154 | /////////////////////////////////////////////////////////////////////////// |
|
155 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
155 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
156 | /////////////////////////////////////////////////////////////////////////// |
156 | /////////////////////////////////////////////////////////////////////////// |
|
157 | /// <summary> |
157 | /// <summary> |
|
158 | /// Determines whether a string is safe to use in XML |
158 | /// Determines whether a string is safe to use in XML |
|
159 | /// </summary> |
159 | /// </summary> |
|
160 | /// <param name="data">the string to check</param> |
160 | /// <param name="data">the string to check</param> |
|
161 | /// <returns>true in case the string is safe</returns> |
161 | /// <returns>true in case the string is safe</returns> |
|
162 | public static bool IsSafeXML(string data) |
162 | public static bool IsSafeXML(string data) |
|
163 | { |
163 | { |
|
164 | return directIsSafeXML(data); |
164 | return directIsSafeXML(data); |
|
165 | } |
165 | } |
|
166 | |
166 | |
|
167 | /////////////////////////////////////////////////////////////////////////// |
167 | /////////////////////////////////////////////////////////////////////////// |
|
168 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
168 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
169 | /////////////////////////////////////////////////////////////////////////// |
169 | /////////////////////////////////////////////////////////////////////////// |
|
170 | /// <summary> |
170 | /// <summary> |
|
171 | /// Recursively rename a node by name. |
171 | /// Recursively rename a node by name. |
|
172 | /// </summary> |
172 | /// </summary> |
|
173 | /// <param name="root">the root from where to start</param> |
173 | /// <param name="root">the root from where to start</param> |
|
174 | /// <param name="name">the name to replace</param> |
174 | /// <param name="name">the name to replace</param> |
|
175 | /// <param name="rename">the name to replace with</param> |
175 | /// <param name="rename">the name to replace with</param> |
|
176 | public static void RenameNodes(XElement root, string name, string rename) |
176 | public static void RenameNodes(XElement root, string name, string rename) |
|
177 | { |
177 | { |
|
178 | if (string.Equals(root.Name.LocalName, name, StringComparison.Ordinal)) |
178 | if (string.Equals(root.Name.LocalName, name, StringComparison.Ordinal)) |
|
179 | { |
179 | { |
|
180 | root.Name = rename; |
180 | root.Name = rename; |
|
181 | } |
181 | } |
|
182 | |
182 | |
|
183 | foreach (var xElement in root.Elements()) |
183 | foreach (var xElement in root.Elements()) |
|
184 | { |
184 | { |
|
185 | RenameNodes(xElement, name, rename); |
185 | RenameNodes(xElement, name, rename); |
|
186 | } |
186 | } |
|
187 | } |
187 | } |
|
188 | } |
188 | } |
|
189 | } |
189 | } |
|
190 | |
190 | |