< Summary

Class:Azure.Core.ConnectionString
Assembly:Azure.Data.AppConfiguration
File(s):C:\Git\azure-sdk-for-net\sdk\core\Azure.Core\src\Shared\ConnectionString.cs
Covered lines:43
Uncovered lines:23
Coverable lines:66
Total lines:176
Line coverage:65.1% (43 of 66)
Covered branches:24
Total branches:44
Branch coverage:54.5% (24 of 44)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
Parse(...)-100%100%
.ctor(...)-100%100%
GetRequired(...)-100%50%
GetNonRequired(...)-0%0%
Replace(...)-0%0%
ToString()-0%0%
ParseSegments(...)-92.86%75%
TryGetNextSegment(...)-100%100%
Validate(...)-60%57.14%

File(s)

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

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4#nullable enable
 5
 6using System;
 7using System.Collections.Generic;
 8using System.Text;
 9
 10namespace Azure.Core
 11{
 12    internal sealed class ConnectionString
 13    {
 14        private readonly Dictionary<string, string> _pairs;
 15        private readonly string _pairSeparator;
 16        private readonly string _keywordValueSeparator;
 17
 18        public static ConnectionString Parse(string connectionString, string segmentSeparator = ";", string keywordValue
 19        {
 32020            Validate(connectionString, segmentSeparator, keywordValueSeparator, allowEmptyValues);
 32021            return new ConnectionString(ParseSegments(connectionString, segmentSeparator, keywordValueSeparator), segmen
 22        }
 23
 32024        private ConnectionString(Dictionary<string, string> pairs, string pairSeparator, string keywordValueSeparator)
 25        {
 32026            _pairs = pairs;
 32027            _pairSeparator = pairSeparator;
 32028            _keywordValueSeparator = keywordValueSeparator;
 32029        }
 30
 31        public string GetRequired(string keyword) =>
 96032            _pairs.TryGetValue(keyword, out var value) ? value : throw new InvalidOperationException($"Required keyword 
 33
 34        public string? GetNonRequired(string keyword) =>
 035            _pairs.TryGetValue(keyword, out var value) ? value : null;
 36
 37        public void Replace(string keyword, string value)
 38        {
 039            if (_pairs.ContainsKey(keyword))
 40            {
 041                _pairs[keyword] = value;
 42            }
 043        }
 44
 45        public override string ToString()
 46        {
 047            var stringBuilder = new StringBuilder();
 048            var isFirst = true;
 049            foreach (KeyValuePair<string, string> pair in _pairs)
 50            {
 051                if (isFirst)
 52                {
 053                    isFirst = false;
 54                }
 55                else
 56                {
 057                    stringBuilder.Append(_pairSeparator);
 58                }
 59
 060                stringBuilder.Append(pair.Key);
 061                if (pair.Value != null)
 62                {
 063                    stringBuilder.Append(_keywordValueSeparator).Append(pair.Value);
 64                }
 65            }
 66
 067            return stringBuilder.ToString();
 68        }
 69
 70        private static Dictionary<string, string> ParseSegments(in string connectionString, in string separator, in stri
 71        {
 32072            var pairs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 73
 32074            var segmentStart = -1;
 32075            var segmentEnd = 0;
 76
 128077            while (TryGetNextSegment(connectionString, separator, ref segmentStart, ref segmentEnd))
 78            {
 96079                var kvSeparatorIndex = connectionString.IndexOf(keywordValueSeparator, segmentStart, segmentEnd - segmen
 96080                int keywordStart = GetStart(connectionString, segmentStart);
 96081                int keyLength = GetLength(connectionString, keywordStart, kvSeparatorIndex);
 82
 96083                var keyword = connectionString.Substring(keywordStart, keyLength);
 96084                if (pairs.ContainsKey(keyword))
 85                {
 086                    throw new InvalidOperationException($"Duplicated keyword '{keyword}'");
 87                }
 88
 96089                var valueStart = GetStart(connectionString, kvSeparatorIndex + keywordValueSeparator.Length);
 96090                var valueLength = GetLength(connectionString, valueStart, segmentEnd);
 96091                pairs.Add(keyword, connectionString.Substring(valueStart, valueLength));
 92            }
 93
 32094            return pairs;
 95
 96            static int GetStart(in string str, int start)
 97            {
 192098                while (start < str.Length && char.IsWhiteSpace(str[start]))
 99                {
 0100                    start++;
 101                }
 102
 1920103                return start;
 104            }
 105
 106            static int GetLength(in string str, in int start, int end)
 107            {
 1920108                while (end > start && char.IsWhiteSpace(str[end - 1]))
 109                {
 0110                    end--;
 111                }
 112
 1920113                return end - start;
 114            }
 115        }
 116
 117        private static bool TryGetNextSegment(in string str, in string separator, ref int start, ref int end)
 118        {
 2560119            if (start == -1)
 120            {
 640121                start = 0;
 122            }
 123            else
 124            {
 1920125                start = end + separator.Length;
 1920126                if (start >= str.Length)
 127                {
 640128                    return false;
 129                }
 130            }
 131
 1920132            end = str.IndexOf(separator, start, StringComparison.Ordinal);
 1920133            if (end == -1)
 134            {
 264135                end = str.Length;
 136            }
 137
 1920138            return true;
 139        }
 140
 141        private static void Validate(string connectionString, string segmentSeparator, string keywordValueSeparator, boo
 142        {
 320143            var segmentStart = -1;
 320144            var segmentEnd = 0;
 145
 1280146            while (TryGetNextSegment(connectionString, segmentSeparator, ref segmentStart, ref segmentEnd))
 147            {
 960148                if (segmentStart == segmentEnd)
 149                {
 0150                    if (segmentStart == 0)
 151                    {
 0152                        throw new InvalidOperationException($"Connection string starts with separator '{segmentSeparator
 153                    }
 154
 0155                    throw new InvalidOperationException($"Connection string contains two following separators '{segmentS
 156                }
 157
 960158                var kvSeparatorIndex = connectionString.IndexOf(keywordValueSeparator, segmentStart, segmentEnd - segmen
 960159                if (kvSeparatorIndex == -1)
 160                {
 0161                    throw new InvalidOperationException($"Connection string doesn't have value for keyword '{connectionS
 162                }
 163
 960164                if (segmentStart == kvSeparatorIndex)
 165                {
 0166                    throw new InvalidOperationException($"Connection string has value '{connectionString.Substring(segme
 167                }
 168
 960169                if (!allowEmptyValues && kvSeparatorIndex + 1 == segmentEnd)
 170                {
 0171                    throw new InvalidOperationException($"Connection string has keyword '{connectionString.Substring(seg
 172                }
 173            }
 320174        }
 175    }
 176}