Esempio n. 1
0
        // TODO: Put strings into the resources.
        //
        public static Type GetIArgsTupleType(ArgumentUtilitiesHandle <IArgsTuple> hnd)
        {
            hnd.EnsureNotNull();
            //
            var args = hnd.Value;

            if (args.ArgsCount < 1)
            {
                return(typeof(IArgsTuple));
            }
            else
            {
                Type result;
                //
                switch (args.ArgsCount - 1)
                {
                case 0:
                    result = typeof(IArgsTuple <>);
                    break;

                case 1:
                    result = typeof(IArgsTuple <,>);
                    break;

                case 2:
                    result = typeof(IArgsTuple <, ,>);
                    break;

                case 3:
                    result = typeof(IArgsTuple <, , ,>);
                    break;

                case 4:
                    result = typeof(IArgsTuple <, , , ,>);
                    break;

                case 5:
                    result = typeof(IArgsTuple <, , , , ,>);
                    break;

                default:
                    throw new ArgumentException(message: $"No generic-type '{nameof(IArgsTuple)}' for the specified tuple of args.{Environment.NewLine}\tTuple:{args.FmtStr().GNLI2()}", paramName: hnd.Name);
                }
                //
                return(result.MakeGenericType(typeArguments: args.ArgsTypes.ToArray()));
            }
        }
Esempio n. 2
0
 public static NameValueCollection GetQueryParameters(this ArgumentUtilitiesHandle <Uri> uri)
 => HttpUtility.ParseQueryString(query: HttpUtility.UrlDecode(str: uri.EnsureNotNull().EnsureAbsolute().Value.Query));
