2 // System.Xml.Serialization.XmlCustomFormatter.cs
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Collections;
36 using System.Globalization;
38 namespace System.Xml.Serialization {
39 internal class XmlCustomFormatter {
43 internal static string FromByteArrayBase64 (byte[] value)
45 return Convert.ToBase64String(value);
48 internal static string FromByteArrayHex (byte[] value)
50 if (value == null) return null;
51 StringBuilder output = new StringBuilder ();
52 foreach (byte val in value)
53 output.Append (val.ToString ("X2", CultureInfo.InvariantCulture));
54 return output.ToString ();
57 internal static string FromChar (char value)
59 return ((int) value).ToString (CultureInfo.InvariantCulture);
62 internal static string FromDate (DateTime value)
64 return XmlConvert.ToString (value, "yyyy-MM-dd");
67 internal static string FromDateTime (DateTime value)
69 return XmlConvert.ToString (value, "yyyy-MM-ddTHH:mm:ss.fffffffzzz");
72 internal static string FromTime (DateTime value)
74 return XmlConvert.ToString (value, "HH:mm:ss.fffffffzzz");
77 internal static string FromEnum (long value, string[] values, long[] ids)
79 return FromEnum (value, values, ids, (string) null);
82 internal static string FromEnum (long value, string[] values, long[] ids, string typeName)
84 StringBuilder sb = new StringBuilder();
85 int length = ids.Length;
86 long valueToProcess = value;
89 for (int i = 0; i < length; i ++) {
93 if (valueToProcess == 0) {
97 if ((ids[i] & value) == ids[i]) {
100 sb.Append (values[i]);
101 valueToProcess &= ~ids[i];
106 if (valueToProcess != 0) {
108 if (typeName != null)
109 throw new InvalidOperationException (string.Format (CultureInfo.CurrentCulture,
110 "'{0}' is not a valid value for {1}.", value, typeName));
112 throw new InvalidOperationException (string.Format (CultureInfo.CurrentCulture,
113 "'{0}' is not a valid value.", value));
115 return value.ToString ();
118 if (sb.Length == 0 && zeroValue != -1) {
119 sb.Append (values[zeroValue]);
121 return sb.ToString ();
124 internal static string FromXmlName (string name)
126 return XmlConvert.EncodeName (name);
129 internal static string FromXmlNCName (string ncName)
131 return XmlConvert.EncodeLocalName (ncName);
134 internal static string FromXmlNmToken (string nmToken)
136 return XmlConvert.EncodeNmToken (nmToken);
139 internal static string FromXmlNmTokens (string nmTokens)
141 string [] tokens = nmTokens.Split (' ');
142 for (int i=0; i<tokens.Length; i++)
143 tokens [i] = FromXmlNmToken (tokens [i]);
144 return String.Join (" ", tokens);
147 internal static byte[] ToByteArrayBase64 (string value)
149 return Convert.FromBase64String(value);
152 internal static char ToChar (string value)
154 return (char) XmlConvert.ToUInt16 (value);
157 internal static DateTime ToDate (string value)
159 return ToDateTime (value);
162 internal static DateTime ToDateTime (string value)
164 return XmlConvert.ToDateTime (value);
167 internal static DateTime ToTime (string value)
169 return ToDateTime (value);
172 internal static long ToEnum (string value, Hashtable values, string typeName, bool validate)
174 // Assuming that h contains map from value to Enumerated Name
177 return ToEnum ("One Two", h, "SomeType");
179 (1) no keys and values for h.
180 (2) string keys and long values.
182 according to MSDN docs (for .NET 2.0) the hashtable "consists of the
183 identifiers as keys and the constants as integral numbers"
186 string[] names = value.Split (' ');
188 foreach (string name in names) {
189 object nameValue = values[name];
190 if (nameValue != null) {
191 enumValue |= (long) nameValue;
192 } else if (validate && name.Length != 0) {
193 throw new InvalidOperationException (String.Format ("'{0}' is not a valid member of type {1}.", name, typeName));
200 internal static string ToXmlName (string value)
202 return XmlConvert.DecodeName (value);
205 internal static string ToXmlNCName (string value)
207 return ToXmlName (value);
210 internal static string ToXmlNmToken (string value)
212 return ToXmlName (value);
215 internal static string ToXmlNmTokens (string value)
217 return ToXmlName (value);
220 internal static string ToXmlString (TypeData type, object value)
222 if (value == null) return null;
223 switch (type.XmlType)
225 case "boolean": return XmlConvert.ToString ((bool)value);
226 case "unsignedByte": return XmlConvert.ToString ((byte)value);
227 case "char": return XmlConvert.ToString ((int)(char)value);
228 case "dateTime": return XmlConvert.ToString ((DateTime)value);
229 case "date": return ((DateTime)value).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
230 case "time": return ((DateTime)value).ToString("HH:mm:ss.fffffffzzz", CultureInfo.InvariantCulture);
231 case "decimal": return XmlConvert.ToString ((decimal)value);
232 case "double": return XmlConvert.ToString ((double)value);
233 case "short": return XmlConvert.ToString ((Int16)value);
234 case "int": return XmlConvert.ToString ((Int32)value);
235 case "long": return XmlConvert.ToString ((Int64)value);
236 case "byte": return XmlConvert.ToString ((sbyte)value);
237 case "float": return XmlConvert.ToString ((Single)value);
238 case "unsignedShort": return XmlConvert.ToString ((UInt16)value);
239 case "unsignedInt": return XmlConvert.ToString ((UInt32)value);
240 case "unsignedLong": return XmlConvert.ToString ((UInt64)value);
241 case "guid": return XmlConvert.ToString ((Guid)value);
243 case "base64Binary": return Convert.ToBase64String ((byte[])value);
244 case "duration": return XmlConvert.ToString ((TimeSpan) value);
245 default: return value is IFormattable ? ((IFormattable) value).ToString (null, CultureInfo.InvariantCulture) : value.ToString ();
249 internal static object FromXmlString (TypeData type, string value)
251 if (value == null) return null;
253 switch (type.XmlType)
255 case "boolean": return XmlConvert.ToBoolean (value);
256 case "unsignedByte": return XmlConvert.ToByte (value);
257 case "char": return (char)XmlConvert.ToInt32 (value);
258 case "dateTime": return XmlConvert.ToDateTime (value);
259 case "date": return DateTime.ParseExact (value, "yyyy-MM-dd", null);
260 case "time": return DateTime.ParseExact (value, "HH:mm:ss.fffffffzzz", null);
261 case "decimal": return XmlConvert.ToDecimal (value);
262 case "double": return XmlConvert.ToDouble (value);
263 case "short": return XmlConvert.ToInt16 (value);
264 case "int": return XmlConvert.ToInt32 (value);
265 case "long": return XmlConvert.ToInt64 (value);
266 case "byte": return XmlConvert.ToSByte (value);
267 case "float": return XmlConvert.ToSingle (value);
268 case "unsignedShort": return XmlConvert.ToUInt16 (value);
269 case "unsignedInt": return XmlConvert.ToUInt32 (value);
270 case "unsignedLong": return XmlConvert.ToUInt64 (value);
271 case "guid": return XmlConvert.ToGuid (value);
273 case "base64Binary": return Convert.FromBase64String (value);
274 case "duration": return XmlConvert.ToTimeSpan (value);
276 if (type.Type != null)
277 return Convert.ChangeType (value, type.Type);
283 internal static string GenerateToXmlString (TypeData type, string value)
285 switch (type.XmlType)
287 case "boolean": return "(" + value + "?\"true\":\"false\")";
288 case "unsignedByte": return value + ".ToString(CultureInfo.InvariantCulture)";
289 case "char": return "((int)(" + value + ")).ToString(CultureInfo.InvariantCulture)";
290 case "dateTime": return value + ".ToString(\"yyyy-MM-ddTHH:mm:ss.fffffffzzz\", CultureInfo.InvariantCulture)";
291 case "date": return value + ".ToString(\"yyyy-MM-dd\", CultureInfo.InvariantCulture)";
292 case "time": return value + ".ToString(\"HH:mm:ss.fffffffzzz\", CultureInfo.InvariantCulture)";
293 case "decimal": return "XmlConvert.ToString (" + value + ")";
294 case "double": return "XmlConvert.ToString (" + value + ")";
295 case "short": return value + ".ToString(CultureInfo.InvariantCulture)";
296 case "int": return value + ".ToString(CultureInfo.InvariantCulture)";
297 case "long": return value + ".ToString(CultureInfo.InvariantCulture)";
298 case "byte": return value + ".ToString(CultureInfo.InvariantCulture)";
299 case "float": return "XmlConvert.ToString (" + value + ")";
300 case "unsignedShort": return value + ".ToString(CultureInfo.InvariantCulture)";
301 case "unsignedInt": return value + ".ToString(CultureInfo.InvariantCulture)";
302 case "unsignedLong": return value + ".ToString(CultureInfo.InvariantCulture)";
303 case "guid": return "XmlConvert.ToString (" + value + ")";
305 case "base64Binary": return "Convert.ToBase64String (" + value + ")";
306 case "duration": return "XmlConvert.ToString (" + value + ")";
316 case "normalizedString":
317 case "string": return value;
318 default: return "((" + value + " != null) ? (" + value + ").ToString() : null)";
322 internal static string GenerateFromXmlString (TypeData type, string value)
324 switch (type.XmlType)
326 case "boolean": return "XmlConvert.ToBoolean (" + value + ")";
327 case "unsignedByte": return "byte.Parse (" + value + ", CultureInfo.InvariantCulture)";
328 case "char": return "(char)Int32.Parse (" + value + ", CultureInfo.InvariantCulture)";
329 case "dateTime": return "XmlConvert.ToDateTime (" + value + ")";
330 case "date": return "DateTime.ParseExact (" + value + ", \"yyyy-MM-dd\", CultureInfo.InvariantCulture)";
331 case "time": return "DateTime.ParseExact (" + value + ", \"HH:mm:ss.fffffffzzz\", CultureInfo.InvariantCulture)";
332 case "decimal": return "Decimal.Parse (" + value + ", CultureInfo.InvariantCulture)";
333 case "double": return "XmlConvert.ToDouble (" + value + ")";
334 case "short": return "Int16.Parse (" + value + ", CultureInfo.InvariantCulture)";
335 case "int": return "Int32.Parse (" + value + ", CultureInfo.InvariantCulture)";
336 case "long": return "Int64.Parse (" + value + ", CultureInfo.InvariantCulture)";
337 case "byte": return "SByte.Parse (" + value + ", CultureInfo.InvariantCulture)";
338 case "float": return "XmlConvert.ToSingle (" + value + ")";
339 case "unsignedShort": return "UInt16.Parse (" + value + ", CultureInfo.InvariantCulture)";
340 case "unsignedInt": return "UInt32.Parse (" + value + ", CultureInfo.InvariantCulture)";
341 case "unsignedLong": return "UInt64.Parse (" + value + ", CultureInfo.InvariantCulture)";
342 case "guid": return "XmlConvert.ToGuid (" + value + ")";
344 case "base64Binary": return "Convert.FromBase64String (" + value + ")";
345 case "duration": return "XmlConvert.ToTimeSpan (" + value + ")";
346 default: return value;
350 #endregion // Methods