wasSharp – Diff between revs 7 and 26
?pathlinks?
Rev 7 | Rev 26 | |||
---|---|---|---|---|
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 |
|
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 | case ';': |
53 | case ';': |
|
54 | if (!t.Count.Equals(0)) |
54 | if (!t.Count.Equals(0)) |
|
55 | { |
55 | { |
|
56 | t.Enqueue(c); |
56 | t.Enqueue(c); |
|
57 | var special = string.Join("", t.ToArray()); |
57 | var special = string.Join("", t.ToArray()); |
|
58 | switch (special) |
58 | switch (special) |
|
59 | { |
59 | { |
|
60 | case "'": |
60 | case "'": |
|
61 | m.Append('\''); |
61 | m.Append('\''); |
|
62 | break; |
62 | break; |
|
63 | case """: |
63 | case """: |
|
64 | m.Append('"'); |
64 | m.Append('"'); |
|
65 | break; |
65 | break; |
|
66 | case ">": |
66 | case ">": |
|
67 | m.Append('>'); |
67 | m.Append('>'); |
|
68 | break; |
68 | break; |
|
69 | case "<": |
69 | case "<": |
|
70 | m.Append('<'); |
70 | m.Append('<'); |
|
71 | break; |
71 | break; |
|
72 | case "&": |
72 | case "&": |
|
73 | m.Append('&'); |
73 | m.Append('&'); |
|
74 | break; |
74 | break; |
|
75 | default: // Unrecognized escape sequence |
75 | default: // Unrecognized escape sequence |
|
76 | m.Append(special); |
76 | m.Append(special); |
|
77 | break; |
77 | break; |
|
78 | } |
78 | } |
|
79 | t.Clear(); |
79 | t.Clear(); |
|
80 | break; |
80 | break; |
|
81 | } |
81 | } |
|
82 | m.Append(c); |
82 | m.Append(c); |
|
83 | break; |
83 | break; |
|
84 | default: |
84 | default: |
|
85 | if (!t.Count.Equals(0)) |
85 | if (!t.Count.Equals(0)) |
|
86 | { |
86 | { |
|
87 | t.Enqueue(c); |
87 | t.Enqueue(c); |
|
88 | if (t.Count >= 6) |
88 | if (t.Count >= 6) |
|
89 | { |
89 | { |
|
90 | m.Append(string.Join("", t.ToArray())); |
90 | m.Append(string.Join("", t.ToArray())); |
|
91 | t.Clear(); |
91 | t.Clear(); |
|
92 | } |
92 | } |
|
93 | break; |
93 | break; |
|
94 | } |
94 | } |
|
95 | m.Append(c); |
95 | m.Append(c); |
|
96 | break; |
96 | break; |
|
97 | } |
97 | } |
|
98 | } |
98 | } |
|
99 | return m.ToString(); |
99 | return m.ToString(); |
|
100 | } |
100 | } |
|
101 | |
101 | |
|
102 | /////////////////////////////////////////////////////////////////////////// |
102 | /////////////////////////////////////////////////////////////////////////// |
|
103 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
103 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
104 | /////////////////////////////////////////////////////////////////////////// |
104 | /////////////////////////////////////////////////////////////////////////// |
|
105 | /// <summary> |
105 | /// <summary> |
|
106 | /// Escapes a string to be used in XML. |
106 | /// Escapes a string to be used in XML. |
|
107 | /// </summary> |
107 | /// </summary> |
|
108 | /// <param name="s">the string to escape</param> |
108 | /// <param name="s">the string to escape</param> |
|
109 | /// <returns>an XML escaped string</returns> |
109 | /// <returns>an XML escaped string</returns> |
|
110 | public static string EscapeXML(string s) |
110 | public static string EscapeXML(string s) |
|
111 | { |
111 | { |
|
112 | if (string.IsNullOrEmpty(s)) return s; |
112 | if (string.IsNullOrEmpty(s)) return s; |
|
113 | |
113 | |
|
114 | var result = new string[s.Length]; |
114 | var result = new string[s.Length]; |
|
115 | Parallel.ForEach(Enumerable.Range(0, s.Length), o => |
115 | Parallel.ForEach(Enumerable.Range(0, s.Length), o => |
|
116 | { |
116 | { |
|
117 | switch (s[o]) |
117 | switch (s[o]) |
|
118 | { |
118 | { |
|
119 | case '&': |
119 | case '&': |
|
120 | result[o] = @"&"; |
120 | result[o] = @"&"; |
|
121 | break; |
121 | break; |
|
122 | case '<': |
122 | case '<': |
|
123 | result[o] = @"<"; |
123 | result[o] = @"<"; |
|
124 | break; |
124 | break; |
|
125 | case '>': |
125 | case '>': |
|
126 | result[o] = @">"; |
126 | result[o] = @">"; |
|
127 | break; |
127 | break; |
|
128 | case '"': |
128 | case '"': |
|
129 | result[o] = @"""; |
129 | result[o] = @"""; |
|
130 | break; |
130 | break; |
|
131 | case '\'': |
131 | case '\'': |
|
132 | result[o] = @"'"; |
132 | result[o] = @"'"; |
|
133 | break; |
133 | break; |
|
134 | default: |
134 | default: |
|
135 | result[o] = s[o].ToString(); |
135 | result[o] = s[o].ToString(); |
|
136 | break; |
136 | break; |
|
137 | } |
137 | } |
|
138 | }); |
138 | }); |
|
139 | return string.Join("", result); |
139 | return string.Join("", result); |
|
140 | } |
140 | } |
|
141 | |
141 | |
|
142 | /////////////////////////////////////////////////////////////////////////// |
142 | /////////////////////////////////////////////////////////////////////////// |
|
143 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
143 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
144 | /////////////////////////////////////////////////////////////////////////// |
144 | /////////////////////////////////////////////////////////////////////////// |
|
145 | /// <summary> |
145 | /// <summary> |
|
146 | /// Determines whether a string is safe to use in XML |
146 | /// Determines whether a string is safe to use in XML |
|
147 | /// </summary> |
147 | /// </summary> |
|
148 | /// <param name="data">the string to check</param> |
148 | /// <param name="data">the string to check</param> |
|
149 | /// <returns>true in case the string is safe</returns> |
149 | /// <returns>true in case the string is safe</returns> |
|
150 | public static bool IsSafeXML(string data) |
150 | public static bool IsSafeXML(string data) |
|
151 | { |
151 | { |
|
152 | return directIsSafeXML(data); |
152 | return directIsSafeXML(data); |
|
153 | } |
153 | } |
|
154 | |
154 | |
|
155 | /////////////////////////////////////////////////////////////////////////// |
155 | /////////////////////////////////////////////////////////////////////////// |
|
156 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
156 | // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
|
157 | /////////////////////////////////////////////////////////////////////////// |
157 | /////////////////////////////////////////////////////////////////////////// |
|
158 | /// <summary> |
158 | /// <summary> |
|
159 | /// Recursively rename a node by name. |
159 | /// Recursively rename a node by name. |
|
160 | /// </summary> |
160 | /// </summary> |
|
161 | /// <param name="root">the root from where to start</param> |
161 | /// <param name="root">the root from where to start</param> |
|
162 | /// <param name="name">the name to replace</param> |
162 | /// <param name="name">the name to replace</param> |
|
163 | /// <param name="rename">the name to replace with</param> |
163 | /// <param name="rename">the name to replace with</param> |
|
164 | public static void RenameNodes(XElement root, string name, string rename) |
164 | public static void RenameNodes(XElement root, string name, string rename) |
|
165 | { |
165 | { |
|
166 | if (Strings.StringEquals(root.Name.LocalName, name, StringComparison.Ordinal)) |
166 | if (String.Equals(root.Name.LocalName, name, StringComparison.Ordinal)) |
|
167 | { |
167 | { |
|
168 | root.Name = rename; |
168 | root.Name = rename; |
|
169 | } |
169 | } |
|
170 | |
170 | |
|
171 | foreach (var xElement in root.Elements()) |
171 | foreach (var xElement in root.Elements()) |
|
172 | { |
172 | { |
|
173 | RenameNodes(xElement, name, rename); |
173 | RenameNodes(xElement, name, rename); |
|
174 | } |
174 | } |
|
175 | } |
175 | } |
|
176 | } |
176 | } |
|
177 | } |
177 | } |
|
178 | |
178 | |
|
179 |
|
179 |
|
|
180 | |
180 | |
|
181 | |
181 | |
|
182 | |
182 | |