Пример #1
0
        /// <summary>
        /// Parses a continuous hex stream from a string.
        /// </summary>
        /// <param name="s">A string containing continuous hex values without delimiters.</param>
        /// <returns>A byte array containing the hex values as bytes.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="s"/> does not consist of event amount of hex digits, or parsing failed.</exception>
        public static byte[] ParseHexBytes(this string s)
        {
            if (s == null)
            {
                Throw.ArgumentNullException(Argument.s);
            }

            if (s.Length == 0)
            {
                return(Reflector.EmptyArray <byte>());
            }

            if ((s.Length & 1) != 0)
            {
                Throw.ArgumentException(Argument.s, Res.StringExtensionsSourceLengthNotEven);
            }

            byte[] result = new byte[s.Length >> 1];
            for (int i = 0; i < result.Length; i++)
            {
                if (!Parser.TryParseHexByte(s, i << 1, out result[i]))
                {
                    Throw.ArgumentException(Argument.s, Res.StringExtensionsCannotParseAsType(s.Substring(i << 1, 2), Reflector.ByteType));
                }
            }

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Parses separated decimal bytes from a string.
        /// </summary>
        /// <param name="s">A string containing delimited decimal integer numbers.</param>
        /// <param name="separator">A separator delimiting the values.</param>
        /// <returns>A byte array containing the decimal values as bytes.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="separator"/> is <see langword="null"/>&#160;or empty.</exception>
        /// <exception cref="FormatException"><paramref name="s"/> is not of the correct format.</exception>
        /// <exception cref="OverflowException">A value in <paramref name="s"/> does not fit in the range of a <see cref="byte">byte</see> value.</exception>
        public static byte[] ParseDecimalBytes(this string s, string separator)
        {
            if (s == null)
            {
                Throw.ArgumentNullException(Argument.s);
            }

            if (String.IsNullOrEmpty(separator))
            {
                Throw.ArgumentException(Argument.separator, Res.StringExtensionsSeparatorNullOrEmpty);
            }

            List <StringSegmentInternal> values = new StringSegmentInternal(s).Split(separator);
            int len = values.Count;

            byte[] result = new byte[len];
            for (int i = 0; i < len; i++)
            {
                StringSegmentInternal segment = values[i];
                segment.Trim();
                if (!segment.TryParseIntQuick(false, Byte.MaxValue, out ulong value))
                {
                    Throw.ArgumentException(Argument.s, Res.StringExtensionsCannotParseAsType(segment.ToString(), Reflector.ByteType));
                }
                result[i] = (byte)value;
            }

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Parses delimited hex values from a string into an array of bytes.
        /// </summary>
        /// <param name="s">A string containing delimited hex values.</param>
        /// <param name="separator">A separator delimiting the hex values. If <see langword="null"/>, then <paramref name="s"/> is parsed as a continuous hex stream.</param>
        /// <returns>A byte array containing the hex values as bytes.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="separator"/> is <see langword="null"/>&#160;or empty, and <paramref name="s"/> does not consist of event number of hex digits,
        /// or parsing failed.</exception>
        public static byte[] ParseHexBytes(this string s, string separator)
        {
            if (s == null)
            {
                Throw.ArgumentNullException(Argument.s);
            }

            if (string.IsNullOrEmpty(separator))
            {
                return(ParseHexBytes(s));
            }

            List <StringSegmentInternal> values = new StringSegmentInternal(s).Split(separator);
            int len = values.Count;

            byte[] result = new byte[len];
            for (int i = 0; i < len; i++)
            {
                StringSegmentInternal segment = values[i];
                segment.Trim();
                if (!Parser.TryParseHexByte(segment, out result[i]))
                {
                    Throw.ArgumentException(Argument.s, Res.StringExtensionsCannotParseAsType(segment.ToString(), Reflector.ByteType));
                }
            }

            return(result);
        }
Пример #4
0
        /// <summary>
        /// Inserts a song from a specified index to a other index in the playlist and moves all songs in between these indexes one index back.
        /// </summary>
        /// <param name="fromIndex">The index of the song to move.</param>
        /// <param name="toIndex">To index to insert the song.</param>
        public void InsertMove(int fromIndex, int toIndex)
        {
            if (fromIndex < 0)
            {
                Throw.ArgumentOutOfRangeException(() => fromIndex, 0);
            }

            if (toIndex < 0)
            {
                Throw.ArgumentOutOfRangeException(() => 0);
            }

            if (toIndex >= fromIndex)
            {
                Throw.ArgumentException(
                    String.Format("{0} has to be small than {1}",
                                  Reflector.GetMemberName(() => toIndex), Reflector.GetMemberName(() => fromIndex)),
                    () => toIndex);
            }

            Song from = this[fromIndex];

            for (int i = fromIndex; i > toIndex; i--)
            {
                this.playlist[i] = this[i - 1];
            }

            this.playlist[toIndex] = from;
        }
        public static object DeserializeValueType(Type type, byte[] data)
        {
            if (type == null)
            {
                Throw.ArgumentNullException(Argument.type);
            }
            if (!type.IsValueType)
            {
                Throw.ArgumentException(Argument.type, Res.BinarySerializationValueTypeExpected);
            }
            if (data == null)
            {
                Throw.ArgumentNullException(Argument.data);
            }
            if (data.Length < Marshal.SizeOf(type))
            {
                Throw.ArgumentException(Argument.data, Res.BinarySerializationDataLengthTooSmall);
            }

            GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);

            try
            {
                return(Marshal.PtrToStructure(handle.AddrOfPinnedObject(), type));
            }
            finally
            {
                handle.Free();
            }
        }
        /// <summary>
        /// Converts the byte array to string of decimal values.
        /// </summary>
        /// <param name="bytes">The byte array to convert.</param>
        /// <param name="separator">The separator to use between the decimal numbers. This parameter is optional.
        /// <br/>Default value: <c>", "</c> (comma and space)</param>
        /// <returns>The string representation, in decimal, of the contents of <paramref name="bytes"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> or <paramref name="separator"/> is <see langword="null"/></exception>
        /// <exception cref="ArgumentException"><paramref name="separator"/> is empty or contains decimal digits</exception>
        public static string ToDecimalValuesString(this byte[] bytes, string separator = ", ")
        {
            if (bytes == null)
            {
                Throw.ArgumentNullException(Argument.bytes);
            }
            if (separator == null)
            {
                Throw.ArgumentNullException(Argument.separator);
            }

            if (separator.Length == 0 || separator.Any(c => c >= '0' && c <= '9'))
            {
                Throw.ArgumentException(Argument.separator, Res.ByteArrayExtensionsSeparatorInvalidDec);
            }

            StringBuilder result = new StringBuilder(bytes.Length * (3 + separator.Length));

            for (int i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString(CultureInfo.InvariantCulture));
                if (i < bytes.Length - 1)
                {
                    result.Append(separator);
                }
            }

            return(result.ToString());
        }
        /// <summary>
        /// Copies the <paramref name="source"/>&#160;<see cref="Stream"/> into the <paramref name="destination"/> one.
        /// Copy begins on the current position of source stream. None of the streams are closed or sought after
        /// the end of the copy progress.
        /// </summary>
        /// <param name="source">Source stream.</param>
        /// <param name="destination">Destination stream.</param>
        /// <param name="bufferSize">Size of the buffer used for copying.</param>
        public static void CopyTo(this Stream source, Stream destination, int bufferSize)
        {
            if (source == null)
            {
                Throw.ArgumentNullException(Argument.source);
            }
            if (destination == null)
            {
                Throw.ArgumentNullException(Argument.destination);
            }
            if (bufferSize <= 0)
            {
                Throw.ArgumentOutOfRangeException(Argument.bufferSize);
            }
            if (!source.CanRead)
            {
                Throw.ArgumentException(Argument.source, Res.StreamExtensionsStreamCannotRead);
            }
            if (!destination.CanWrite)
            {
                Throw.ArgumentException(Argument.destination, Res.StreamExtensionsStreamCannotWrite);
            }

            byte[] buffer = new byte[bufferSize];
            int    read;

            while ((read = source.Read(buffer, 0, buffer.Length)) > 0)
            {
                destination.Write(buffer, 0, read);
            }
        }