Esempio n. 3
0
        TValue P_GetOrAdd(ArgumentUtilitiesHandle <TKey> key, Func <TKey, TValue> valueFactory, Action <TKey, TValue> valueCleanup, bool keyAbsenceRequired, out bool added, bool keyDisposeTolerant = default, TValue keyDisposeSentinel = default)
        {
            key.EnsureNotNull();
            if (valueFactory is null)
            {
                throw new ArgumentNullException(paramName: nameof(valueFactory));
            }
            //
            valueCleanup = valueCleanup ?? __NopValueCleanup;
            var           isAdded             = false;
            P_ValueHolder newValueHolder      = default;
            P_ValueHolder existingValueHolder = default;
            Exception     caughtException     = default;

            try {
                itrlck
                .Update(
                    location: ref _innerTable,
                    transform:
                    (ImmutableDictionary <TKey, P_ValueHolder> locCurrent) => {
                    ImmutableDictionary <TKey, P_ValueHolder> locChanged;
                    if (keyAbsenceRequired)
                    {
                        try {
                            locChanged = locCurrent.Add(key: key.Value, value: newValueHolder ?? (newValueHolder = new P_ValueHolder()));
                        }
                        catch (ArgumentException locException) {
                            throw
                            new ArgumentException(
                                paramName: key.Name,
                                message: $"Specified key is already exists in this table.{Environment.NewLine}\tKey:{key.Value.FmtStr().GNLI2()}",
                                innerException: locException);
                        }
                    }
                    else
                    {
                        locChanged         = locCurrent;
                        var locValueHolder = ImmutableInterlocked.GetOrAdd(location: ref locChanged, key: key.Value, valueFactory: locKey => newValueHolder ?? (newValueHolder = new P_ValueHolder()));
                        if (ReferenceEquals(locCurrent, locChanged))
                        {
                            // Словарь не был изменён (а значит, в словаре уже присутствовало значение для указанного ключа).
                            //
                            existingValueHolder = locValueHolder;
                        }
                    }
                    if (!ReferenceEquals(locCurrent, locChanged) && newValueHolder.ValueCleanup is null)
                    {
                        newValueHolder.Value        = valueFactory(arg: key.Value);
                        newValueHolder.ValueCleanup = valueCleanup;
                        if (keyDisposeTolerant)
                        {
                            if (key.Value.IsDisposeRequested)
                            {
                                return(locCurrent);
                            }
                            else
                            {
                                try {
                                    key.Value.AfterDisposed += (locSender, locEventArgs) => P_EH_Key_AfterDisposed(sender: locSender, eventArgs: locEventArgs, valueHolder: newValueHolder);
                                }
                                catch (ObjectDisposedException) {
                                    return(locCurrent);
                                }
                            }
                        }
                        else
                        {
                            key.Value.AfterDisposed += (locSender, locEventArgs) => P_EH_Key_AfterDisposed(sender: locSender, eventArgs: locEventArgs, valueHolder: newValueHolder);
                        }
                    }
                    return(locChanged);
                },
                    isUpdated: out isAdded);
                if (isAdded)
                {
                    added = true;
                    return(newValueHolder.Value);
                }
                else if (keyDisposeTolerant)
                {
                    added = false;
                    return(keyDisposeSentinel);
                }
                else
                {
                    added = false;
                    return(existingValueHolder.Value);
                }
            }
            catch (Exception exception) {
                caughtException = exception;
                throw;
            }
            finally {
                if (!(isAdded || newValueHolder is null))
                {
                    try {
                        itrlck.SetNull(location: ref newValueHolder.ValueCleanup)?.Invoke(arg1: key.Value, arg2: newValueHolder.Value);
                    }
                    catch (Exception exception) {
                        if (caughtException is null)
                        {
                            throw;
                        }
                        else
                        {
                            throw new AggregateException(caughtException, exception);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        // TODO: Put strings into the resources.
        //
        /// <summary>
        /// Выполняет парсинг параметров, заданных в виде массива строк.
        /// <para>Каждый элемент массива <paramref name="parameters"/> представляет пару параметр-значение.</para>
        /// <para>Если элемент массива является <see langword="null"/>, пустой строкой или строкой, содержащей только пробельные символы, то этот элемент пропускается.</para>
        /// <para>Ожидаемый формат параметра (элемента массива <paramref name="parameters"/>): &lt;имя параметра&gt;&lt;разделитель имени параметра и значения (<paramref name="parameterNameDelimiter"/>)&gt;&lt;значение параметра&gt;. Значение параметра может быть пустой строкой.</para>
        /// <para>В качестве компаратора ключей словаря, где ключ — имя параметра, используется <see cref="StringComparer.OrdinalIgnoreCase"/>.</para>
        /// </summary>
        /// <param name="parameters">
        /// Массив строк, каждый элемент которого представляет отдельную пару параметр-значение.
        /// <para>Не может быть null.</para>
        /// </param>
        /// <param name="parameterNameDelimiter">
        /// Символ-разделитель имени параметра и его значения.
        /// <para>Не может быть пробельным символом (см. <seealso cref="char.IsWhiteSpace(char)"/>).</para>
        /// </param>
        /// <returns>Словарь <see cref="IDictionary{TKey, TValue}"/>.</returns>
        public static IDictionary <string, string> ParseParametersDictionary(ArgumentUtilitiesHandle <string[]> parameters, ArgumentUtilitiesHandle <char> parameterNameDelimiter)
        {
            parameters.EnsureNotNull();
            if (char.IsWhiteSpace(parameterNameDelimiter.Value))
            {
                throw new ArgumentOutOfRangeException(paramName: parameterNameDelimiter.Name, message: "Значение не может быть пробельным символом.");
            }
            //
            Func <string, char, int, string, string[]> parseArgument =
                (locParametersArrayArgName, locParameterNameDelimiter, locParameterPosition, locParameterText) => {
                if (string.IsNullOrWhiteSpace(locParameterText))
                {
                    return(null);
                }
                else
                {
                    var locNamePart    = new List <char>();
                    var locValuePart   = new List <char>();
                    var locCurrentPart = locNamePart;
                    var locIsParameterNameDelimiterOccurred = false;
                    for (var i = 0; i < locParameterText.Length; i++)
                    {
                        var locCurrentChar = locParameterText[i];
                        if (locCurrentChar == locParameterNameDelimiter)
                        {
                            // Символ-разделитель имени и значения параметра.
                            //
                            if (ReferenceEquals(locCurrentPart, locNamePart))
                            {
                                locIsParameterNameDelimiterOccurred = true;
                                // Удаление конечных "пробелов" в имени.
                                //
                                for (var y = locNamePart.Count - 1; y > -1; y--)
                                {
                                    if (char.IsWhiteSpace(locNamePart[y]))
                                    {
                                        locNamePart.RemoveAt(y);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                if (locNamePart.Count < 1)
                                {
                                    throw
                                        new ArgumentException(
                                            message: $"Параметр в позиции '{locParameterPosition.ToString("d")}' имеет недопустимый формат.{Environment.NewLine}\tПараметр:{locParameterText.FmtStr().GNLI2()}",
                                            paramName: locParametersArrayArgName);
                                }
                                else
                                {
                                    locCurrentPart = locValuePart;
                                }
                            }
                            else
                            {
                                locCurrentPart.Add(locCurrentChar);
                            }
                        }
                        else if (ReferenceEquals(locCurrentPart, locNamePart))
                        {
                            if (locCurrentPart.Count > 0 || !char.IsWhiteSpace(locCurrentChar))
                            {
                                locCurrentPart.Add(locCurrentChar);
                            }
                        }
                        else
                        {
                            locCurrentPart.Add(locCurrentChar);
                        }
                    }
                    //
                    if (!locIsParameterNameDelimiterOccurred || locNamePart.Count < 1)
                    {
                        throw
                            new ArgumentException(
                                message: $"Параметр в позиции '{locParameterPosition.ToString("d")}' имеет недопустимый формат.{Environment.NewLine}\tПараметр:{locParameterText.FmtStr().GNLI2()}",
                                paramName: locParametersArrayArgName);
                    }
                    return
                        (new string[] {
                        new string(locNamePart.ToArray()),
                        locValuePart.Count < 1 ? null : new string(locValuePart.ToArray())
                    });
                }
            };
            //
            var result = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            string[] parameterNameAndValue;
            for (var i = 0; i < parameters.Value.Length; i++)
            {
                parameterNameAndValue =
                    parseArgument(
                        parameters.Name,
                        parameterNameDelimiter.Value,
                        i,
                        parameters.Value[i]);
                if (parameterNameAndValue == null)
                {
                    continue;
                }
                else if (result.ContainsKey(parameterNameAndValue[0]))
                {
                    throw
                        new ArgumentException(
                            message: $"Параметр '{parameters.Value[ i ]}' (в позиции {i.ToString("d")}) указан по меньшей мере дважды. Каждый аргумент должен указываться единажды.",
                            paramName: parameters.Name);
                }
                result.Add(parameterNameAndValue[0], parameterNameAndValue[1]);
            }
            return(result);
        }