< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Dispatcher.QueryStringConverter
Assembly: CoreWCF.WebHttp
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Dispatcher/QueryStringConverter.cs
Line coverage
21%
Covered lines: 30
Uncovered lines: 110
Coverable lines: 140
Total lines: 330
Line coverage: 21.4%
Branch coverage
2%
Covered branches: 3
Total branches: 140
Branch coverage: 2.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%11100%
CanConvert(...)25%4440%
ConvertStringToValue(...)2.66%75757.31%
ConvertValueToString(...)0%43430%
GetStringConverter(...)0%18180%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Dispatcher/QueryStringConverter.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections;
 6using System.ComponentModel;
 7using System.Diagnostics;
 8using System.Globalization;
 9using System.Reflection;
 10using System.Runtime.InteropServices;
 11using System.Xml;
 12using CoreWCF.Runtime;
 13
 14namespace CoreWCF.Dispatcher
 15{
 16    public class QueryStringConverter
 17    {
 18        private readonly Hashtable _defaultSupportedQueryStringTypes;
 19
 20        // the cache does not have a quota since it is per endpoint and is
 21        // bounded by the number of types in the contract at the endpoint
 22        private readonly Hashtable _typeConverterCache;
 23
 32624        public QueryStringConverter()
 25        {
 32626            _defaultSupportedQueryStringTypes = new Hashtable();
 32627            _defaultSupportedQueryStringTypes.Add(typeof(byte), null);
 32628            _defaultSupportedQueryStringTypes.Add(typeof(sbyte), null);
 32629            _defaultSupportedQueryStringTypes.Add(typeof(short), null);
 32630            _defaultSupportedQueryStringTypes.Add(typeof(int), null);
 32631            _defaultSupportedQueryStringTypes.Add(typeof(long), null);
 32632            _defaultSupportedQueryStringTypes.Add(typeof(ushort), null);
 32633            _defaultSupportedQueryStringTypes.Add(typeof(uint), null);
 32634            _defaultSupportedQueryStringTypes.Add(typeof(ulong), null);
 32635            _defaultSupportedQueryStringTypes.Add(typeof(float), null);
 32636            _defaultSupportedQueryStringTypes.Add(typeof(double), null);
 32637            _defaultSupportedQueryStringTypes.Add(typeof(bool), null);
 32638            _defaultSupportedQueryStringTypes.Add(typeof(char), null);
 32639            _defaultSupportedQueryStringTypes.Add(typeof(decimal), null);
 32640            _defaultSupportedQueryStringTypes.Add(typeof(string), null);
 32641            _defaultSupportedQueryStringTypes.Add(typeof(object), null);
 32642            _defaultSupportedQueryStringTypes.Add(typeof(DateTime), null);
 32643            _defaultSupportedQueryStringTypes.Add(typeof(TimeSpan), null);
 32644            _defaultSupportedQueryStringTypes.Add(typeof(byte[]), null);
 32645            _defaultSupportedQueryStringTypes.Add(typeof(Guid), null);
 32646            _defaultSupportedQueryStringTypes.Add(typeof(Uri), null);
 32647            _defaultSupportedQueryStringTypes.Add(typeof(DateTimeOffset), null);
 32648            _typeConverterCache = new Hashtable();
 32649        }
 50
 51        public virtual bool CanConvert(Type type)
 52        {
 1653            if (_defaultSupportedQueryStringTypes.ContainsKey(type))
 54            {
 1655                return true;
 56            }
 57
 58            // otherwise check if its an enum
 059            if (typeof(Enum).IsAssignableFrom(type))
 60            {
 061                return true;
 62            }
 63
 64            // check if there's a typeconverter defined on the type
 065            return (GetStringConverter(type) != null);
 66        }
 67
 68        public virtual object ConvertStringToValue(string parameter, Type parameterType)
 69        {
 170            if (parameterType == null)
 71            {
 072                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(parameterType));
 73            }
 74
 175            switch (Type.GetTypeCode(parameterType))
 76            {
 77                case TypeCode.Byte:
 078                    return parameter == null ? default : XmlConvert.ToByte(parameter);
 79                case TypeCode.SByte:
 080                    return parameter == null ? default : XmlConvert.ToSByte(parameter);
 81                case TypeCode.Int16:
 082                    return parameter == null ? default : XmlConvert.ToInt16(parameter);
 83                case TypeCode.Int32:
 84                    {
 085                        if (typeof(Enum).IsAssignableFrom(parameterType))
 86                        {
 087                            return Enum.Parse(parameterType, parameter, true);
 88                        }
 89                        else
 90                        {
 091                            return parameter == null ? default : XmlConvert.ToInt32(parameter);
 92                        }
 93                    }
 94                case TypeCode.Int64:
 095                    return parameter == null ? default : XmlConvert.ToInt64(parameter);
 96                case TypeCode.UInt16:
 097                    return parameter == null ? default : XmlConvert.ToUInt16(parameter);
 98                case TypeCode.UInt32:
 099                    return parameter == null ? default : XmlConvert.ToUInt32(parameter);
 100                case TypeCode.UInt64:
 0101                    return parameter == null ? default : XmlConvert.ToUInt64(parameter);
 102                case TypeCode.Single:
 0103                    return parameter == null ? default : XmlConvert.ToSingle(parameter);
 104                case TypeCode.Double:
 0105                    return parameter == null ? default : XmlConvert.ToDouble(parameter);
 106                case TypeCode.Char:
 0107                    return parameter == null ? default : XmlConvert.ToChar(parameter);
 108                case TypeCode.Decimal:
 0109                    return parameter == null ? default : XmlConvert.ToDecimal(parameter);
 110                case TypeCode.Boolean:
 0111                    return parameter == null ? default : Convert.ToBoolean(parameter, CultureInfo.InvariantCulture);
 112                case TypeCode.String:
 1113                    return parameter;
 114                case TypeCode.DateTime:
 0115                    return parameter == null ? default : DateTime.Parse(parameter, CultureInfo.InvariantCulture, DateTim
 116                default:
 117                    {
 0118                        if (parameterType == typeof(TimeSpan))
 119                        {
 120                            // support the XML as well as default way of representing timespans
 121                            TimeSpan result;
 0122                            if (!TimeSpan.TryParse(parameter, out result))
 123                            {
 0124                                result = parameter == null ? default : XmlConvert.ToTimeSpan(parameter);
 125                            }
 0126                            return result;
 127                        }
 0128                        else if (parameterType == typeof(Guid))
 129                        {
 0130                            return parameter == null ? default : XmlConvert.ToGuid(parameter);
 131                        }
 0132                        else if (parameterType == typeof(DateTimeOffset))
 133                        {
 0134                            return (parameter == null) ? default : DateTimeOffset.Parse(parameter, CultureInfo.Invariant
 135                        }
 0136                        else if (parameterType == typeof(byte[]))
 137                        {
 0138                            return (!string.IsNullOrEmpty(parameter)) ? Convert.FromBase64String(parameter) : new byte[]
 139                        }
 0140                        else if (parameterType == typeof(Uri))
 141                        {
 0142                            return (!string.IsNullOrEmpty(parameter)) ? new Uri(parameter, UriKind.RelativeOrAbsolute) :
 143                        }
 0144                        else if (parameterType == typeof(object))
 145                        {
 0146                            return parameter;
 147                        }
 148                        else
 149                        {
 0150                            TypeConverter stringConverter = GetStringConverter(parameterType);
 0151                            if (stringConverter == null)
 152                            {
 0153                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(
 0154                                    SR.Format(
 0155                                    SR.TypeNotSupportedByQueryStringConverter,
 0156                                    parameterType.ToString(), GetType().Name)));
 157                            }
 158
 0159                            return stringConverter.ConvertFromInvariantString(parameter);
 160                        }
 161                    }
 162            }
 163        }
 164
 165        public virtual string ConvertValueToString(object parameter, Type parameterType)
 166        {
 0167            if (parameterType == null)
 168            {
 0169                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(parameterType));
 170            }
 171
 0172            if (parameterType.IsValueType && parameter == null)
 173            {
 0174                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(parameter));
 175            }
 176
 0177            switch (Type.GetTypeCode(parameterType))
 178            {
 179                case TypeCode.Byte:
 0180                    return XmlConvert.ToString((byte)parameter);
 181                case TypeCode.SByte:
 0182                    return XmlConvert.ToString((sbyte)parameter);
 183                case TypeCode.Int16:
 0184                    return XmlConvert.ToString((short)parameter);
 185                case TypeCode.Int32:
 186                    {
 0187                        if (typeof(Enum).IsAssignableFrom(parameterType))
 188                        {
 0189                            return Enum.Format(parameterType, parameter, "G");
 190                        }
 191                        else
 192                        {
 0193                            return XmlConvert.ToString((int)parameter);
 194                        }
 195                    }
 196                case TypeCode.Int64:
 0197                    return XmlConvert.ToString((long)parameter);
 198                case TypeCode.UInt16:
 0199                    return XmlConvert.ToString((ushort)parameter);
 200                case TypeCode.UInt32:
 0201                    return XmlConvert.ToString((uint)parameter);
 202                case TypeCode.UInt64:
 0203                    return XmlConvert.ToString((ulong)parameter);
 204                case TypeCode.Single:
 0205                    return XmlConvert.ToString((float)parameter);
 206                case TypeCode.Double:
 0207                    return XmlConvert.ToString((double)parameter);
 208                case TypeCode.Char:
 0209                    return XmlConvert.ToString((char)parameter);
 210                case TypeCode.Decimal:
 0211                    return XmlConvert.ToString((decimal)parameter);
 212                case TypeCode.Boolean:
 0213                    return XmlConvert.ToString((bool)parameter);
 214                case TypeCode.String:
 0215                    return (string)parameter;
 216                case TypeCode.DateTime:
 0217                    return XmlConvert.ToString((DateTime)parameter, XmlDateTimeSerializationMode.RoundtripKind);
 218                default:
 219                    {
 0220                        if (parameterType == typeof(TimeSpan))
 221                        {
 0222                            return XmlConvert.ToString((TimeSpan)parameter);
 223                        }
 0224                        else if (parameterType == typeof(Guid))
 225                        {
 0226                            return XmlConvert.ToString((Guid)parameter);
 227                        }
 0228                        else if (parameterType == typeof(DateTimeOffset))
 229                        {
 0230                            return XmlConvert.ToString((DateTimeOffset)parameter);
 231                        }
 0232                        else if (parameterType == typeof(byte[]))
 233                        {
 0234                            return (parameter != null) ? Convert.ToBase64String((byte[])parameter, Base64FormattingOptio
 235                        }
 0236                        else if (parameterType == typeof(Uri) || parameterType == typeof(object))
 237                        {
 238                            // URI or object
 0239                            return (parameter != null) ? Convert.ToString(parameter, CultureInfo.InvariantCulture) : nul
 240                        }
 241                        else
 242                        {
 0243                            TypeConverter stringConverter = GetStringConverter(parameterType);
 0244                            if (stringConverter == null)
 245                            {
 0246                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(
 0247                                    SR.Format(
 0248                                    SR.TypeNotSupportedByQueryStringConverter,
 0249                                    parameterType.ToString(), GetType().Name)));
 250                            }
 251                            else
 252                            {
 0253                                return stringConverter.ConvertToInvariantString(parameter);
 254                            }
 255                        }
 256                    }
 257            }
 258        }
 259
 260        // hash table is safe for multiple readers single writer
 261        private TypeConverter GetStringConverter(Type parameterType)
 262        {
 0263            if (_typeConverterCache.ContainsKey(parameterType))
 264            {
 0265                return (TypeConverter)_typeConverterCache[parameterType];
 266            }
 267
 0268            if (parameterType.GetCustomAttributes(typeof(TypeConverterAttribute), true) is TypeConverterAttribute[] type
 269            {
 0270                foreach (TypeConverterAttribute converterAttr in typeConverterAttrs)
 271                {
 0272                    Type converterType = Type.GetType(converterAttr.ConverterTypeName, false, true);
 0273                    if (converterType != null)
 274                    {
 0275                        TypeConverter converter = null;
 0276                        Exception handledException = null;
 277                        try
 278                        {
 0279                            converter = (TypeConverter)Activator.CreateInstance(converterType);
 0280                        }
 281                        catch (TargetInvocationException e)
 282                        {
 0283                            handledException = e;
 0284                        }
 285                        catch (MemberAccessException e)
 286                        {
 0287                            handledException = e;
 0288                        }
 289                        catch (TypeLoadException e)
 290                        {
 0291                            handledException = e;
 0292                        }
 293                        catch (COMException e)
 294                        {
 0295                            handledException = e;
 0296                        }
 297                        catch (InvalidComObjectException e)
 298                        {
 0299                            handledException = e;
 0300                        }
 301                        finally
 302                        {
 0303                            if (handledException != null)
 304                            {
 0305                                if (Fx.IsFatal(handledException))
 306                                {
 0307                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(handledException);
 308                                }
 0309                                DiagnosticUtility.TraceHandledException(handledException, TraceEventType.Warning);
 310                            }
 0311                        }
 312
 0313                        if (converter == null)
 314                        {
 315                            continue;
 316                        }
 317
 0318                        if (converter.CanConvertTo(typeof(string)) && converter.CanConvertFrom(typeof(string)))
 319                        {
 0320                            _typeConverterCache.Add(parameterType, converter);
 0321                            return converter;
 322                        }
 323                    }
 324                }
 325            }
 326
 0327            return null;
 328        }
 329    }
 330}