Пример #8
0
        /// <summary>
        /// Gets whether <paramref name="item"/> is among the results of <paramref name="set"/>.
        /// </summary>
        /// <param name="item">The item to search for in the results of <paramref name="set"/>.</param>
        /// <param name="set">The set of delegates, whose results are checked whether they are equal to the specified <paramref name="item"/>.</param>
        /// <typeparam name="T">The type of <paramref name="item"/> and the <paramref name="set"/> elements.</typeparam>
        /// <returns><see langword="true"/>&#160;if <paramref name="item"/> is among the results of <paramref name="set"/>; otherwise, <see langword="false"/>.</returns>
        /// <remarks>
        /// <para>This method works similarly to the <c>in</c> operator in SQL and Pascal.</para>
        /// <para>This overload uses generic <see cref="IEqualityComparer{T}"/> implementations to compare the items for the best performance.
        /// The elements of <paramref name="set"/> are evaluated only when they are actually compared so if a result is found the rest of the elements will not be evaluated.
        /// <note>If elements of <paramref name="set"/> are constants or simple expressions consider to use the <see cref="In{T}(T,T[])"/> overload to eliminate the overhead of delegate invokes.</note></para>
        /// </remarks>
        public static bool In <T>(this T item, params Func <T>[] set)
        {
            int length;

            if (set == null || (length = set.Length) == 0)
            {
                return(false);
            }

            var comparer = ComparerHelper <T> .EqualityComparer;

            for (int i = 0; i < length; i++)
            {
                Func <T> func = set[i];
                if (func == null)
                {
                    Throw.ArgumentException(Argument.set, Res.ArgumentContainsNull);
                }
                if (comparer.Equals(item, func.Invoke()))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Converts the byte array to string of hexadecimal values.
        /// </summary>
        /// <param name="bytes">The byte array to convert.</param>
        /// <param name="separator">The separator to use between the hex numbers. If <see langword="null"/>&#160;or empty, the hex stream will be continuous. This parameter is optional.
        /// <br/>Default value: <see langword="null"/>.</param>
        /// <returns>The string representation, in hex, of the contents of <paramref name="bytes"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is <see langword="null"/></exception>
        /// <exception cref="ArgumentException"><paramref name="separator"/> contains hex digits</exception>
        public static string ToHexValuesString(this byte[] bytes, string separator = null)
        {
            if (bytes == null)
            {
                Throw.ArgumentNullException(Argument.bytes);
            }
            bool useSeparator = !String.IsNullOrEmpty(separator);

            if (useSeparator && separator.Any(c => c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'))
            {
                Throw.ArgumentException(Argument.separator, Res.ByteArrayExtensionsSeparatorInvalidHex);
            }

            StringBuilder result = new StringBuilder(bytes.Length * (2 + (separator ?? String.Empty).Length));

            for (int i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString("X2", CultureInfo.InvariantCulture));
                if (useSeparator && i < bytes.Length - 1)
                {
                    result.Append(separator);
                }
            }

            return(result.ToString());
        }
Пример #10
0
        /// <summary>
        /// Copies the elements of the <see cref="T:System.Collections.ICollection" /> to an <see cref="T:System.Array" />, starting at a particular <see cref="T:System.Array" /> index.
        /// </summary>
        /// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param>
        /// <param name="index">The zero-based index in <paramref name="array" /> at which copying begins.</param>
        public void CopyTo(Array array, int index)
        {
            if (array == null)
            {
                Throw.ArgumentNullException(nameof(array));
            }
            if (index < 0)
            {
                Throw.ArgumentOutOfRangeException(nameof(index), index, Message.Common.NonNegativeArrayIndex);
            }
            if (index > array.Length)
            {
                Throw.ArgumentOutOfRangeException(nameof(index), index, Message.Common.ArrayIndexCannotGreaterThanArraySize);
            }
            if (Count > array.Length - index)
            {
                Throw.ArgumentException(Message.Common.ArraySizeLess);
            }
            if (_head < _tail)
            {
                Array.Copy(_array, 0, array, index, Count);
                return;
            }

            Array.Copy(_array, _head, array, 0, _array.Length - _head);
            Array.Copy(_array, 0, array, _array.Length - _head, _tail);
        }
Пример #11
0
        /// <summary>
        /// Gets whether the specified <see cref="string"/>&#160;<paramref name="s"/> contains any of the strings in the specified <paramref name="set"/> set using a specific <paramref name="comparison"/>.
        /// </summary>
        /// <param name="comparison">The <see cref="StringComparison"/> to use.</param>
        /// <param name="s">A <see cref="string"/> instance that is to be compared to each element of the <paramref name="set"/>.</param>
        /// <param name="set">A string array</param>
        /// <returns><see langword="true"/>&#160;if string <paramref name="s"/> contains any of the elements of <paramref name="set"/>; otherwise, <see langword="false"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>
        /// <br/>-or-
        /// <br/><paramref name="set"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="comparison"/> is not a defined <see cref="StringComparison"/> value.</exception>
        /// <exception cref="ArgumentException"><paramref name="set"/>contains a <see langword="null"/>&#160;element.</exception>
        public static bool ContainsAny(this string s, StringComparison comparison, params string[] set)
        {
            if (!Enum <StringComparison> .IsDefined(comparison))
            {
                Throw.EnumArgumentOutOfRange(Argument.comparison, comparison);
            }
            if (s == null)
            {
                Throw.ArgumentNullException(Argument.s);
            }
            if (set == null)
            {
                Throw.ArgumentNullException(Argument.set);
            }

            foreach (var str in set)
            {
                if (str == null)
                {
                    Throw.ArgumentException(Argument.set, Res.ArgumentContainsNull);
                }
                if (s.IndexOf(str, comparison) >= 0)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #12
0
        /// <summary>
        /// Parses a continuous hex stream from a string.
        /// </summary>
        /// <param name="s">A string containing continuous hex values without delimiters.</param>
        /// <returns>A byte array containing the hex values as bytes.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="s"/> does not consist of event amount of hex digits.</exception>
        /// <exception cref="FormatException"><paramref name="s"/> is not of the correct format.</exception>
        /// <exception cref="OverflowException">A value in <paramref name="s"/> does not fit in the range of a <see cref="byte">byte</see> value.</exception>
        public static byte[] ParseHexBytes(this string s)
        {
            if (s == null)
            {
                Throw.ArgumentNullException(Argument.s);
            }

            if (s.Length == 0)
            {
                return(Reflector.EmptyArray <byte>());
            }

            if (s.Length % 2 != 0)
            {
                Throw.ArgumentException(Argument.s, Res.StringExtensionsSourceLengthNotEven);
            }

            byte[] result = new byte[s.Length >> 1];
            for (int i = 0; i < (s.Length >> 1); i++)
            {
                result[i] = Byte.Parse(s.Substring(i << 1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
            }

            return(result);
        }
Пример #13
0
        /// <summary>
        ///     Inserts a song from a specified index to a other index in the playlist and moves all songs in between these indexes
        ///     one index back.
        /// </summary>
        /// <param name="fromIndex">The index of the song to move.</param>
        /// <param name="toIndex">To index to insert the song.</param>
        internal void InsertMove(int fromIndex, int toIndex)
        {
            if (fromIndex < 0)
            {
                Throw.ArgumentOutOfRangeException(() => fromIndex, 0);
            }

            if (toIndex < 0)
            {
                Throw.ArgumentOutOfRangeException(() => toIndex, 0);
            }

            if (toIndex >= fromIndex)
            {
                Throw.ArgumentException(
                    String.Format("{0} has to be smaller than {1}",
                                  Reflector.GetMemberName(() => toIndex), Reflector.GetMemberName(() => fromIndex)),
                    () => toIndex);
            }

            PlaylistEntry from = this[fromIndex];

            for (int i = fromIndex; i > toIndex; i--)
            {
                _playlist[i].Index = i - 1;
                _playlist[i]       = this[i - 1];
            }

            from.Index         = toIndex;
            _playlist[toIndex] = from;
        }
Пример #14
0
        public void CopyTo(T[] array, int arrayIndex)
        {
            if (array == null)
            {
                Throw.ArgumentNullException(nameof(array));
            }
            if (arrayIndex < 0)
            {
                Throw.ArgumentOutOfRangeException(nameof(arrayIndex), Message.Common.NonNegativeArrayIndex);
            }
            if (arrayIndex > array.Length)
            {
                Throw.ArgumentOutOfRangeException(nameof(arrayIndex), Message.Common.ArrayIndexCannotGreaterThanArraySize);
            }
            if (Count > array.Length - arrayIndex)
            {
                Throw.ArgumentException(Message.Common.ArraySizeLess);
            }
            if (IsEmpty)
            {
                return;
            }

            var current = Head;

            while (current != null)
            {
                array[arrayIndex++] = current.Item;
                current             = current.Next;
            }
        }
Пример #15
0
 internal static void CheckDestinationLength(this ISignAlgorithm a, int len)
 {
     if (len < a.SignatureByteLength)
     {
         Throw.ArgumentException($"Signature algorithm '{a.AlgorithmId}' requires {a.SignatureByteLength} destination bytes. Provided buffer has only {len} bytes.", "destination");
     }
 }
        public static byte[] ToArray(this Stream s)
        {
            if (s == null)
            {
                Throw.ArgumentNullException(Argument.s);
            }
            if (!s.CanRead)
            {
                Throw.ArgumentException(Argument.s, Res.StreamExtensionsStreamCannotRead);
            }

            if (s is MemoryStream ms)
            {
                return(ms.ToArray());
            }

            if (!s.CanSeek)
            {
                using (ms = new MemoryStream())
                {
                    CopyTo(s, ms);
                    return(ms.ToArray());
                }
            }

            long pos = s.Position;

            try
            {
                if (pos != 0L)
                {
                    s.Seek(0, SeekOrigin.Begin);
                }

                byte[] result = new byte[s.Length];
                int    len    = s.Read(result, 0, result.Length);

                // we could read the whole stream in one step
                if (len == s.Length)
                {
                    return(result);
                }

                // we use the buffer with the first fragment and continue reading
                using (ms = new MemoryStream(result, 0, len, true, true)
                {
                    Position = len
                })
                {
                    CopyTo(s, ms);

                    // if the stream still reports the same length we return its internal buffer to prevent duplicating the array in memory; otherwise, returning a new array
                    return(ms.Length == s.Length ? ms.GetBuffer() : ms.ToArray());
                }
            }
            finally
            {
                s.Seek(pos, SeekOrigin.Begin);
            }
        }
        private protected static object CreateCollectionByInitializerCollection(ConstructorInfo collectionCtor, IEnumerable initializerCollection, Dictionary <MemberInfo, object> members)
        {
            initializerCollection = initializerCollection.AdjustInitializerCollection(collectionCtor);
            object result = CreateInstanceAccessor.GetAccessor(collectionCtor).CreateInstance(initializerCollection);

            // restoring fields and properties of the final collection
            foreach (KeyValuePair <MemberInfo, object> member in members)
            {
                var property = member.Key as PropertyInfo;
                var field    = property != null ? null : member.Key as FieldInfo;


                // read-only property
                if (property?.CanWrite == false)
                {
                    object existingValue = property.Get(result);
                    if (property.PropertyType.IsValueType)
                    {
                        if (Equals(existingValue, member.Value))
                        {
                            continue;
                        }
                        Throw.SerializationException(Res.XmlSerializationPropertyHasNoSetter(property.Name, collectionCtor.DeclaringType));
                    }

                    if (existingValue == null && member.Value == null)
                    {
                        continue;
                    }
                    if (member.Value == null)
                    {
                        Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterCantSetNull(property.Name, collectionCtor.DeclaringType));
                    }
                    if (existingValue == null)
                    {
                        Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterGetsNull(property.Name, collectionCtor.DeclaringType));
                    }
                    if (existingValue.GetType() != member.Value.GetType())
                    {
                        Throw.ArgumentException(Res.XmlSerializationPropertyTypeMismatch(collectionCtor.DeclaringType, property.Name, member.Value.GetType(), existingValue.GetType()));
                    }

                    CopyContent(member.Value, existingValue);
                    continue;
                }

                // read-write property
                if (property != null)
                {
                    property.Set(result, member.Value);
                    continue;
                }

                // field
                field.Set(result, member.Value);
            }

            return(result);
        }
Пример #18
0
 /// <summary>
 /// Converts the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object.
 /// </summary>
 /// <param name="value">The string representation of the enumerated value or values to parse.</param>
 /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case.</param>
 /// <returns>The parsed <see langword="enum"/>&#160;value.</returns>
 /// <exception cref="ArgumentException"><paramref name="value"/> cannot be parsed as <typeparamref name="TEnum"/>.</exception>
 public static TEnum Parse(ReadOnlySpan <char> value, bool ignoreCase)
 {
     if (!TryParse(value, default, ignoreCase, out TEnum result))
     {
         Throw.ArgumentException(Argument.value, Res.EnumValueCannotBeParsedAsEnum(value.ToString(), typeof(TEnum)));
     }
     return(result);
 }
Пример #19
0
 /// <summary>
 /// Converts the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object.
 /// </summary>
 /// <param name="value">The string representation of the enumerated value or values to parse.</param>
 /// <param name="separator">In case of more values specified the separator among the values. If <see cref="StringSegment.Null"/> or <see cref="StringSegment.Empty"/>, then comma (<c>,</c>) separator is used. This parameter is optional.
 /// <br/>Default value: <see cref="StringSegment.Null"/>.</param>
 /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case. This parameter is optional.
 /// <br/>Default value: <see langword="false"/>.</param>
 /// <returns>The parsed <see langword="enum"/>&#160;value.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see cref="StringSegment.Null"/>.</exception>
 /// <exception cref="ArgumentException"><paramref name="value"/> cannot be parsed as <typeparamref name="TEnum"/>.</exception>
 public static TEnum Parse(StringSegment value, StringSegment separator = default, bool ignoreCase = false)
 {
     if (!TryParse(value, separator, ignoreCase, out TEnum result))
     {
         Throw.ArgumentException(Argument.value, Res.EnumValueCannotBeParsedAsEnum(value.ToString(), typeof(TEnum)));
     }
     return(result);
 }
Пример #20
0
 /// <summary>
 /// Parses an object from a <see cref="string"/> value. Firstly, it tries to parse the type natively.
 /// If <paramref name="type"/> cannot be parsed natively but the type has a <see cref="TypeConverter"/> or a registered conversion that can convert from string,
 /// then the type converter or conversion will be used.
 /// <br/>See the <strong>Remarks</strong> section of the <see cref="Parse{T}"/> overload for details.
 /// </summary>
 /// <returns>An object of <paramref name="type"/>, which is the result of the parsing.</returns>
 /// <param name="s">The string value to parse. If <see langword="null"/>&#160;and <paramref name="type"/> is a reference or nullable type, then returns <see langword="null"/>.</param>
 /// <param name="type">The desired type of the return value.</param>
 /// <param name="culture">The culture to use for the parsing. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional.
 /// <br/>Default value: <see langword="null"/>.</param>
 /// <returns>The parsed value.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="type"/> is <see langword="null"/>, or <paramref name="type"/> is not nullable and <paramref name="s"/> is <see langword="null"/>.</exception>
 /// <exception cref="ArgumentException">Parameter <paramref name="s"/> cannot be parsed as <paramref name="type"/>.</exception>
 public static object Parse(this string s, Type type, CultureInfo culture = null)
 {
     if (!Parser.TryParse(s, type, culture, out object value, out Exception error) || !type.CanAcceptValue(value))
     {
         Throw.ArgumentException(Argument.obj, Res.StringExtensionsCannotParseAsType(s, type), error);
     }
     return(value);
 }
Пример #21
0
 /// <summary>
 /// Parses an object of type <typeparamref name="T"/> from a <see cref="string">string</see> value. Firstly, it tries to parse the type natively.
 /// If <typeparamref name="T"/> cannot be parsed natively but the type has a <see cref="TypeConverter"/> or a registered conversion that can convert from string,
 /// then the type converter or conversion will be used.
 /// <br/>See the <strong>Remarks</strong> section for details.
 /// </summary>
 /// <typeparam name="T">The desired type of the return value.</typeparam>
 /// <param name="s">The string value to parse. If <see langword="null"/>&#160;and <typeparamref name="T"/> is a reference or nullable type, then returns <see langword="null"/>.</param>
 /// <param name="culture">The culture to use for the parsing. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional.
 /// <br/>Default value: <see langword="null"/>.</param>
 /// <returns>An object of <typeparamref name="T"/>, which is the result of the parsing.</returns>
 /// <remarks>
 /// <para>New conversions can be registered by the <see cref="O:KGySoft.CoreLibraries.TypeExtensions.RegisterConversion">RegisterConversion</see>&#160;extension methods.</para>
 /// <para>A <see cref="TypeConverter"/> can be registered by the <see cref="TypeExtensions.RegisterTypeConverter{TConverter}">RegisterTypeConverter</see>&#160;extension method.</para>
 /// <para>Natively parsed types:
 /// <list type="bullet">
 /// <item><description><see cref="System.Enum"/> based types</description></item>
 /// <item><description><see cref="string"/></description></item>
 /// <item><description><see cref="char"/></description></item>
 /// <item><description><see cref="byte"/></description></item>
 /// <item><description><see cref="sbyte"/></description></item>
 /// <item><description><see cref="short"/></description></item>
 /// <item><description><see cref="ushort"/></description></item>
 /// <item><description><see cref="int"/></description></item>
 /// <item><description><see cref="uint"/></description></item>
 /// <item><description><see cref="long"/></description></item>
 /// <item><description><see cref="ulong"/></description></item>
 /// <item><description><see cref="float"/></description></item>
 /// <item><description><see cref="double"/></description></item>
 /// <item><description><see cref="decimal"/></description></item>
 /// <item><description><see cref="bool"/></description></item>
 /// <item><description><see cref="IntPtr"/></description></item>
 /// <item><description><see cref="UIntPtr"/></description></item>
 /// <item><description><see cref="Type"/></description></item>
 /// <item><description><see cref="DateTime"/></description></item>
 /// <item><description><see cref="DateTimeOffset"/></description></item>
 /// <item><description><see cref="TimeSpan"/></description></item>
 /// <item><description><see cref="Nullable{T}"/> of types above: <see langword="null"/>&#160;or empty value returns <see langword="null"/>; otherwise, <paramref name="s"/> is parsed as the underlying type</description></item>
 /// </list>
 /// </para>
 /// </remarks>
 /// <exception cref="ArgumentNullException"><typeparamref name="T"/> is not nullable and <paramref name="s"/> is <see langword="null"/>.</exception>
 /// <exception cref="ArgumentException">Parameter <paramref name="s"/> cannot be parsed as <typeparamref name="T"/>.</exception>
 public static T Parse <T>(this string s, CultureInfo culture = null)
 {
     if (!Parser.TryParse(s, culture, out T value, out Exception error))
     {
         Throw.ArgumentException(Argument.obj, Res.StringExtensionsCannotParseAsType(s, typeof(T)), error);
     }
     return(value);
 }
Пример #22
0
 /// <summary>
 /// Converts the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object.
 /// </summary>
 /// <param name="value">The <see cref="string">string</see> representation of the enumerated value or values to parse.</param>
 /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case.</param>
 /// <returns>The parsed <see langword="enum"/>&#160;value.</returns>
 /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
 /// <exception cref="ArgumentException"><paramref name="value"/> cannot be parsed as <typeparamref name="TEnum"/>.</exception>
 public static TEnum Parse(string value, bool ignoreCase)
 {
     if (!TryParse(value, EnumExtensions.DefaultParseSeparator, ignoreCase, out TEnum result))
     {
         Throw.ArgumentException(Argument.value, Res.EnumValueCannotBeParsedAsEnum(value, typeof(TEnum)));
     }
     return(result);
 }
Пример #23
0
 /// <summary>
 /// Converts an <see cref="object"/> specified in the <paramref name="obj"/> parameter to the desired <paramref name="targetType"/>.
 /// <br/>See the <strong>Examples</strong> section of the generic <see cref="Convert{TTarget}"/> overload for an example.
 /// </summary>
 /// <param name="targetType">The desired type of the return value.</param>
 /// <param name="obj">The object to convert.</param>
 /// <param name="culture">The culture to use for the conversion. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional.
 /// <br/>Default value: <see langword="null"/>.</param>
 /// <returns>An object of <paramref name="targetType"/>, which is the result of the conversion.</returns>
 /// <exception cref="ArgumentException"><paramref name="obj"/> cannot be converted to <paramref name="targetType"/>.</exception>
 /// <remarks>
 /// <para>New conversions can be registered by the <see cref="O:KGySoft.CoreLibraries.TypeExtensions.RegisterConversion">RegisterConversion</see>&#160;<see cref="Type"/> extension methods.</para>
 /// <note type="tip">The registered conversions are tried to be used for intermediate conversion steps if possible. For example, if a conversion is registered from <see cref="long"/> to <see cref="IntPtr"/>,
 /// then conversions from other convertible types become automatically available using the <see cref="long"/> type as an intermediate conversion step.</note>
 /// <para><paramref name="targetType"/> can be even a collection type if <paramref name="obj"/> is also an <see cref="IEnumerable"/> implementation.
 /// The target collection type must have either a default constructor or a constructor that can accept a list, array or dictionary as an initializer collection.</para>
 /// </remarks>
 public static object Convert(this object obj, Type targetType, CultureInfo culture = null)
 {
     if (!ObjectConverter.TryConvert(obj, targetType, culture, out object result, out Exception error) || !targetType.CanAcceptValue(result))
     {
         Throw.ArgumentException(Argument.obj, Res.ObjectExtensionsCannotConvertToType(targetType), error);
     }
     return(result);
 }
Пример #24
0
 /// <summary>
 /// Converts an <see cref="object"/> specified in the <paramref name="obj"/> parameter to the desired <typeparamref name="TTarget"/>.
 /// </summary>
 /// <typeparam name="TTarget">The desired type of the return value.</typeparam>
 /// <param name="obj">The object to convert.</param>
 /// <param name="culture">The culture to use for the conversion. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional.
 /// <br/>Default value: <see langword="null"/>.</param>
 /// <returns>An object of <typeparamref name="TTarget"/>, which is the result of the conversion.</returns>
 /// <exception cref="ArgumentException"><paramref name="obj"/> cannot be converted to <typeparamref name="TTarget"/>.</exception>
 /// <remarks>
 /// <para>The method firstly tries to use registered direct conversions between source and target types, then attempts to perform the conversion via <see cref="IConvertible"/> types and registered <see cref="TypeConverter"/>s.
 /// If these attempts fail, then the registered conversions tried to be used for intermediate steps, if possible.</para>
 /// <para>New conversions can be registered by the <see cref="O:KGySoft.CoreLibraries.TypeExtensions.RegisterConversion">RegisterConversion</see>&#160;<see cref="Type"/> extension methods.</para>
 /// <para>A <see cref="TypeConverter"/> can be registered by the <see cref="TypeExtensions.RegisterTypeConverter{TConverter}">RegisterTypeConverter</see>&#160;<see cref="Type"/> extension method.</para>
 /// <note type="tip">The registered conversions are tried to be used for intermediate conversion steps if possible. For example, if a conversion is registered from <see cref="long"/> to <see cref="IntPtr"/>,
 /// then conversions from other convertible types become automatically available using the <see cref="long"/> type as an intermediate conversion step.</note>
 /// <para><typeparamref name="TTarget"/> can be even a collection type if <paramref name="obj"/> is also an <see cref="IEnumerable"/> implementation.
 /// The target collection type must have either a default constructor or a constructor that can accept a list, array or dictionary as an initializer collection.</para>
 /// </remarks>
 /// <example>
 /// <note type="tip">Try also <a href="https://dotnetfiddle.net/rzg8If" target="_blank">online</a>.</note>
 /// <code lang="C#"><![CDATA[
 /// using System;
 /// using System.Collections;
 /// using System.Collections.Generic;
 /// using System.Collections.ObjectModel;
 /// using System.Linq;
 /// using KGySoft.CoreLibraries;
 ///
 /// public class Example
 /// {
 ///     public static void Main()
 ///     {
 ///         // between convertible types: like the Convert class but supports also enums in both ways
 ///         ConvertTo<int>("123"); // culture can be specified, default is InvariantCulture
 ///         ConvertTo<float>(ConsoleColor.Blue);
 ///         ConvertTo<ConsoleColor>(13); // this would fail by Convert.ChangeType
 ///
 ///         // TypeConverters are used if possible:
 ///         ConvertTo<Guid>("AADC78003DAB4906826EFD8B2D5CF33D");
 ///
 ///         // New conversions can be registered:
 ///         ConvertTo<IntPtr>(42L); // fail
 ///         typeof(long).RegisterConversion(typeof(IntPtr), (obj, type, culture) => new IntPtr((long)obj));
 ///         ConvertTo<IntPtr>(42L); // success
 ///
 ///         // Registered conversions can be used as intermediate steps:
 ///         ConvertTo<IntPtr>('x'); // char => long => IntPtr
 ///
 ///         // Collection conversion is also supported:
 ///         ConvertTo<bool[]>(new List<int> { 1, 0, 0, 1 });
 ///         ConvertTo<List<int>>("Blah"); // works because string is an IEnumerable<char>
 ///         ConvertTo<string>(new[] { 'h', 'e', 'l', 'l', 'o' }); // because string has a char[] constructor
 ///         ConvertTo<ReadOnlyCollection<string>>(new[] { 1.0m, 2, -1 }); // via the IList<T> constructor
 ///
 ///         // even between non-generic collections:
 ///         ConvertTo<ArrayList>(new HashSet<int> { 1, 2, 3 });
 ///         ConvertTo<Dictionary<ConsoleColor, string>>(new Hashtable { { 1, "One" }, { "Black", 'x' } });
 ///     }
 ///
 ///     private static void ConvertTo<T>(object source)
 ///     {
 ///         Console.Write($"{source.GetType().GetName(TypeNameKind.ShortName)} => {typeof(T).GetName(TypeNameKind.ShortName)}: {AsString(source)} => ");
 ///         try
 ///         {
 ///             T result = source.Convert<T>(); // a culture can be specified here for string conversions
 ///             Console.WriteLine(AsString(result));
 ///         }
 ///         catch (Exception e)
 ///         {
 ///             Console.WriteLine(e.Message.Replace(Environment.NewLine, " "));
 ///         }
 ///     }
 ///
 ///     private static string AsString(object obj)
 ///     {
 ///         if (obj == null)
 ///             return "<null>";
 ///
 ///         // KeyValuePair has a similar ToString to this one
 ///         if (obj is DictionaryEntry de)
 ///             return $"[{de.Key}, {de.Value}]";
 ///
 ///         if (!(obj is IEnumerable) || obj is string)
 ///             return obj.ToString();
 ///
 ///         return String.Join(", ", ((IEnumerable)obj).Cast<object>().Select(AsString));
 ///     }
 /// }
 ///
 /// // This example produces the following output:
 /// // String => Int32: 123 => 123
 /// // ConsoleColor => Single: Blue => 9
 /// // Int32 => ConsoleColor: 13 => Magenta
 /// // String => Guid: AADC78003DAB4906826EFD8B2D5CF33D => aadc7800-3dab-4906-826e-fd8b2d5cf33d
 /// // Int64 => IntPtr: 42 => The specified argument cannot be converted to type System.IntPtr. Parameter name: obj
 /// // Int64 => IntPtr: 42 => 42
 /// // Char => IntPtr: x => 120
 /// // List`1 => Boolean[]: 1, 0, 0, 1 => True, False, False, True
 /// // String => List`1: Blah => 66, 108, 97, 104
 /// // Char[] => String: h, e, l, l, o => hello
 /// // Decimal[] => ReadOnlyCollection`1: 1.0, 2, -1 => 1.0, 2, -1
 /// // HashSet`1 => ArrayList: 1, 2, 3 => 1, 2, 3
 /// // Hashtable => Dictionary`2: [1, One], [Black, x] => [DarkBlue, One], [Black, x]]]></code>
 /// </example>
 public static TTarget Convert <TTarget>(this object obj, CultureInfo culture = null)
 {
     if (!ObjectConverter.TryConvert(obj, typeof(TTarget), culture, out object result, out Exception error) || (!(result is TTarget) && !typeof(TTarget).CanAcceptValue(result)))
     {
         Throw.ArgumentException(Argument.obj, Res.ObjectExtensionsCannotConvertToType(typeof(TTarget)), error);
     }
     return((TTarget)result);
 }
Пример #25
0
        public T From <T>(byte[] data, Type messageType)
        {
            if (data is null || data.Length == 0)
            {
                Throw.ArgumentException(nameof(data), "Cannot be null or empty");
            }

            return((T)serializer.Deserialize(messageType, data));
        }
Пример #26
0
        public T From <T>(string data, Type messageType)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                Throw.ArgumentException(nameof(data), "Cannot be null, empty or whitespace");
            }

            return(From <T>(Convert.FromBase64String(data), messageType));
        }
Пример #27
0
        public T From <T>(string data, Type messageType)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                Throw.ArgumentException(nameof(data), "Cannot be null, empty or whitespace");
            }

            return((T)JsonSerializer.Deserialize(data, messageType, _settings));
        }
Пример #28
0
        public T From <T>(byte[] data, Type messageType)
        {
            if (data is null || data.Length == 0)
            {
                Throw.ArgumentException(nameof(data), "Cannot be null or empty");
            }

            return((T)JSON.Deserialize(Encoding.UTF8.GetString(data), messageType));
        }
Пример #29
0
        public T?From <T>(byte[] data, Type messageType) where T : class
        {
            if (data is null || data.Length == 0)
            {
                Throw.ArgumentException(nameof(data), "Cannot be null or empty");
            }

            return((T?)JsonSerializer.Deserialize(data, messageType, _settings));
        }
        private protected static void HandleDeserializedMember(object obj, MemberInfo member, object deserializedValue, object existingValue, Dictionary <MemberInfo, object> members)
        {
            // 1/a.) Cache for later (obj is an initializer collection)
            if (members != null)
            {
                members[member] = deserializedValue;
                return;
            }

            // 1/b.) Successfully deserialized into the existing instance (or both are null)
            if (!(deserializedValue is ValueType) && ReferenceEquals(existingValue, deserializedValue))
            {
                return;
            }

            // 1.c.) Processing result
            // Field
            if (member is FieldInfo field)
            {
                field.Set(obj, deserializedValue);
                return;
            }

            var property = (PropertyInfo)member;

            // Read-only property
            if (!property.CanWrite)
            {
                if (property.PropertyType.IsValueType)
                {
                    if (Equals(existingValue, deserializedValue))
                    {
                        return;
                    }
                    Throw.SerializationException(Res.XmlSerializationPropertyHasNoSetter(property.Name, obj.GetType()));
                }

                if (existingValue == null)
                {
                    Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterGetsNull(property.Name, obj.GetType()));
                }
                if (deserializedValue == null)
                {
                    Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterCantSetNull(property.Name, obj.GetType()));
                }
                if (existingValue.GetType() != deserializedValue.GetType())
                {
                    Throw.ArgumentException(Res.XmlSerializationPropertyTypeMismatch(obj.GetType(), property.Name, deserializedValue.GetType(), existingValue.GetType()));
                }

                CopyContent(deserializedValue, existingValue);
                return;
            }

            // Read-write property
            property.Set(obj, deserializedValue);
        }