1 //------------------------------------------------------------------------------
2 // <copyright file="Scalars.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Web.Services.Protocols {
9 using System.Web.Services;
10 using System.Collections;
11 using System.Globalization;
12 using System.Reflection;
15 using System.Threading;
17 internal class ScalarFormatter {
18 private ScalarFormatter() { }
20 internal static string ToString(object value) {
23 else if (value is string)
25 else if (value.GetType().IsEnum)
26 return EnumToString(value);
28 return (string)Convert.ToString(value, CultureInfo.InvariantCulture);
31 internal static object FromString(string value, Type type) {
33 if (type == typeof(string))
36 return (object)EnumFromString(value, type);
38 return Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
41 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
44 throw new ArgumentException(Res.GetString(Res.WebChangeTypeFailed, value, type.FullName), "type", e);
48 static object EnumFromString(string value, Type type) {
49 return Enum.Parse(type, value);
52 static string EnumToString(object value) {
53 return Enum.Format(value.GetType(), value, "G");
56 // We support: whatever Convert supports, and Enums
57 internal static bool IsTypeSupported(Type type) {
58 if (type.IsEnum) return true;
60 type == typeof(int) ||
61 type == typeof(string) ||
62 type == typeof(long) ||
63 type == typeof(byte) ||
64 type == typeof(sbyte) ||
65 type == typeof(short) ||
66 type == typeof(bool) ||
67 type == typeof(char) ||
68 type == typeof(float) ||
69 type == typeof(decimal) ||
70 type == typeof(DateTime) ||
71 type == typeof(UInt16) ||
72 type == typeof(UInt32) ||
73 type == typeof(UInt64) ||
74 type == typeof(double));
78 internal class UrlEncoder {
79 private UrlEncoder() { }
81 private const int Max16BitUtf8SequenceLength = 4;
83 internal static string EscapeString(string s, Encoding e) {
84 return EscapeStringInternal(s, e == null ? new ASCIIEncoding() : e, false);
87 internal static string UrlEscapeString(string s, Encoding e) {
88 return EscapeStringInternal(s, e == null ? new ASCIIEncoding() : e, true);
91 private static string EscapeStringInternal(string s, Encoding e, bool escapeUriStuff) {
92 if (s == null) return null;
94 byte[] bytes = e.GetBytes(s);
95 StringBuilder sb = new StringBuilder(bytes.Length);
96 for (int i = 0; i < bytes.Length; i++) {
99 if (b > 0x7f || b < 0x20 || c == '%' || (escapeUriStuff && !IsSafe(c))) {
106 return sb.ToString();
110 // [....]: adapted from UrlEscapeStringUnicode below
111 internal static string EscapeStringUnicode(string s) {
113 StringBuilder sb = new StringBuilder(l);
115 for (int i = 0; i < l; i++) {
117 if ((ch & 0xff80) == 0) {
125 return sb.ToString();
129 // [....]: copied from System.Web.HttpUtility
130 internal static string UrlEscapeStringUnicode(string s) {
132 StringBuilder sb = new StringBuilder(l);
134 for (int i = 0; i < l; i++) {
140 else if (ch == ' ') {
143 else if ((ch & 0xff80) == 0) { // 7 bit?
146 else { // arbitrary Unicode?
150 return sb.ToString();
153 private static void HexEscape8(StringBuilder sb, char c) {
155 sb.Append(HexUpperChars[(c >> 4) & 0xf]);
156 sb.Append(HexUpperChars[(c) & 0xf]);
159 private static void HexEscape16(StringBuilder sb, char c) {
161 sb.Append(HexUpperChars[(c >> 12) & 0xf]);
162 sb.Append(HexUpperChars[(c >> 8) & 0xf]);
163 sb.Append(HexUpperChars[(c >> 4) & 0xf]);
164 sb.Append(HexUpperChars[(c) & 0xf]);
167 private static bool IsSafe(char ch) {
168 if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
186 internal static readonly char[] HexUpperChars = {
187 '0', '1', '2', '3', '4', '5', '6', '7',
188 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
192 internal class ContentType {
193 private ContentType() { }
194 internal const string TextBase = "text";
195 internal const string TextXml = "text/xml";
196 internal const string TextPlain = "text/plain";
197 internal const string TextHtml = "text/html";
199 internal const string ApplicationBase = "application";
200 internal const string ApplicationXml = "application/xml";
201 internal const string ApplicationSoap = "application/soap+xml";
202 internal const string ApplicationOctetStream = "application/octet-stream";
204 internal const string ContentEncoding = "Content-Encoding";
206 // this returns the "base" part of the contentType/mimeType, e.g. the "text/xml" part w/o
207 // the ; CharSet=isoxxx part that sometimes follows.
208 internal static string GetBase(string contentType) {
209 int semi = contentType.IndexOf(';');
210 if (semi >= 0) return contentType.Substring(0, semi);
214 // this returns the "type" part of the contentType/mimeType without subtyape
215 internal static string GetMediaType(string contentType) {
216 string baseCT = GetBase(contentType);
217 int tmp = baseCT.IndexOf('/');
218 if (tmp >= 0) return baseCT.Substring(0, tmp);
222 // grabs as follows (and case-insensitive): .*;\s*charset\s*=\s*[\s'"]*(.*)[\s'"]*
223 internal static string GetCharset(string contentType) {
224 return GetParameter(contentType, "charset");
227 internal static string GetAction(string contentType) {
228 return GetParameter(contentType, "action");
231 private static string GetParameter(string contentType, string paramName) {
232 string[] paramDecls = contentType.Split(new char[] { ';' });
233 for (int i = 1; i < paramDecls.Length; i++) {
234 string paramDecl = paramDecls[i].TrimStart(null);
235 if (String.Compare(paramDecl, 0, paramName, 0, paramName.Length, StringComparison.OrdinalIgnoreCase) == 0) {
236 int equals = paramDecl.IndexOf('=', paramName.Length);
238 return paramDecl.Substring(equals + 1).Trim(new char[] { ' ', '\'', '\"', '\t' });
244 internal static bool MatchesBase(string contentType, string baseContentType) {
245 return string.Compare(GetBase(contentType), baseContentType, StringComparison.OrdinalIgnoreCase) == 0;
248 internal static bool IsApplication(string contentType) {
249 return string.Compare(GetMediaType(contentType), ApplicationBase, StringComparison.OrdinalIgnoreCase) == 0;
252 internal static bool IsSoap(string contentType) {
253 string type = GetBase(contentType);
254 return (String.Compare(type, ContentType.TextXml, StringComparison.OrdinalIgnoreCase) == 0) ||
255 (String.Compare(type, ContentType.ApplicationSoap, StringComparison.OrdinalIgnoreCase) == 0);
258 internal static bool IsXml(string contentType) {
259 string type = GetBase(contentType);
260 return (String.Compare(type, ContentType.TextXml, StringComparison.OrdinalIgnoreCase) == 0) ||
261 (String.Compare(type, ContentType.ApplicationXml, StringComparison.OrdinalIgnoreCase) == 0);
264 internal static bool IsHtml(string contentType) {
265 string type = GetBase(contentType);
266 return String.Compare(type, ContentType.TextHtml, StringComparison.OrdinalIgnoreCase) == 0;
269 internal static string Compose(string contentType, Encoding encoding) {
270 return Compose(contentType, encoding, null);
273 internal static string Compose(string contentType, Encoding encoding, string action) {
274 if (encoding == null && action == null) return contentType;
276 StringBuilder sb = new StringBuilder(contentType);
277 if (encoding != null) {
278 sb.Append("; charset=");
279 sb.Append(encoding.WebName);
281 if (action != null) {
282 sb.Append("; action=\"");
286 return sb.ToString();
290 internal class MemberHelper {
291 private MemberHelper() { }
292 static object[] emptyObjectArray = new object[0];
294 internal static void SetValue(MemberInfo memberInfo, object target, object value) {
295 if (memberInfo is FieldInfo ) {
296 ((FieldInfo)memberInfo).SetValue(target, value);
299 ((PropertyInfo)memberInfo).SetValue(target, value, emptyObjectArray);
303 internal static object GetValue(MemberInfo memberInfo, object target) {
304 if (memberInfo is FieldInfo) {
305 return ((FieldInfo)memberInfo).GetValue(target);
308 return ((PropertyInfo)memberInfo).GetValue(target, emptyObjectArray);
312 internal static bool IsStatic(MemberInfo memberInfo) {
313 if (memberInfo is FieldInfo)
314 return ((FieldInfo)memberInfo).IsStatic;
319 internal static bool CanRead(MemberInfo memberInfo) {
320 if (memberInfo is FieldInfo)
323 return ((PropertyInfo)memberInfo).CanRead;
326 internal static bool CanWrite(MemberInfo memberInfo) {
327 if (memberInfo is FieldInfo)
330 return ((PropertyInfo)memberInfo).CanWrite;