< Summary

Class:Azure.Core.RequestUriBuilder
Assembly:Azure.Core
File(s):C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\RequestUriBuilder.cs
Covered lines:95
Uncovered lines:4
Coverable lines:99
Total lines:296
Line coverage:95.9% (95 of 99)
Covered branches:54
Total branches:56
Branch coverage:96.4% (54 of 56)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor()-100%100%
get_Scheme()-100%100%
set_Scheme(...)-100%100%
get_Host()-100%100%
set_Host(...)-100%100%
get_Port()-100%100%
set_Port(...)-100%100%
get_Query()-100%100%
set_Query(...)-100%100%
get_Path()-100%100%
set_Path(...)-57.14%50%
get_HasQuery()-100%100%
get_QueryLength()-100%50%
get_PathLength()-100%100%
get_PathAndQuery()-0%100%
Reset(...)-100%100%
ToUri()-100%100%
AppendQuery(...)-100%100%
AppendQuery(...)-100%100%
AppendPath(...)-100%100%
AppendPath(...)-100%100%
ToString()-100%100%
get_HasDefaultPortForScheme()-100%100%
ResetUri()-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\RequestUriBuilder.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Diagnostics;
 6using System.Text;
 7
 8namespace Azure.Core
 9{
 10    /// <summary>
 11    /// Provides a custom constructor for uniform resource identifiers (URIs) and modifies URIs for the <see cref="Syste
 12    /// </summary>
 13    public class RequestUriBuilder
 14    {
 15        private const char QuerySeparator = '?';
 16
 17        private const char PathSeparator = '/';
 18
 396619        private readonly StringBuilder _pathAndQuery = new StringBuilder();
 20
 396621        private int _queryIndex = -1;
 22
 23        private Uri? _uri;
 24
 25        private int _port;
 26
 27        private string? _host;
 28
 29        private string? _scheme;
 30
 31        /// <summary>
 32        /// Gets or sets the scheme name of the URI.
 33        /// </summary>
 34        public string? Scheme
 35        {
 365636            get => _scheme;
 37            set
 38            {
 386439                ResetUri();
 386440                _scheme = value;
 386441            }
 42        }
 43
 44        /// <summary>
 45        /// Gets or sets the Domain Name System (DNS) host name or IP address of a server.
 46        /// </summary>
 47        public string? Host
 48        {
 238249            get => _host;
 50            set
 51            {
 386452                ResetUri();
 386453                _host = value;
 386454            }
 55        }
 56
 57        /// <summary>
 58        /// Gets or sets the port number of the URI.
 59        /// </summary>
 60        public int Port
 61        {
 654862            get => _port;
 63            set
 64            {
 386465                ResetUri();
 386466                _port = value;
 386467            }
 68        }
 69
 70        /// <summary>
 71        /// Gets or sets any query information included in the URI.
 72        /// </summary>
 73        public string Query
 74        {
 2475            get => HasQuery ? _pathAndQuery.ToString(_queryIndex, _pathAndQuery.Length - _queryIndex) : string.Empty;
 76            set
 77            {
 391678                ResetUri();
 391679                if (HasQuery)
 80                {
 7281                    _pathAndQuery.Remove(_queryIndex, _pathAndQuery.Length - _queryIndex);
 7282                    _queryIndex = -1;
 83                }
 84
 391685                if (!string.IsNullOrEmpty(value))
 86                {
 10087                    _queryIndex = _pathAndQuery.Length;
 10088                    if (value[0] != QuerySeparator)
 89                    {
 1090                        _pathAndQuery.Append(QuerySeparator);
 91                    }
 10092                    _pathAndQuery.Append(value);
 93                }
 391694            }
 95        }
 96
 97        /// <summary>
 98        /// Gets or sets the password associated with the user that accesses the URI and the query information.
 99        /// </summary>
 100        public string Path
 101        {
 24102            get => HasQuery ? _pathAndQuery.ToString(0, _queryIndex) : _pathAndQuery.ToString();
 103            set
 104            {
 3828105                if (HasQuery)
 106                {
 0107                    _pathAndQuery.Remove(0, _queryIndex);
 0108                    _pathAndQuery.Insert(0, value);
 0109                    _queryIndex = value.Length;
 110                }
 111                else
 112                {
 3828113                    _pathAndQuery.Remove(0, _pathAndQuery.Length);
 3828114                    _pathAndQuery.Append(value);
 115                }
 3828116            }
 117        }
 118
 10512119        private bool HasQuery => _queryIndex != -1;
 120
 102121        private int QueryLength => HasQuery ? _pathAndQuery.Length - _queryIndex : 0;
 122
 38123        private int PathLength => HasQuery ? _queryIndex : _pathAndQuery.Length;
 124
 125        /// <summary>
 126        /// Gets the path to the resource referenced by the URI.
 127        /// </summary>
 0128        public string PathAndQuery => _pathAndQuery.ToString();
 129
 130        /// <summary>
 131        /// Replaces values inside this instance with values provided in <paramref name="value"/> parameter.
 132        /// </summary>
 133        /// <param name="value">The <see cref="Uri"/> instance to get values from.</param>
 134        public void Reset(Uri value)
 135        {
 3792136            Scheme = value.Scheme;
 3792137            Host = value.Host;
 3792138            Port = value.Port;
 3792139            Path = value.AbsolutePath;
 3792140            Query = value.Query;
 3792141            _uri = value;
 3792142        }
 143
 144        /// <summary>
 145        /// Gets the <see cref="System.Uri"></see> instance constructed by the specified <see cref="RequestUriBuilder"/>
 146        /// </summary>
 147        /// <returns>
 148        /// A <see cref="System.Uri"></see> that contains the URI constructed by the <see cref="RequestUriBuilder"/>.
 149        /// </returns>
 150        public Uri ToUri()
 151        {
 3366152            if (_uri == null)
 153            {
 182154                _uri = new Uri(ToString());
 155            }
 156
 3366157            return _uri;
 158        }
 159
 160        /// <summary>
 161        /// Appends a query parameter adding separator if required. Escapes the value.
 162        /// </summary>
 163        /// <param name="name">The name of parameter.</param>
 164        /// <param name="value">The value of parameter.</param>
 165        public void AppendQuery(string name, string value)
 166        {
 184167            AppendQuery(name, value, true);
 184168        }
 169
 170        /// <summary>
 171        /// Appends a query parameter adding separator if required.
 172        /// </summary>
 173        /// <param name="name">The name of parameter.</param>
 174        /// <param name="value">The value of parameter.</param>
 175        /// <param name="escapeValue">Whether value should be escaped.</param>
 176        public void AppendQuery(string name, string value, bool escapeValue)
 177        {
 184178            ResetUri();
 184179            if (!HasQuery)
 180            {
 82181                _queryIndex = _pathAndQuery.Length;
 82182                _pathAndQuery.Append(QuerySeparator);
 183            }
 102184            else if (!(QueryLength == 1 && _pathAndQuery[_queryIndex] == QuerySeparator))
 185            {
 100186                _pathAndQuery.Append('&');
 187            }
 188
 184189            _pathAndQuery.Append(name);
 184190            _pathAndQuery.Append('=');
 184191            if (escapeValue && !string.IsNullOrEmpty(value))
 192            {
 182193                value = Uri.EscapeDataString(value);
 194            }
 184195            _pathAndQuery.Append(value);
 196
 197            Debug.Assert(_pathAndQuery[_queryIndex] == QuerySeparator);
 184198        }
 199
 200        /// <summary>
 201        /// Appends escaped <paramref name="value"/> to <see cref="Path"/> without adding path separator.
 202        /// </summary>
 203        /// <param name="value">The value to append.</param>
 204        public void AppendPath(string value)
 205        {
 26206            AppendPath(value, escape: true);
 26207        }
 208
 209        /// <summary>
 210        /// Appends optionally escaped <paramref name="value"/> to <see cref="Path"/> without adding path separator.
 211        /// </summary>
 212        /// <param name="value">The value to append.</param>
 213        /// <param name="escape">Whether value should be escaped.</param>
 214        public void AppendPath(string value, bool escape)
 215        {
 40216            if (string.IsNullOrEmpty(value))
 217            {
 2218                return;
 219            }
 220
 38221            ResetUri();
 38222            int startIndex = 0;
 38223            if (PathLength == 1 && _pathAndQuery[0] == PathSeparator && value[0] == PathSeparator)
 224            {
 6225                startIndex = 1;
 226            }
 38227            if (HasQuery)
 228            {
 4229                string substring = value.Substring(startIndex, value.Length - startIndex);
 4230                if (escape)
 231                {
 4232                    substring = Uri.EscapeDataString(substring);
 233                }
 4234                _pathAndQuery.Insert(_queryIndex, substring);
 4235                _queryIndex += value.Length;
 236            }
 237            else
 238            {
 34239                if (escape)
 240                {
 22241                    string substring = value.Substring(startIndex, value.Length - startIndex);
 22242                    substring = Uri.EscapeDataString(substring);
 22243                    _pathAndQuery.Append(substring);
 244                }
 245                else
 246                {
 12247                    _pathAndQuery.Append(value, startIndex, value.Length - startIndex);
 248                }
 249            }
 12250        }
 251
 252        /// <summary>
 253        /// Returns a string representation of this <see cref="RequestUriBuilder"/> i.
 254        /// </summary>
 255        /// <returns></returns>
 256        public override string ToString()
 257        {
 2358258            var stringBuilder = new StringBuilder();
 2358259            stringBuilder.Append(Scheme);
 2358260            stringBuilder.Append("://");
 2358261            stringBuilder.Append(Host);
 2358262            if (!HasDefaultPortForScheme)
 263            {
 2040264                stringBuilder.Append(':');
 2040265                stringBuilder.Append(Port);
 266            }
 267
 2358268            if (_pathAndQuery.Length == 0 || _pathAndQuery[0] != PathSeparator)
 269            {
 70270                stringBuilder.Append(PathSeparator);
 271            }
 272
 273            // TODO: Escaping can be done in-place
 2358274            if (!HasQuery)
 275            {
 2248276                stringBuilder.Append(_pathAndQuery);
 277            }
 278            else
 279            {
 110280                stringBuilder.Append(_pathAndQuery.ToString(0, _queryIndex));
 110281                stringBuilder.Append(_pathAndQuery.ToString(_queryIndex, _pathAndQuery.Length - _queryIndex));
 282            }
 283
 2358284            return stringBuilder.ToString();
 285        }
 286
 287        private bool HasDefaultPortForScheme =>
 2358288            (Port == 80 && string.Equals(Scheme, "http", StringComparison.InvariantCultureIgnoreCase)) ||
 2358289            (Port == 443 && string.Equals(Scheme, "https", StringComparison.InvariantCultureIgnoreCase));
 290
 291        private void ResetUri()
 292        {
 15730293            _uri = null;
 15730294        }
 295    }
 296}