1 //------------------------------------------------------------------------------
2 // <copyright file="XmlCustomFormatter.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">[....]</owner>
6 //------------------------------------------------------------------------------
7 namespace System.Xml.Serialization {
11 using System.Globalization;
12 using System.ComponentModel;
13 using System.Diagnostics;
14 using System.Diagnostics.CodeAnalysis;
16 using System.Collections;
17 using System.Configuration;
18 using System.Xml.Serialization.Configuration;
21 /// The <see cref="XmlCustomFormatter"/> class provides a set of static methods for converting
22 /// primitive type values to and from their XML string representations.</summary>
23 internal class XmlCustomFormatter {
25 private static DateTimeSerializationSection.DateTimeSerializationMode mode;
27 static DateTimeSerializationSection.DateTimeSerializationMode Mode {
28 [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety")]
30 if (mode == DateTimeSerializationSection.DateTimeSerializationMode.Default) {
31 DateTimeSerializationSection section = PrivilegedConfigurationManager.GetSection(ConfigurationStrings.DateTimeSerializationSectionPath) as DateTimeSerializationSection;
32 if (section != null) {
36 mode = DateTimeSerializationSection.DateTimeSerializationMode.Roundtrip;
43 private XmlCustomFormatter() {}
44 internal static string FromDefaultValue(object value, string formatter) {
45 if (value == null) return null;
46 Type type = value.GetType();
47 if (type == typeof(DateTime)) {
48 if (formatter == "DateTime") {
49 return FromDateTime((DateTime)value);
51 if (formatter == "Date") {
52 return FromDate((DateTime)value);
54 if (formatter == "Time") {
55 return FromTime((DateTime)value);
58 else if (type == typeof(string)) {
59 if (formatter == "XmlName") {
60 return FromXmlName((string)value);
62 if (formatter == "XmlNCName") {
63 return FromXmlNCName((string)value);
65 if (formatter == "XmlNmToken") {
66 return FromXmlNmToken((string)value);
68 if (formatter == "XmlNmTokens") {
69 return FromXmlNmTokens((string)value);
72 throw new Exception(Res.GetString(Res.XmlUnsupportedDefaultType, type.FullName));
75 internal static string FromDate(DateTime value) {
76 return XmlConvert.ToString(value, "yyyy-MM-dd");
79 internal static string FromTime(DateTime value) {
80 return XmlConvert.ToString(DateTime.MinValue + value.TimeOfDay, "HH:mm:ss.fffffffzzzzzz");
83 internal static string FromDateTime(DateTime value) {
85 if (Mode == DateTimeSerializationSection.DateTimeSerializationMode.Local) {
86 return XmlConvert.ToString(value, "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz");
89 // for mode DateTimeSerializationMode.Roundtrip and DateTimeSerializationMode.Default
90 return XmlConvert.ToString(value, XmlDateTimeSerializationMode.RoundtripKind);
93 internal static string FromChar(char value) {
94 return XmlConvert.ToString((UInt16)value);
97 internal static string FromXmlName(string name) {
98 return XmlConvert.EncodeName(name);
101 internal static string FromXmlNCName(string ncName) {
102 return XmlConvert.EncodeLocalName(ncName);
105 internal static string FromXmlNmToken(string nmToken) {
106 return XmlConvert.EncodeNmToken(nmToken);
109 internal static string FromXmlNmTokens(string nmTokens) {
110 if (nmTokens == null)
112 if (nmTokens.IndexOf(' ') < 0)
113 return FromXmlNmToken(nmTokens);
115 string[] toks = nmTokens.Split(new char[] { ' ' });
116 StringBuilder sb = new StringBuilder();
117 for (int i = 0; i < toks.Length; i++) {
118 if (i > 0) sb.Append(' ');
119 sb.Append(FromXmlNmToken(toks[i]));
121 return sb.ToString();
125 internal static void WriteArrayBase64(XmlWriter writer, byte[] inData, int start, int count) {
126 if (inData == null || count == 0) {
129 writer.WriteBase64(inData, start, count);
132 internal static string FromByteArrayHex(byte[] value) {
135 if (value.Length == 0)
137 return XmlConvert.ToBinHexString(value);
140 internal static string FromEnum(long val, string[] vals, long[] ids, string typeName) {
142 // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
143 if (ids.Length != vals.Length) throw new InvalidOperationException(Res.GetString(Res.XmlInternalErrorDetails, "Invalid enum"));
146 long originalValue = val;
147 StringBuilder sb = new StringBuilder();
150 for (int i = 0; i < ids.Length; i++) {
158 if ((ids[i] & originalValue) == ids[i]) {
166 // failed to parse the enum value
167 throw new InvalidOperationException(Res.GetString(Res.XmlUnknownConstant, originalValue, typeName == null ? "enum" : typeName));
169 if (sb.Length == 0 && iZero >= 0) {
170 sb.Append(vals[iZero]);
172 return sb.ToString();
175 internal static object ToDefaultValue(string value, string formatter) {
176 if (formatter == "DateTime") {
177 return ToDateTime(value);
179 if (formatter == "Date") {
180 return ToDate(value);
182 if (formatter == "Time") {
183 return ToTime(value);
185 if (formatter == "XmlName") {
186 return ToXmlName(value);
188 if (formatter == "XmlNCName") {
189 return ToXmlNCName(value);
191 if (formatter == "XmlNmToken") {
192 return ToXmlNmToken(value);
194 if (formatter == "XmlNmTokens") {
195 return ToXmlNmTokens(value);
197 throw new Exception(Res.GetString(Res.XmlUnsupportedDefaultValue, formatter));
198 // Debug.WriteLineIf(CompModSwitches.XmlSerialization.TraceVerbose, "XmlSerialization::Unhandled default value " + value + " formatter " + formatter);
199 // return DBNull.Value;
202 static string[] allDateTimeFormats = new string[] {
203 "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz",
241 "HH:mm:ss.fffzzzzzz",
242 "HH:mm:ss.ffffzzzzzz",
243 "HH:mm:ss.fffffzzzzzz",
244 "HH:mm:ss.ffffffzzzzzz",
245 "HH:mm:ss.fffffffzzzzzz",
246 "yyyy-MM-ddTHH:mm:ss",
247 "yyyy-MM-ddTHH:mm:ss.f",
248 "yyyy-MM-ddTHH:mm:ss.ff",
249 "yyyy-MM-ddTHH:mm:ss.fff",
250 "yyyy-MM-ddTHH:mm:ss.ffff",
251 "yyyy-MM-ddTHH:mm:ss.fffff",
252 "yyyy-MM-ddTHH:mm:ss.ffffff",
253 "yyyy-MM-ddTHH:mm:ss.fffffff",
254 "yyyy-MM-ddTHH:mm:ssZ",
255 "yyyy-MM-ddTHH:mm:ss.fZ",
256 "yyyy-MM-ddTHH:mm:ss.ffZ",
257 "yyyy-MM-ddTHH:mm:ss.fffZ",
258 "yyyy-MM-ddTHH:mm:ss.ffffZ",
259 "yyyy-MM-ddTHH:mm:ss.fffffZ",
260 "yyyy-MM-ddTHH:mm:ss.ffffffZ",
261 "yyyy-MM-ddTHH:mm:ss.fffffffZ",
262 "yyyy-MM-ddTHH:mm:sszzzzzz",
263 "yyyy-MM-ddTHH:mm:ss.fzzzzzz",
264 "yyyy-MM-ddTHH:mm:ss.ffzzzzzz",
265 "yyyy-MM-ddTHH:mm:ss.fffzzzzzz",
266 "yyyy-MM-ddTHH:mm:ss.ffffzzzzzz",
267 "yyyy-MM-ddTHH:mm:ss.fffffzzzzzz",
268 "yyyy-MM-ddTHH:mm:ss.ffffffzzzzzz",
271 static string[] allDateFormats = new string[] {
291 static string[] allTimeFormats = new string[] {
292 "HH:mm:ss.fffffffzzzzzz",
312 "HH:mm:ss.fffzzzzzz",
313 "HH:mm:ss.ffffzzzzzz",
314 "HH:mm:ss.fffffzzzzzz",
315 "HH:mm:ss.ffffffzzzzzz",
318 internal static DateTime ToDateTime(string value) {
319 #if CONFIGURATION_DEP
320 if (Mode == DateTimeSerializationSection.DateTimeSerializationMode.Local) {
321 return ToDateTime(value, allDateTimeFormats);
326 // for mode DateTimeSerializationMode.Roundtrip and DateTimeSerializationMode.Default
327 return XmlConvert.ToDateTime(value, XmlDateTimeSerializationMode.RoundtripKind);
331 internal static DateTime ToDateTime(string value, string[] formats) {
332 return XmlConvert.ToDateTime(value, formats);
335 internal static DateTime ToDate(string value) {
336 return ToDateTime(value, allDateFormats);
339 internal static DateTime ToTime(string value) {
340 return DateTime.ParseExact(value, allTimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AllowLeadingWhite|DateTimeStyles.AllowTrailingWhite|DateTimeStyles.NoCurrentDateDefault);
343 internal static char ToChar(string value) {
344 return (char)XmlConvert.ToUInt16(value);
347 internal static string ToXmlName(string value) {
348 return XmlConvert.DecodeName(CollapseWhitespace(value));
351 internal static string ToXmlNCName(string value) {
352 return XmlConvert.DecodeName(CollapseWhitespace(value));
355 internal static string ToXmlNmToken(string value) {
356 return XmlConvert.DecodeName(CollapseWhitespace(value));
359 internal static string ToXmlNmTokens(string value) {
360 return XmlConvert.DecodeName(CollapseWhitespace(value));
363 internal static byte[] ToByteArrayBase64(string value) {
364 if (value == null) return null;
365 value = value.Trim();
366 if (value.Length == 0)
368 return Convert.FromBase64String(value);
370 internal static byte[] ToByteArrayHex(string value) {
371 if (value == null) return null;
372 value = value.Trim();
373 return XmlConvert.FromBinHexString(value);
376 internal static long ToEnum(string val, Hashtable vals, string typeName, bool validate) {
378 string[] parts = val.Split(null);
379 for (int i = 0; i < parts.Length; i++) {
380 object id = vals[parts[i]];
383 else if (validate && parts[i].Length > 0)
384 throw new InvalidOperationException(Res.GetString(Res.XmlUnknownConstant, parts[i], typeName));
389 static string CollapseWhitespace(string value) {