diff --git a/DisCatSharp.Common/Attributes/DateTimeFormatAttribute.cs b/DisCatSharp.Common/Attributes/DateTimeFormatAttribute.cs
deleted file mode 100644
index e1a645f57..000000000
--- a/DisCatSharp.Common/Attributes/DateTimeFormatAttribute.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-// ReSharper disable InconsistentNaming
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Defines the format for string-serialized and objects.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class DateTimeFormatAttribute : SerializationAttribute
- {
- ///
- /// Gets the ISO 8601 format string of "yyyy-MM-ddTHH:mm:ss.fffzzz".
- ///
- public const string FORMAT_ISO_8601 = "yyyy-MM-ddTHH:mm:ss.fffzzz";
-
- ///
- /// Gets the RFC 1123 format string of "R".
- ///
- public const string FORMAT_RFC_1123 = "R";
-
- ///
- /// Gets the general long format.
- ///
- public const string FORMAT_LONG = "G";
-
- ///
- /// Gets the general short format.
- ///
- public const string FORMAT_SHORT = "g";
-
- ///
- /// Gets the custom datetime format string to use.
- ///
- public string Format { get; }
-
- ///
- /// Gets the predefined datetime format kind.
- ///
- public DateTimeFormatKind Kind { get; }
-
- ///
- /// Specifies a predefined format to use.
- ///
- /// Predefined format kind to use.
- public DateTimeFormatAttribute(DateTimeFormatKind kind)
- {
- if (kind < 0 || kind > DateTimeFormatKind.InvariantLocaleShort)
- throw new ArgumentOutOfRangeException(nameof(kind), "Specified format kind is not legal or supported.");
-
- this.Kind = kind;
- this.Format = null;
- }
-
- ///
- /// Specifies a custom format to use.
- /// See https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings for more details.
- ///
- /// Custom format string to use.
- public DateTimeFormatAttribute(string format)
- {
- if (string.IsNullOrWhiteSpace(format))
- throw new ArgumentNullException(nameof(format), "Specified format cannot be null or empty.");
-
- this.Kind = DateTimeFormatKind.Custom;
- this.Format = format;
- }
- }
-
- ///
- /// Defines which built-in format to use for for and serialization.
- /// See https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings and https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings for more details.
- ///
- public enum DateTimeFormatKind : int
- {
- ///
- /// Specifies ISO 8601 format, which is equivalent to .NET format string of "yyyy-MM-ddTHH:mm:ss.fffzzz".
- ///
- ISO8601 = 0,
-
- ///
- /// Specifies RFC 1123 format, which is equivalent to .NET format string of "R".
- ///
- RFC1123 = 1,
-
- ///
- /// Specifies a format defined by , with a format string of "G". This format is not recommended for portability reasons.
- ///
- CurrentLocaleLong = 2,
-
- ///
- /// Specifies a format defined by , with a format string of "g". This format is not recommended for portability reasons.
- ///
- CurrentLocaleShort = 3,
-
- ///
- /// Specifies a format defined by , with a format string of "G".
- ///
- InvariantLocaleLong = 4,
-
- ///
- /// Specifies a format defined by , with a format string of "g".
- ///
- InvariantLocaleShort = 5,
-
- ///
- /// Specifies a custom format. This value is not usable directly.
- ///
- Custom = int.MaxValue
- }
-}
diff --git a/DisCatSharp.Common/Attributes/DecomposerAttribute.cs b/DisCatSharp.Common/Attributes/DecomposerAttribute.cs
deleted file mode 100644
index b6ba47f89..000000000
--- a/DisCatSharp.Common/Attributes/DecomposerAttribute.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Specifies a decomposer for a given type or property.
- ///
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class DecomposerAttribute : SerializationAttribute
- {
- ///
- /// Gets the type of the decomposer.
- ///
- public Type DecomposerType { get; }
-
- ///
- /// Specifies a decomposer for given type or property.
- ///
- /// Type of decomposer to use.
- public DecomposerAttribute(Type type)
- {
- if (!typeof(IDecomposer).IsAssignableFrom(type) || !type.IsClass || type.IsAbstract) // abstract covers static - static = abstract + sealed
- throw new ArgumentException("Invalid type specified. Must be a non-abstract class which implements DisCatSharp.Common.Serialization.IDecomposer interface.", nameof(type));
-
- this.DecomposerType = type;
- }
- }
-}
diff --git a/DisCatSharp.Common/Attributes/EnumAttributes.cs b/DisCatSharp.Common/Attributes/EnumAttributes.cs
deleted file mode 100644
index 7c2485cc2..000000000
--- a/DisCatSharp.Common/Attributes/EnumAttributes.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Specifies that this enum should be serialized and deserialized as its underlying numeric type.
- /// This is used to change the behaviour of enum serialization.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class NumericEnumAttribute : SerializationAttribute
- { }
-
- ///
- /// Specifies that this enum should be serialized and deserialized as its string representation.
- /// This is used to change the behaviour of enum serialization.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class StringEnumAttribute : SerializationAttribute
- { }
-}
diff --git a/DisCatSharp.Common/Attributes/IncludeNullAttribute.cs b/DisCatSharp.Common/Attributes/IncludeNullAttribute.cs
deleted file mode 100644
index afb4cc8ac..000000000
--- a/DisCatSharp.Common/Attributes/IncludeNullAttribute.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Specifies that if the value of the field or property is null, it should be included in the serialized data.
- /// This alters the default behaviour of ignoring nulls.
- ///
- [Obsolete("Use [DataMember] with EmitDefaultValue = true.")]
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class IncludeNullAttribute : SerializationAttribute
- { }
-}
diff --git a/DisCatSharp.Common/Attributes/Int53Attribute.cs b/DisCatSharp.Common/Attributes/Int53Attribute.cs
deleted file mode 100644
index b8bad4b91..000000000
--- a/DisCatSharp.Common/Attributes/Int53Attribute.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Specifies that this 64-bit integer uses no more than 53 bits to represent its value.
- /// This is used to indicate that large numbers are safe for direct serialization into formats which do support 64-bit integers natively (such as JSON).
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class Int53Attribute : SerializationAttribute
- {
- ///
- /// Gets the maximum safe value representable as an integer by a IEEE754 64-bit binary floating point value.
- /// This value equals to 9007199254740991.
- ///
- public const long MAX_VALUE = (1L << 53) - 1;
-
- ///
- /// Gets the minimum safe value representable as an integer by a IEEE754 64-bit binary floating point value.
- /// This value equals to -9007199254740991.
- ///
- public const long MIN_VALUE = -MAX_VALUE;
- }
-}
diff --git a/DisCatSharp.Common/Attributes/SerializationAttribute.cs b/DisCatSharp.Common/Attributes/SerializationAttribute.cs
deleted file mode 100644
index 950605130..000000000
--- a/DisCatSharp.Common/Attributes/SerializationAttribute.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// ABC for serialization attributes.
- ///
- public abstract class SerializationAttribute : Attribute
- { }
-}
diff --git a/DisCatSharp.Common/Attributes/SerializedNameAttribute.cs b/DisCatSharp.Common/Attributes/SerializedNameAttribute.cs
deleted file mode 100644
index 914d706c3..000000000
--- a/DisCatSharp.Common/Attributes/SerializedNameAttribute.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Declares name of a property in serialized data. This is used for mapping serialized data to object properties and fields.
- ///
- [Obsolete("Use [DataMember] with set Name instead.")]
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class SerializedNameAttribute : SerializationAttribute
- {
- ///
- /// Gets the serialized name of the field or property.
- ///
- public string Name { get; }
-
- ///
- /// Declares name of a property in serialized data. This is used for mapping serialized data to object properties and fields.
- ///
- /// Name of the field or property in serialized data.
- public SerializedNameAttribute(string name)
- {
- this.Name = name;
- }
- }
-}
diff --git a/DisCatSharp.Common/Attributes/TimeSpanAttributes.cs b/DisCatSharp.Common/Attributes/TimeSpanAttributes.cs
deleted file mode 100644
index b88643fb5..000000000
--- a/DisCatSharp.Common/Attributes/TimeSpanAttributes.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Specifies that this will be serialized as a number of whole seconds.
- /// This value will always be serialized as a number.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class TimeSpanSecondsAttribute : SerializationAttribute
- { }
-
- ///
- /// Specifies that this will be serialized as a number of whole milliseconds.
- /// This value will always be serialized as a number.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class TimeSpanMillisecondsAttribute : SerializationAttribute
- { }
-}
diff --git a/DisCatSharp.Common/Attributes/TimeSpanFormatAttribute.cs b/DisCatSharp.Common/Attributes/TimeSpanFormatAttribute.cs
deleted file mode 100644
index 8cfd15cf4..000000000
--- a/DisCatSharp.Common/Attributes/TimeSpanFormatAttribute.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-// ReSharper disable InconsistentNaming
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Defines the format for string-serialized objects.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class TimeSpanFormatAttribute : SerializationAttribute
- {
- ///
- /// Gets the ISO 8601 format string of @"ddThh\:mm\:ss\.fff".
- ///
- public const string FORMAT_ISO_8601 = @"ddThh\:mm\:ss\.fff";
-
- ///
- /// Gets the constant format.
- ///
- public const string FORMAT_CONSTANT = "c";
-
- ///
- /// Gets the general long format.
- ///
- public const string FORMAT_LONG = "G";
-
- ///
- /// Gets the general short format.
- ///
- public const string FORMAT_SHORT = "g";
-
- ///
- /// Gets the custom datetime format string to use.
- ///
- public string Format { get; }
-
- ///
- /// Gets the predefined datetime format kind.
- ///
- public TimeSpanFormatKind Kind { get; }
-
- ///
- /// Specifies a predefined format to use.
- ///
- /// Predefined format kind to use.
- public TimeSpanFormatAttribute(TimeSpanFormatKind kind)
- {
- if (kind < 0 || kind > TimeSpanFormatKind.InvariantLocaleShort)
- throw new ArgumentOutOfRangeException(nameof(kind), "Specified format kind is not legal or supported.");
-
- this.Kind = kind;
- this.Format = null;
- }
-
- ///
- /// Specifies a custom format to use.
- /// See https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings for more details.
- ///
- /// Custom format string to use.
- public TimeSpanFormatAttribute(string format)
- {
- if (string.IsNullOrWhiteSpace(format))
- throw new ArgumentNullException(nameof(format), "Specified format cannot be null or empty.");
-
- this.Kind = TimeSpanFormatKind.Custom;
- this.Format = format;
- }
- }
-
- ///
- /// Defines which built-in format to use for serialization.
- /// See https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-timespan-format-strings and https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings for more details.
- ///
- public enum TimeSpanFormatKind : int
- {
- ///
- /// Specifies ISO 8601-like time format, which is equivalent to .NET format string of @"ddThh\:mm\:ss\.fff".
- ///
- ISO8601 = 0,
-
- ///
- /// Specifies a format defined by , with a format string of "c".
- ///
- InvariantConstant = 1,
-
- ///
- /// Specifies a format defined by , with a format string of "G". This format is not recommended for portability reasons.
- ///
- CurrentLocaleLong = 2,
-
- ///
- /// Specifies a format defined by , with a format string of "g". This format is not recommended for portability reasons.
- ///
- CurrentLocaleShort = 3,
-
- ///
- /// Specifies a format defined by , with a format string of "G". This format is not recommended for portability reasons.
- ///
- InvariantLocaleLong = 4,
-
- ///
- /// Specifies a format defined by , with a format string of "g". This format is not recommended for portability reasons.
- ///
- InvariantLocaleShort = 5,
-
- ///
- /// Specifies a custom format. This value is not usable directly.
- ///
- Custom = int.MaxValue
- }
-}
diff --git a/DisCatSharp.Common/Attributes/UnixTimestampAttributes.cs b/DisCatSharp.Common/Attributes/UnixTimestampAttributes.cs
deleted file mode 100644
index 2bf2ba457..000000000
--- a/DisCatSharp.Common/Attributes/UnixTimestampAttributes.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Specifies that this or will be serialized as Unix timestamp seconds.
- /// This value will always be serialized as a number.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class UnixSecondsAttribute : SerializationAttribute
- { }
-
- ///
- /// Specifies that this or will be serialized as Unix timestamp milliseconds.
- /// This value will always be serialized as a number.
- ///
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
- public sealed class UnixMillisecondsAttribute : SerializationAttribute
- { }
-}
diff --git a/DisCatSharp.Common/GlobalSuppressions.cs b/DisCatSharp.Common/GlobalSuppressions.cs
deleted file mode 100644
index cb38bcb49..000000000
--- a/DisCatSharp.Common/GlobalSuppressions.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System.Diagnostics.CodeAnalysis;
-
-[assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "", Scope = "member", Target = "~F:DisCatSharp.Common.Utilities.AsyncEvent`2._lock")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.Enumerator.Dispose")]
-[assembly: SuppressMessage("Style", "IDE0083:Use pattern matching", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.System#Collections#IDictionary#Add(System.Object,System.Object)")]
-[assembly: SuppressMessage("Style", "IDE0083:Use pattern matching", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.System#Collections#IDictionary#Contains(System.Object)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.System#Collections#IDictionary#Contains(System.Object)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0083:Use pattern matching", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.System#Collections#IDictionary#Remove(System.Object)")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.TryGetValue(System.String,`0@)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupDictionary`1.TryRemove(System.String,`0@)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Extensions.FirstTwoOrDefault``1(System.Collections.Generic.IEnumerable{``0})~System.ValueTuple{``0,``0}")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Extensions.IsInRange(System.Double,System.Double,System.Double,System.Boolean)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Extensions.IsInRange(System.Single,System.Single,System.Single,System.Boolean)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0047:Remove unnecessary parentheses", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Types.ContinuousMemoryBuffer`1.Read(System.Span{`0},System.UInt64,System.Int32@)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Types.ContinuousMemoryBuffer`1.ToArray~`0[]")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Utilities.AsyncEvent`2.UnregisterAll")]
-[assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupDictionary`1.Enumerator.System#Collections#IDictionaryEnumerator#Entry")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupDictionary`1.Item(System.ReadOnlySpan{System.Char})")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupDictionary`1.Item(System.String)")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupDictionary`1.System#Collections#IDictionary#Item(System.Object)")]
-[assembly: SuppressMessage("Style", "IDE0083:Use pattern matching", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupDictionary`1.System#Collections#IDictionary#Item(System.Object)")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupReadOnlyDictionary`1.Enumerator.Dispose")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.CharSpanLookupReadOnlyDictionary`1.TryGetValue(System.String,`0@)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetBytes(System.Span{System.Byte})")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetNonZeroBytes(System.Span{System.Byte})")]
-[assembly: SuppressMessage("Style", "IDE0047:Remove unnecessary parentheses", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Types.MemoryBuffer`1.Grow(System.Int32)")]
-[assembly: SuppressMessage("Style", "IDE0047:Remove unnecessary parentheses", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Types.MemoryBuffer`1.Read(System.Span{`0},System.UInt64,System.Int32@)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupReadOnlyDictionary`1.Item(System.ReadOnlySpan{System.Char})")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~P:DisCatSharp.Common.CharSpanLookupReadOnlyDictionary`1.Item(System.String)")]
-[assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Optional.FromDefaultValue``1~DisCatSharp.Common.Optional{``0}")]
-[assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Optional.FromValue``1(``0)~DisCatSharp.Common.Optional{``0}")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Optional`1.Equals(`0)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Optional`1.Equals(DisCatSharp.Common.Optional`1)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Optional`1.Equals(System.Object)~System.Boolean")]
-[assembly: SuppressMessage("Style", "IDE0090:Use 'new(...)'", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Optional`1.op_Implicit(`0)~DisCatSharp.Common.Optional`1")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetBytes(System.Byte[])")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetInt16(System.Int16,System.Int16)~System.Int16")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetInt32(System.Int32,System.Int32)~System.Int32")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetInt64(System.Int64,System.Int64)~System.Int64")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetInt8(System.SByte,System.SByte)~System.SByte")]
-[assembly: SuppressMessage("Style", "IDE0022:Use expression body for methods", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetNonZeroBytes(System.Byte[])")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt16(System.UInt16,System.UInt16)~System.UInt16")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt16(System.UInt16,System.UInt16)~System.UInt16")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt32(System.UInt32,System.UInt32)~System.UInt32")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt32(System.UInt32,System.UInt32)~System.UInt32")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt64(System.UInt64,System.UInt64)~System.UInt64")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt64(System.UInt64,System.UInt64)~System.UInt64")]
-[assembly: SuppressMessage("Style", "IDE0048:Add parentheses for clarity", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt8(System.Byte,System.Byte)~System.Byte")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.SecureRandom.GetUInt8(System.Byte,System.Byte)~System.Byte")]
-[assembly: SuppressMessage("Style", "IDE0045:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Utilities.AsyncExecutor.Execute(System.Threading.Tasks.Task)")]
-[assembly: SuppressMessage("Style", "IDE0062:Make local function 'static'", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Utilities.AsyncExecutor.Execute(System.Threading.Tasks.Task)")]
-[assembly: SuppressMessage("Style", "IDE0045:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Utilities.AsyncExecutor.Execute``1(System.Threading.Tasks.Task{``0})~``0")]
-[assembly: SuppressMessage("Style", "IDE0062:Make local function 'static'", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Utilities.AsyncExecutor.Execute``1(System.Threading.Tasks.Task{``0})~``0")]
-[assembly: SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "", Scope = "member", Target = "~M:DisCatSharp.Common.Utilities.ReflectionUtilities.ToDictionary``1(``0)~System.Collections.Generic.IReadOnlyDictionary{System.String,System.Object}")]
diff --git a/DisCatSharp.Common/RegularExpressions/CommonRegEx.cs b/DisCatSharp.Common/RegularExpressions/CommonRegEx.cs
index d436083d6..34f33a757 100644
--- a/DisCatSharp.Common/RegularExpressions/CommonRegEx.cs
+++ b/DisCatSharp.Common/RegularExpressions/CommonRegEx.cs
@@ -1,75 +1,50 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Text.RegularExpressions;
namespace DisCatSharp.Common.RegularExpressions
{
///
/// Provides common regex.
///
public static class CommonRegEx
{
///
/// Represents a hex color string.
///
public static Regex HexColorString
=> new(@"^#?([a-fA-F0-9]{6})$", RegexOptions.ECMAScript | RegexOptions.Compiled);
///
/// Represents a rgb color string.
///
public static Regex RgbColorString
=> new(@"^(\d{1,3})\s*?,\s*?(\d{1,3}),\s*?(\d{1,3})$", RegexOptions.ECMAScript | RegexOptions.Compiled);
///
/// Represents a timespan.
///
public static Regex TimeSpan
=> new(@"^(?\d+d\s*)?(?\d{1,2}h\s*)?(?\d{1,2}m\s*)?(?\d{1,2}s\s*)?$", RegexOptions.ECMAScript | RegexOptions.Compiled);
-
- ///
- /// Represents a advanced youtube regex.
- /// Named groups:
- ///
- ///
- /// group
- /// description
- ///
- ///
- /// id
- /// Video ID
- ///
- ///
- /// list
- /// List ID
- ///
- ///
- /// index
- /// List index
- ///
- ///
- ///
- public static Regex AdvancedYoutubeRegex
- => new(@"http(s)?:\/\/(www\.)?youtu(\.be|be\.com)\/(watch\?v=|playlist)?(?\w{1,})?((\?|\&)list=(?\w{1,}))(&index=(?\d{1,}))?", RegexOptions.ECMAScript | RegexOptions.Compiled);
}
}
diff --git a/DisCatSharp.Common/Types/CharSpanLookupDictionary.cs b/DisCatSharp.Common/Types/CharSpanLookupDictionary.cs
deleted file mode 100644
index 11806b9d0..000000000
--- a/DisCatSharp.Common/Types/CharSpanLookupDictionary.cs
+++ /dev/null
@@ -1,814 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-
-namespace DisCatSharp.Common
-{
- ///
- /// Represents collection of string keys and values, allowing the use of for dictionary operations.
- ///
- /// Type of items in this dictionary.
- public sealed class CharSpanLookupDictionary :
- IDictionary,
- IReadOnlyDictionary,
- IDictionary
- {
- ///
- /// Gets the collection of all keys present in this dictionary.
- ///
- public IEnumerable Keys => this.GetKeysInternal();
- ///
- /// Gets the keys.
- ///
- ICollection IDictionary.Keys => this.GetKeysInternal();
- ///
- /// Gets the keys.
- ///
- ICollection IDictionary.Keys => this.GetKeysInternal();
-
- ///
- /// Gets the collection of all values present in this dictionary.
- ///
- public IEnumerable Values => this.GetValuesInternal();
- ///
- /// Gets the values.
- ///
- ICollection IDictionary.Values => this.GetValuesInternal();
- ///
- /// Gets the values.
- ///
- ICollection IDictionary.Values => this.GetValuesInternal();
-
- ///
- /// Gets the total number of items in this dictionary.
- ///
- public int Count { get; private set; }
-
- ///
- /// Gets whether this dictionary is read-only.
- ///
- public bool IsReadOnly => false;
-
- ///
- /// Gets whether this dictionary has a fixed size.
- ///
- public bool IsFixedSize => false;
-
- ///
- /// Gets whether this dictionary is considered thread-safe.
- ///
- public bool IsSynchronized => false;
-
- ///
- /// Gets the object which allows synchronizing access to this dictionary.
- ///
- public object SyncRoot { get; } = new();
-
- ///
- /// Gets or sets a value corresponding to given key in this dictionary.
- ///
- /// Key to get or set the value for.
- /// Value matching the supplied key, if applicable.
- public TValue this[string key]
- {
- get
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key));
-
- if (!this.TryRetrieveInternal(key.AsSpan(), out var value))
- throw new KeyNotFoundException($"The given key '{key}' was not present in the dictionary.");
-
- return value;
- }
-
- set
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key));
-
- this.TryInsertInternal(key, value, true);
- }
- }
-
- ///
- /// Gets or sets a value corresponding to given key in this dictionary.
- ///
- /// Key to get or set the value for.
- /// Value matching the supplied key, if applicable.
- public TValue this[ReadOnlySpan key]
- {
- get
- {
- if (!this.TryRetrieveInternal(key, out var value))
- throw new KeyNotFoundException($"The given key was not present in the dictionary.");
-
- return value;
- }
-
- set
- {
- unsafe
- {
- fixed (char* chars = &key.GetPinnableReference())
- this.TryInsertInternal(new string(chars, 0, key.Length), value, true);
- }
- }
- }
-
- object IDictionary.this[object key]
- {
- get
- {
- if (!(key is string tkey))
- throw new ArgumentException("Key needs to be an instance of a string.");
-
- if (!this.TryRetrieveInternal(tkey.AsSpan(), out var value))
- throw new KeyNotFoundException($"The given key '{tkey}' was not present in the dictionary.");
-
- return value;
- }
-
- set
- {
- if (!(key is string tkey))
- throw new ArgumentException("Key needs to be an instance of a string.");
-
- if (!(value is TValue tvalue))
- {
- tvalue = default;
- if (tvalue != null)
- throw new ArgumentException($"Value needs to be an instance of {typeof(TValue)}.");
- }
-
- this.TryInsertInternal(tkey, tvalue, true);
- }
- }
-
- ///
- /// Gets the internal buckets.
- ///
- private readonly Dictionary _internalBuckets;
-
- ///
- /// Creates a new, empty with string keys and items of type .
- ///
- public CharSpanLookupDictionary()
- {
- this._internalBuckets = new Dictionary();
- }
-
- ///
- /// Creates a new, empty with string keys and items of type and sets its initial capacity to specified value.
- ///
- /// Initial capacity of the dictionary.
- public CharSpanLookupDictionary(int initialCapacity)
- {
- this._internalBuckets = new Dictionary(initialCapacity);
- }
-
- ///
- /// Creates a new with string keys and items of type and populates it with key-value pairs from supplied dictionary.
- ///
- /// Dictionary containing items to populate this dictionary with.
- public CharSpanLookupDictionary(IDictionary values)
- : this(values.Count)
- {
- foreach (var (k, v) in values)
- this.Add(k, v);
- }
-
- ///
- /// Creates a new with string keys and items of type and populates it with key-value pairs from supplied dictionary.
- ///
- /// Dictionary containing items to populate this dictionary with.
- public CharSpanLookupDictionary(IReadOnlyDictionary values)
- : this(values.Count)
- {
- foreach (var (k, v) in values)
- this.Add(k, v);
- }
-
- ///
- /// Creates a new with string keys and items of type and populates it with key-value pairs from supplied key-value collection.
- ///
- /// Dictionary containing items to populate this dictionary with.
- public CharSpanLookupDictionary(IEnumerable> values)
- : this()
- {
- foreach (var (k, v) in values)
- this.Add(k, v);
- }
-
- ///
- /// Inserts a specific key and corresponding value into this dictionary.
- ///
- /// Key to insert.
- /// Value corresponding to this key.
- public void Add(string key, TValue value)
- {
- if (!this.TryInsertInternal(key, value, false))
- throw new ArgumentException("Given key is already present in the dictionary.", nameof(key));
- }
-
- ///
- /// Inserts a specific key and corresponding value into this dictionary.
- ///
- /// Key to insert.
- /// Value corresponding to this key.
- public void Add(ReadOnlySpan key, TValue value)
- {
- unsafe
- {
- fixed (char* chars = &key.GetPinnableReference())
- if (!this.TryInsertInternal(new string(chars, 0, key.Length), value, false))
- throw new ArgumentException("Given key is already present in the dictionary.", nameof(key));
- }
- }
-
- ///
- /// Attempts to insert a specific key and corresponding value into this dictionary.
- ///
- /// Key to insert.
- /// Value corresponding to this key.
- /// Whether the operation was successful.
- public bool TryAdd(string key, TValue value)
- => this.TryInsertInternal(key, value, false);
-
- ///
- /// Attempts to insert a specific key and corresponding value into this dictionary.
- ///
- /// Key to insert.
- /// Value corresponding to this key.
- /// Whether the operation was successful.
- public bool TryAdd(ReadOnlySpan key, TValue value)
- {
- unsafe
- {
- fixed (char* chars = &key.GetPinnableReference())
- return this.TryInsertInternal(new string(chars, 0, key.Length), value, false);
- }
- }
-
- ///
- /// Attempts to retrieve a value corresponding to the supplied key from this dictionary.
- ///
- /// Key to retrieve the value for.
- /// Retrieved value.
- /// Whether the operation was successful.
- public bool TryGetValue(string key, out TValue value)
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key));
-
- return this.TryRetrieveInternal(key.AsSpan(), out value);
- }
-
- ///
- /// Attempts to retrieve a value corresponding to the supplied key from this dictionary.
- ///
- /// Key to retrieve the value for.
- /// Retrieved value.
- /// Whether the operation was successful.
- public bool TryGetValue(ReadOnlySpan key, out TValue value)
- => this.TryRetrieveInternal(key, out value);
-
- ///
- /// Attempts to remove a value corresponding to the supplied key from this dictionary.
- ///
- /// Key to remove the value for.
- /// Removed value.
- /// Whether the operation was successful.
- public bool TryRemove(string key, out TValue value)
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key));
-
- return this.TryRemoveInternal(key.AsSpan(), out value);
- }
-
- ///
- /// Attempts to remove a value corresponding to the supplied key from this dictionary.
- ///
- /// Key to remove the value for.
- /// Removed value.
- /// Whether the operation was successful.
- public bool TryRemove(ReadOnlySpan key, out TValue value)
- => this.TryRemoveInternal(key, out value);
-
- ///
- /// Checks whether this dictionary contains the specified key.
- ///
- /// Key to check for in this dictionary.
- /// Whether the key was present in the dictionary.
- public bool ContainsKey(string key)
- => this.ContainsKeyInternal(key.AsSpan());
-
- ///
- /// Checks whether this dictionary contains the specified key.
- ///
- /// Key to check for in this dictionary.
- /// Whether the key was present in the dictionary.
- public bool ContainsKey(ReadOnlySpan key)
- => this.ContainsKeyInternal(key);
-
- ///
- /// Removes all items from this dictionary.
- ///
- public void Clear()
- {
- this._internalBuckets.Clear();
- this.Count = 0;
- }
-
- ///
- /// Gets an enumerator over key-value pairs in this dictionary.
- ///
- ///
- public IEnumerator> GetEnumerator()
- => new Enumerator(this);
-
- ///
- /// Removes the.
- ///
- /// The key.
- /// A bool.
- bool IDictionary.Remove(string key)
- => this.TryRemove(key.AsSpan(), out _);
-
- ///
- /// Adds the.
- ///
- /// The key.
- /// The value.
- void IDictionary.Add(object key, object value)
- {
- if (!(key is string tkey))
- throw new ArgumentException("Key needs to be an instance of a string.");
-
- if (!(value is TValue tvalue))
- {
- tvalue = default;
- if (tvalue != null)
- throw new ArgumentException($"Value needs to be an instance of {typeof(TValue)}.");
- }
-
- this.Add(tkey, tvalue);
- }
-
- ///
- /// Removes the.
- ///
- /// The key.
- void IDictionary.Remove(object key)
- {
- if (!(key is string tkey))
- throw new ArgumentException("Key needs to be an instance of a string.");
-
- this.TryRemove(tkey, out _);
- }
-
- ///
- /// Contains the.
- ///
- /// The key.
- /// A bool.
- bool IDictionary.Contains(object key)
- {
- if (!(key is string tkey))
- throw new ArgumentException("Key needs to be an instance of a string.");
-
- return this.ContainsKey(tkey);
- }
-
- ///
- /// Gets the enumerator.
- ///
- /// An IDictionaryEnumerator.
- IDictionaryEnumerator IDictionary.GetEnumerator()
- => new Enumerator(this);
-
- ///
- /// Adds the.
- ///
- /// The item.
- void ICollection>.Add(KeyValuePair item)
- => this.Add(item.Key, item.Value);
-
- ///
- /// Removes the.
- ///
- /// The item.
- /// A bool.
- bool ICollection>.Remove(KeyValuePair item)
- => this.TryRemove(item.Key, out _);
-
- ///
- /// Contains the.
- ///
- /// The item.
- /// A bool.
- bool ICollection>.Contains(KeyValuePair item)
- => this.TryGetValue(item.Key, out var value) && EqualityComparer.Default.Equals(value, item.Value);
-
- ///
- /// Copies the to.
- ///
- /// The array.
- /// The array index.
- void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex)
- {
- if (array.Length - arrayIndex < this.Count)
- throw new ArgumentException("Target array is too small.", nameof(array));
-
- var i = arrayIndex;
- foreach (var (k, v) in this._internalBuckets)
- {
- var kdv = v;
- while (kdv != null)
- {
- array[i++] = new KeyValuePair(kdv.Key, kdv.Value);
- kdv = kdv.Next;
- }
- }
- }
-
- ///
- /// Copies the to.
- ///
- /// The array.
- /// The array index.
- void ICollection.CopyTo(Array array, int arrayIndex)
- {
- if (array is KeyValuePair[] tarray)
- {
- (this as ICollection>).CopyTo(tarray, arrayIndex);
- return;
- }
-
- if (array is not object[])
- throw new ArgumentException($"Array needs to be an instance of {typeof(TValue[])} or object[].");
-
- var i = arrayIndex;
- foreach (var (k, v) in this._internalBuckets)
- {
- var kdv = v;
- while (kdv != null)
- {
- array.SetValue(new KeyValuePair(kdv.Key, kdv.Value), i++);
- kdv = kdv.Next;
- }
- }
- }
-
- ///
- /// Gets the enumerator.
- ///
- /// An IEnumerator.
- IEnumerator IEnumerable.GetEnumerator()
- => this.GetEnumerator();
-
- ///
- /// Tries the insert internal.
- ///
- /// The key.
- /// The value.
- /// If true, replace.
- /// A bool.
- private bool TryInsertInternal(string key, TValue value, bool replace)
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key), "Key cannot be null.");
-
- var hash = key.CalculateKnuthHash();
- if (!this._internalBuckets.ContainsKey(hash))
- {
- this._internalBuckets.Add(hash, new KeyedValue(key, hash, value));
- this.Count++;
- return true;
- }
-
- var kdv = this._internalBuckets[hash];
- var kdvLast = kdv;
- while (kdv != null)
- {
- if (kdv.Key == key)
- {
- if (!replace)
- return false;
-
- kdv.Value = value;
- return true;
- }
-
- kdvLast = kdv;
- kdv = kdv.Next;
- }
-
- kdvLast.Next = new KeyedValue(key, hash, value);
- this.Count++;
- return true;
- }
-
- ///
- /// Tries the retrieve internal.
- ///
- /// The key.
- /// The value.
- /// A bool.
- private bool TryRetrieveInternal(ReadOnlySpan key, out TValue value)
- {
- value = default;
-
- var hash = key.CalculateKnuthHash();
- if (!this._internalBuckets.TryGetValue(hash, out var kdv))
- return false;
-
- while (kdv != null)
- {
- if (key.SequenceEqual(kdv.Key.AsSpan()))
- {
- value = kdv.Value;
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// Tries the remove internal.
- ///
- /// The key.
- /// The value.
- /// A bool.
- private bool TryRemoveInternal(ReadOnlySpan key, out TValue value)
- {
- value = default;
-
- var hash = key.CalculateKnuthHash();
- if (!this._internalBuckets.TryGetValue(hash, out var kdv))
- return false;
-
- if (kdv.Next == null && key.SequenceEqual(kdv.Key.AsSpan()))
- {
- // Only bucket under this hash and key matches, pop the entire bucket
-
- value = kdv.Value;
- this._internalBuckets.Remove(hash);
- this.Count--;
- return true;
- }
- else if (kdv.Next == null)
- {
- // Only bucket under this hash and key does not match, cannot remove
-
- return false;
- }
- else if (key.SequenceEqual(kdv.Key.AsSpan()))
- {
- // First key in the bucket matches, pop it and set its child as current bucket
-
- value = kdv.Value;
- this._internalBuckets[hash] = kdv.Next;
- this.Count--;
- return true;
- }
-
- var kdvLast = kdv;
- kdv = kdv.Next;
- while (kdv != null)
- {
- if (key.SequenceEqual(kdv.Key.AsSpan()))
- {
- // Key matched, remove this bucket from the chain
-
- value = kdv.Value;
- kdvLast.Next = kdv.Next;
- this.Count--;
- return true;
- }
-
- kdvLast = kdv;
- kdv = kdv.Next;
- }
-
- return false;
- }
-
- ///
- /// Contains the key internal.
- ///
- /// The key.
- /// A bool.
- private bool ContainsKeyInternal(ReadOnlySpan key)
- {
- var hash = key.CalculateKnuthHash();
- if (!this._internalBuckets.TryGetValue(hash, out var kdv))
- return false;
-
- while (kdv != null)
- {
- if (key.SequenceEqual(kdv.Key.AsSpan()))
- return true;
-
- kdv = kdv.Next;
- }
-
- return false;
- }
-
- ///
- /// Gets the keys internal.
- ///
- /// An ImmutableArray.
- private ImmutableArray GetKeysInternal()
- {
- var builder = ImmutableArray.CreateBuilder(this.Count);
- foreach (var value in this._internalBuckets.Values)
- {
- var kdv = value;
- while (kdv != null)
- {
- builder.Add(kdv.Key);
- kdv = kdv.Next;
- }
- }
-
- return builder.MoveToImmutable();
- }
-
- ///
- /// Gets the values internal.
- ///
- /// An ImmutableArray.
- private ImmutableArray GetValuesInternal()
- {
- var builder = ImmutableArray.CreateBuilder(this.Count);
- foreach (var value in this._internalBuckets.Values)
- {
- var kdv = value;
- while (kdv != null)
- {
- builder.Add(kdv.Value);
- kdv = kdv.Next;
- }
- }
-
- return builder.MoveToImmutable();
- }
-
- ///
- /// The keyed value.
- ///
- private class KeyedValue
- {
- ///
- /// Gets the key hash.
- ///
- public ulong KeyHash { get; }
- ///
- /// Gets the key.
- ///
- public string Key { get; }
- ///
- /// Gets or sets the value.
- ///
- public TValue Value { get; set; }
-
- ///
- /// Gets or sets the next.
- ///
- public KeyedValue Next { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The key.
- /// The key hash.
- /// The value.
- public KeyedValue(string key, ulong keyHash, TValue value)
- {
- this.KeyHash = keyHash;
- this.Key = key;
- this.Value = value;
- }
- }
-
- ///
- /// The enumerator.
- ///
- private class Enumerator :
- IEnumerator>,
- IDictionaryEnumerator
- {
- ///
- /// Gets the current.
- ///
- public KeyValuePair Current { get; private set; }
- ///
- /// Gets the current.
- ///
- object IEnumerator.Current => this.Current;
- ///
- /// Gets the key.
- ///
- object IDictionaryEnumerator.Key => this.Current.Key;
- ///
- /// Gets the value.
- ///
- object IDictionaryEnumerator.Value => this.Current.Value;
- ///
- /// Gets the entry.
- ///
- DictionaryEntry IDictionaryEnumerator.Entry => new(this.Current.Key, this.Current.Value);
-
- ///
- /// Gets the internal dictionary.
- ///
- private readonly CharSpanLookupDictionary _internalDictionary;
-
- ///
- /// Gets the internal enumerator.
- ///
- private readonly IEnumerator> _internalEnumerator;
-
- ///
- /// Gets or sets the current value.
- ///
- private KeyedValue _currentValue;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The sp dict.
- public Enumerator(CharSpanLookupDictionary spDict)
- {
- this._internalDictionary = spDict;
- this._internalEnumerator = this._internalDictionary._internalBuckets.GetEnumerator();
- }
-
- ///
- /// Moves the next.
- ///
- /// A bool.
- public bool MoveNext()
- {
- var kdv = this._currentValue;
- if (kdv == null)
- {
- if (!this._internalEnumerator.MoveNext())
- return false;
-
- kdv = this._internalEnumerator.Current.Value;
- this.Current = new KeyValuePair(kdv.Key, kdv.Value);
-
- this._currentValue = kdv.Next;
- return true;
- }
-
- this.Current = new KeyValuePair(kdv.Key, kdv.Value);
- this._currentValue = kdv.Next;
- return true;
- }
-
- ///
- /// Resets the.
- ///
- public void Reset()
- {
- this._internalEnumerator.Reset();
- this.Current = default;
- this._currentValue = null;
- }
-
- ///
- /// Disposes the.
- ///
- public void Dispose() => this.Reset();
- }
- }
-}
diff --git a/DisCatSharp.Common/Types/CharSpanLookupReadOnlyDictionary.cs b/DisCatSharp.Common/Types/CharSpanLookupReadOnlyDictionary.cs
deleted file mode 100644
index 7a5a73a9f..000000000
--- a/DisCatSharp.Common/Types/CharSpanLookupReadOnlyDictionary.cs
+++ /dev/null
@@ -1,416 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Collections.ObjectModel;
-
-namespace DisCatSharp.Common
-{
- ///
- /// Represents collection of string keys and values, allowing the use of for dictionary operations.
- ///
- /// Type of items in this dictionary.
- public sealed class CharSpanLookupReadOnlyDictionary : IReadOnlyDictionary
- {
- ///
- /// Gets the collection of all keys present in this dictionary.
- ///
- public IEnumerable Keys => this.GetKeysInternal();
-
- ///
- /// Gets the collection of all values present in this dictionary.
- ///
- public IEnumerable Values => this.GetValuesInternal();
-
- ///
- /// Gets the total number of items in this dictionary.
- ///
- public int Count { get; }
-
- ///
- /// Gets a value corresponding to given key in this dictionary.
- ///
- /// Key to get or set the value for.
- /// Value matching the supplied key, if applicable.
- public TValue this[string key]
- {
- get
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key));
-
- if (!this.TryRetrieveInternal(key.AsSpan(), out var value))
- throw new KeyNotFoundException($"The given key '{key}' was not present in the dictionary.");
-
- return value;
- }
- }
-
- ///
- /// Gets a value corresponding to given key in this dictionary.
- ///
- /// Key to get or set the value for.
- /// Value matching the supplied key, if applicable.
- public TValue this[ReadOnlySpan key]
- {
- get
- {
- if (!this.TryRetrieveInternal(key, out var value))
- throw new KeyNotFoundException($"The given key was not present in the dictionary.");
-
- return value;
- }
- }
-
- ///
- /// Gets the internal buckets.
- ///
- private readonly IReadOnlyDictionary _internalBuckets;
-
- ///
- /// Creates a new with string keys and items of type and populates it with key-value pairs from supplied dictionary.
- ///
- /// Dictionary containing items to populate this dictionary with.
- public CharSpanLookupReadOnlyDictionary(IDictionary values)
- : this(values as IEnumerable>)
- { }
-
- ///
- /// Creates a new with string keys and items of type and populates it with key-value pairs from supplied dictionary.
- ///
- /// Dictionary containing items to populate this dictionary with.
- public CharSpanLookupReadOnlyDictionary(IReadOnlyDictionary values)
- : this(values as IEnumerable>)
- { }
-
- ///
- /// Creates a new with string keys and items of type and populates it with key-value pairs from supplied key-value collection.
- ///
- /// Dictionary containing items to populate this dictionary with.
- public CharSpanLookupReadOnlyDictionary(IEnumerable> values)
- {
- this._internalBuckets = PrepareItems(values, out var count);
- this.Count = count;
- }
-
- ///
- /// Attempts to retrieve a value corresponding to the supplied key from this dictionary.
- ///
- /// Key to retrieve the value for.
- /// Retrieved value.
- /// Whether the operation was successful.
- public bool TryGetValue(string key, out TValue value)
- {
- if (key == null)
- throw new ArgumentNullException(nameof(key));
-
- return this.TryRetrieveInternal(key.AsSpan(), out value);
- }
-
- ///
- /// Attempts to retrieve a value corresponding to the supplied key from this dictionary.
- ///
- /// Key to retrieve the value for.
- /// Retrieved value.
- /// Whether the operation was successful.
- public bool TryGetValue(ReadOnlySpan key, out TValue value)
- => this.TryRetrieveInternal(key, out value);
-
- ///
- /// Checks whether this dictionary contains the specified key.
- ///
- /// Key to check for in this dictionary.
- /// Whether the key was present in the dictionary.
- public bool ContainsKey(string key)
- => this.ContainsKeyInternal(key.AsSpan());
-
- ///
- /// Checks whether this dictionary contains the specified key.
- ///
- /// Key to check for in this dictionary.
- /// Whether the key was present in the dictionary.
- public bool ContainsKey(ReadOnlySpan key)
- => this.ContainsKeyInternal(key);
-
- ///
- /// Gets an enumerator over key-value pairs in this dictionary.
- ///
- ///
- public IEnumerator> GetEnumerator()
- => new Enumerator(this);
-
- ///
- /// Gets the enumerator.
- ///
- /// An IEnumerator.
- IEnumerator IEnumerable.GetEnumerator()
- => this.GetEnumerator();
-
- ///
- /// Tries the retrieve internal.
- ///
- /// The key.
- /// The value.
- /// A bool.
- private bool TryRetrieveInternal(ReadOnlySpan key, out TValue value)
- {
- value = default;
-
- var hash = key.CalculateKnuthHash();
- if (!this._internalBuckets.TryGetValue(hash, out var kdv))
- return false;
-
- while (kdv != null)
- {
- if (key.SequenceEqual(kdv.Key.AsSpan()))
- {
- value = kdv.Value;
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// Contains the key internal.
- ///
- /// The key.
- /// A bool.
- private bool ContainsKeyInternal(ReadOnlySpan key)
- {
- var hash = key.CalculateKnuthHash();
- if (!this._internalBuckets.TryGetValue(hash, out var kdv))
- return false;
-
- while (kdv != null)
- {
- if (key.SequenceEqual(kdv.Key.AsSpan()))
- return true;
-
- kdv = kdv.Next;
- }
-
- return false;
- }
-
- ///
- /// Gets the keys internal.
- ///
- /// An ImmutableArray.
- private ImmutableArray GetKeysInternal()
- {
- var builder = ImmutableArray.CreateBuilder(this.Count);
- foreach (var value in this._internalBuckets.Values)
- {
- var kdv = value;
- while (kdv != null)
- {
- builder.Add(kdv.Key);
- kdv = kdv.Next;
- }
- }
-
- return builder.MoveToImmutable();
- }
-
- ///
- /// Gets the values internal.
- ///
- /// An ImmutableArray.
- private ImmutableArray GetValuesInternal()
- {
- var builder = ImmutableArray.CreateBuilder(this.Count);
- foreach (var value in this._internalBuckets.Values)
- {
- var kdv = value;
- while (kdv != null)
- {
- builder.Add(kdv.Value);
- kdv = kdv.Next;
- }
- }
-
- return builder.MoveToImmutable();
- }
-
- ///
- /// Prepares the items.
- ///
- /// The items.
- /// The count.
- /// An IReadOnlyDictionary.
- private static IReadOnlyDictionary PrepareItems(IEnumerable> items, out int count)
- {
- count = 0;
- var dict = new Dictionary();
- foreach (var (k, v) in items)
- {
- if (k == null)
- throw new ArgumentException("Keys cannot be null.", nameof(items));
-
- var hash = k.CalculateKnuthHash();
- if (!dict.ContainsKey(hash))
- {
- dict.Add(hash, new KeyedValue(k, hash, v));
- count++;
- continue;
- }
-
- var kdv = dict[hash];
- var kdvLast = kdv;
- while (kdv != null)
- {
- if (kdv.Key == k)
- throw new ArgumentException("Given key is already present in the dictionary.", nameof(items));
-
- kdvLast = kdv;
- kdv = kdv.Next;
- }
-
- kdvLast.Next = new KeyedValue(k, hash, v);
- count++;
- }
-
- return new ReadOnlyDictionary(dict);
- }
-
- ///
- /// The keyed value.
- ///
- private class KeyedValue
- {
- ///
- /// Gets the key hash.
- ///
- public ulong KeyHash { get; }
- ///
- /// Gets the key.
- ///
- public string Key { get; }
- ///
- /// Gets or sets the value.
- ///
- public TValue Value { get; set; }
-
- ///
- /// Gets or sets the next.
- ///
- public KeyedValue Next { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The key.
- /// The key hash.
- /// The value.
- public KeyedValue(string key, ulong keyHash, TValue value)
- {
- this.KeyHash = keyHash;
- this.Key = key;
- this.Value = value;
- }
- }
-
- ///
- /// The enumerator.
- ///
- private class Enumerator : IEnumerator>
- {
- ///
- /// Gets the current.
- ///
- public KeyValuePair Current { get; private set; }
- ///
- /// Gets the current.
- ///
- object IEnumerator.Current => this.Current;
-
- ///
- /// Gets the internal dictionary.
- ///
- private readonly CharSpanLookupReadOnlyDictionary _internalDictionary;
-
- ///
- /// Gets the internal enumerator.
- ///
- private readonly IEnumerator> _internalEnumerator;
-
- ///
- /// Gets or sets the current value.
- ///
- private KeyedValue _currentValue;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The sp dict.
- public Enumerator(CharSpanLookupReadOnlyDictionary spDict)
- {
- this._internalDictionary = spDict;
- this._internalEnumerator = this._internalDictionary._internalBuckets.GetEnumerator();
- }
-
- ///
- /// Moves the next.
- ///
- /// A bool.
- public bool MoveNext()
- {
- var kdv = this._currentValue;
- if (kdv == null)
- {
- if (!this._internalEnumerator.MoveNext())
- return false;
-
- kdv = this._internalEnumerator.Current.Value;
- this.Current = new KeyValuePair(kdv.Key, kdv.Value);
-
- this._currentValue = kdv.Next;
- return true;
- }
-
- this.Current = new KeyValuePair(kdv.Key, kdv.Value);
- this._currentValue = kdv.Next;
- return true;
- }
-
- ///
- /// Resets the.
- ///
- public void Reset()
- {
- this._internalEnumerator.Reset();
- this.Current = default;
- this._currentValue = null;
- }
-
- ///
- /// Disposes the.
- ///
- public void Dispose() => this.Reset();
- }
- }
-}
diff --git a/DisCatSharp.Common/Types/ContinuousMemoryBuffer.cs b/DisCatSharp.Common/Types/ContinuousMemoryBuffer.cs
deleted file mode 100644
index d6163205b..000000000
--- a/DisCatSharp.Common/Types/ContinuousMemoryBuffer.cs
+++ /dev/null
@@ -1,255 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Buffers;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace DisCatSharp.Common.Types
-{
- ///
- /// Provides a resizable memory buffer analogous to , using a single continuous memory region instead.
- ///
- /// Type of item to hold in the buffer.
- public sealed class ContinuousMemoryBuffer : IMemoryBuffer where T : unmanaged
- {
- ///
- public ulong Capacity => (ulong)this._buff.Length;
-
- ///
- public ulong Length => (ulong)this._pos;
-
- ///
- public ulong Count => (ulong)(this._pos / this._itemSize);
-
- private readonly MemoryPool _pool;
- private IMemoryOwner _buffOwner;
- private Memory _buff;
- private readonly bool _clear;
- private int _pos;
- private readonly int _itemSize;
- private bool _isDisposed;
-
- ///
- /// Creates a new buffer with a specified segment size, specified number of initially-allocated segments, and supplied memory pool.
- ///
- /// Initial size of the buffer in bytes. Defaults to 64KiB.
- /// Memory pool to use for renting buffers. Defaults to .
- /// Determines whether the underlying buffers should be cleared on exit. If dealing with sensitive data, it might be a good idea to set this option to true.
- public ContinuousMemoryBuffer(int initialSize = 65536, MemoryPool memPool = default, bool clearOnDispose = false)
- {
- this._itemSize = Unsafe.SizeOf();
- this._pool = memPool ?? MemoryPool.Shared;
- this._clear = clearOnDispose;
-
- this._buffOwner = this._pool.Rent(initialSize);
- this._buff = this._buffOwner.Memory;
-
- this._isDisposed = false;
- }
-
- ///
- public void Write(ReadOnlySpan data)
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- var bytes = MemoryMarshal.AsBytes(data);
- this.EnsureSize(this._pos + bytes.Length);
-
- bytes.CopyTo(this._buff[this._pos..].Span);
- this._pos += bytes.Length;
- }
-
- ///
- public void Write(T[] data, int start, int count)
- => this.Write(data.AsSpan(start, count));
-
- ///
- public void Write(ArraySegment data)
- => this.Write(data.AsSpan());
-
- ///
- public void Write(Stream stream)
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- if (stream.CanSeek)
- this.WriteStreamSeekable(stream);
- else
- this.WriteStreamUnseekable(stream);
- }
-
- ///
- /// Writes the stream seekable.
- ///
- /// The stream.
- private void WriteStreamSeekable(Stream stream)
- {
- if (stream.Length > int.MaxValue)
- throw new ArgumentException("Stream is too long.", nameof(stream));
-
- this.EnsureSize(this._pos + (int)stream.Length);
- var memo = ArrayPool.Shared.Rent((int)stream.Length);
- try
- {
- var br = stream.Read(memo, 0, memo.Length);
- memo.AsSpan(0, br).CopyTo(this._buff[this._pos..].Span);
- }
- finally
- {
- ArrayPool.Shared.Return(memo);
- }
-
- this._pos += (int)stream.Length;
- }
-
- ///
- /// Writes the stream unseekable.
- ///
- /// The stream.
- private void WriteStreamUnseekable(Stream stream)
- {
- var memo = ArrayPool.Shared.Rent(4096);
- try
- {
- var br = 0;
- while ((br = stream.Read(memo, 0, memo.Length)) != 0)
- {
- this.EnsureSize(this._pos + br);
- memo.AsSpan(0, br).CopyTo(this._buff[this._pos..].Span);
- this._pos += br;
- }
- }
- finally
- {
- ArrayPool.Shared.Return(memo);
- }
- }
-
- ///
- public bool Read(Span destination, ulong source, out int itemsWritten)
- {
- itemsWritten = 0;
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- source *= (ulong)this._itemSize;
- if (source > this.Count)
- throw new ArgumentOutOfRangeException(nameof(source), "Cannot copy data from beyond the buffer.");
-
- var start = (int)source;
- var sbuff = this._buff[start..this._pos ].Span;
- var dbuff = MemoryMarshal.AsBytes(destination);
- if (sbuff.Length > dbuff.Length)
- sbuff = sbuff[..dbuff.Length];
-
- itemsWritten = sbuff.Length / this._itemSize;
- sbuff.CopyTo(dbuff);
-
- return this.Length - source != (ulong)itemsWritten;
- }
-
- ///
- public bool Read(T[] data, int start, int count, ulong source, out int itemsWritten)
- => this.Read(data.AsSpan(start, count), source, out itemsWritten);
-
- ///
- public bool Read(ArraySegment data, ulong source, out int itemsWritten)
- => this.Read(data.AsSpan(), source, out itemsWritten);
-
- ///
- public T[] ToArray()
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- return MemoryMarshal.Cast(this._buff[..this._pos].Span).ToArray();
- }
-
- ///
- public void CopyTo(Stream destination)
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- var buff = this._buff[..this._pos].ToArray();
- destination.Write(buff, 0, buff.Length);
- }
-
- ///
- public void Clear()
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- this._pos = 0;
- }
-
- ///
- /// Disposes of any resources claimed by this buffer.
- ///
- public void Dispose()
- {
- if (this._isDisposed)
- return;
-
- this._isDisposed = true;
- if (this._clear)
- this._buff.Span.Clear();
-
- this._buffOwner.Dispose();
- this._buff = default;
- }
-
- ///
- /// Ensures the size.
- ///
- /// The new capacity.
- private void EnsureSize(int newCapacity)
- {
- var cap = this._buff.Length;
- if (cap >= newCapacity)
- return;
-
- var factor = newCapacity / cap;
- if (newCapacity % cap != 0)
- ++factor;
-
- var newActualCapacity = cap * factor;
-
- var newBuffOwner = this._pool.Rent(newActualCapacity);
- var newBuff = newBuffOwner.Memory;
-
- this._buff.Span.CopyTo(newBuff.Span);
- if (this._clear)
- this._buff.Span.Clear();
-
- this._buffOwner.Dispose();
- this._buffOwner = newBuffOwner;
- this._buff = newBuff;
- }
- }
-}
diff --git a/DisCatSharp.Common/Types/IMemoryBuffer.cs b/DisCatSharp.Common/Types/IMemoryBuffer.cs
deleted file mode 100644
index d498b4816..000000000
--- a/DisCatSharp.Common/Types/IMemoryBuffer.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.IO;
-
-namespace DisCatSharp.Common.Types
-{
- ///
- /// An interface describing the API of resizable memory buffers, such as and .
- ///
- /// Type of item to hold in the buffer.
- public interface IMemoryBuffer : IDisposable where T : unmanaged
- {
- ///
- /// Gets the total capacity of this buffer. The capacity is the number of segments allocated, multiplied by size of individual segment.
- ///
- ulong Capacity { get; }
-
- ///
- /// Gets the amount of bytes currently written to the buffer. This number is never greater than .
- ///
- ulong Length { get; }
-
- ///
- /// Gets the number of items currently written to the buffer. This number is equal to divided by size of .
- ///
- ulong Count { get; }
-
- ///
- /// Appends data from a supplied buffer to this buffer, growing it if necessary.
- ///
- /// Buffer containing data to write.
- void Write(ReadOnlySpan data);
-
- ///
- /// Appends data from a supplied array to this buffer, growing it if necessary.
- ///
- /// Array containing data to write.
- /// Index from which to start reading the data.
- /// Number of bytes to read from the source.
- void Write(T[] data, int start, int count);
-
- ///
- /// Appends data from a supplied array slice to this buffer, growing it if necessary.
- ///
- /// Array slice containing data to write.
- void Write(ArraySegment data);
-
- ///
- /// Appends data from a supplied stream to this buffer, growing it if necessary.
- ///
- /// Stream to copy data from.
- void Write(Stream stream);
-
- ///
- /// Reads data from this buffer to the specified destination buffer. This method will write either as many
- /// bytes as there are in the destination buffer, or however many bytes are available in this buffer,
- /// whichever is less.
- ///
- /// Buffer to read the data from this buffer into.
- /// Starting position in this buffer to read from.
- /// Number of items written to the destination buffer.
- /// Whether more data is available in this buffer.
- bool Read(Span destination, ulong source, out int itemsWritten);
-
- ///
- /// Reads data from this buffer to specified destination array. This method will write either as many bytes
- /// as specified for the destination array, or however many bytes are available in this buffer, whichever is
- /// less.
- ///
- /// Array to read the data from this buffer into.
- /// Starting position in the target array to write to.
- /// Maximum number of bytes to write to target array.
- /// Starting position in this buffer to read from.
- /// Number of items written to the destination buffer.
- /// Whether more data is available in this buffer.
- bool Read(T[] data, int start, int count, ulong source, out int itemsWritten);
-
- ///
- /// Reads data from this buffer to specified destination array slice. This method will write either as many
- /// bytes as specified in the target slice, or however many bytes are available in this buffer, whichever is
- /// less.
- ///
- ///
- ///
- /// Number of items written to the destination buffer.
- /// Whether more data is available in this buffer.
- bool Read(ArraySegment data, ulong source, out int itemsWritten);
-
- ///
- /// Converts this buffer into a single continuous byte array.
- ///
- /// Converted byte array.
- T[] ToArray();
-
- ///
- /// Copies all the data from this buffer to a stream.
- ///
- /// Stream to copy this buffer's data to.
- void CopyTo(Stream destination);
-
- ///
- /// Resets the buffer's pointer to the beginning, allowing for reuse.
- ///
- void Clear();
- }
-}
diff --git a/DisCatSharp.Common/Types/LinqMethods.cs b/DisCatSharp.Common/Types/LinqMethods.cs
index 576afe2cc..bd601cc85 100644
--- a/DisCatSharp.Common/Types/LinqMethods.cs
+++ b/DisCatSharp.Common/Types/LinqMethods.cs
@@ -1,79 +1,76 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2022 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
namespace DisCatSharp.Common
{
///
/// Various Methods for Linq
///
public static class LinqMethods
{
///
/// Safely tries to get the first match out of a list.
///
/// Value type of list.
/// The list to use.
/// The predicate.
/// The value to get if succeeded
/// Whether a value was found.
-#nullable enable
public static bool GetFirstValueWhere(this List? list, Func predicate, out TSource? value)
{
- if (list == null || !list.Any())
+ if (list.EmptyOrNull())
{
value = default;
return false;
}
value = list.Where(predicate).FirstOrDefault();
return value is not null;
}
-#nullable disable
///
/// Safely tries to extract the value of the first match where target key is found, otherwise null.
///
/// Key type of dictionary.
/// Value type of dictionary.
/// The dictionary to use.
/// The key to search for.
/// The value to get if succeeded.
/// Whether a value was found through the key.
-#nullable enable
- public static bool GetFirstValueByKey(this Dictionary? dict, TKey? key, out TValue? value)
+ public static bool GetFirstValueByKey(this Dictionary? dict, TKey? key, out TValue? value)
+ where TKey : notnull
{
if (dict == null)
{
value = default;
return false;
}
return dict.TryGetValue(key, out value);
}
-#nullable disable
}
}
diff --git a/DisCatSharp.Common/Types/MemoryBuffer.cs b/DisCatSharp.Common/Types/MemoryBuffer.cs
deleted file mode 100644
index aca6d3151..000000000
--- a/DisCatSharp.Common/Types/MemoryBuffer.cs
+++ /dev/null
@@ -1,340 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Buffers;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace DisCatSharp.Common.Types
-{
- ///
- /// Provides a resizable memory buffer, which can be read from and written to. It will automatically resize whenever required.
- ///
- /// Type of item to hold in the buffer.
- public sealed class MemoryBuffer : IMemoryBuffer where T : unmanaged
- {
- ///
- public ulong Capacity => this._segments.Aggregate(0UL, (a, x) => a + (ulong)x.Memory.Length); // .Sum() does only int
-
- ///
- public ulong Length { get; private set; }
-
- ///
- public ulong Count => this.Length / (ulong)this._itemSize;
-
- private readonly MemoryPool _pool;
- private readonly int _segmentSize;
- private int _lastSegmentLength;
- private int _segNo;
- private readonly bool _clear;
- private readonly List> _segments;
- private readonly int _itemSize;
- private bool _isDisposed;
-
- ///
- /// Creates a new buffer with a specified segment size, specified number of initially-allocated segments, and supplied memory pool.
- ///
- /// Byte size of an individual segment. Defaults to 64KiB.
- /// Number of segments to allocate. Defaults to 0.
- /// Memory pool to use for renting buffers. Defaults to .
- /// Determines whether the underlying buffers should be cleared on exit. If dealing with sensitive data, it might be a good idea to set this option to true.
- public MemoryBuffer(int segmentSize = 65536, int initialSegmentCount = 0, MemoryPool memPool = default, bool clearOnDispose = false)
- {
- this._itemSize = Unsafe.SizeOf();
- if (segmentSize % this._itemSize != 0)
- throw new ArgumentException("Segment size must match size of individual item.");
-
- this._pool = memPool ?? MemoryPool.Shared;
-
- this._segmentSize = segmentSize;
- this._segNo = 0;
- this._lastSegmentLength = 0;
- this._clear = clearOnDispose;
-
- this._segments = new List>(initialSegmentCount + 1);
- for (var i = 0; i < initialSegmentCount; i++)
- this._segments.Add(this._pool.Rent(this._segmentSize));
-
- this.Length = 0;
-
- this._isDisposed = false;
- }
-
- ///
- public void Write(ReadOnlySpan data)
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- var src = MemoryMarshal.AsBytes(data);
- this.Grow(src.Length);
-
- while (this._segNo < this._segments.Count && src.Length > 0)
- {
- var seg = this._segments[this._segNo];
- var mem = seg.Memory;
- var avs = mem.Length - this._lastSegmentLength;
- avs = avs > src.Length
- ? src.Length
- : avs;
- var dmem = mem[this._lastSegmentLength..];
-
- src[..avs].CopyTo(dmem.Span);
- src = src[avs..];
-
- this.Length += (ulong)avs;
- this._lastSegmentLength += avs;
-
- if (this._lastSegmentLength == mem.Length)
- {
- this._segNo++;
- this._lastSegmentLength = 0;
- }
- }
- }
-
- ///
- public void Write(T[] data, int start, int count)
- => this.Write(data.AsSpan(start, count));
-
- ///
- public void Write(ArraySegment data)
- => this.Write(data.AsSpan());
-
- ///
- public void Write(Stream stream)
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- if (stream.CanSeek)
- this.WriteStreamSeekable(stream);
- else
- this.WriteStreamUnseekable(stream);
- }
-
- ///
- /// Writes the stream seekable.
- ///
- /// The stream.
- private void WriteStreamSeekable(Stream stream)
- {
- var len = (int)(stream.Length - stream.Position);
- this.Grow(len);
-
- var buff = new byte[this._segmentSize];
-
- while (this._segNo < this._segments.Count && len > 0)
- {
- var seg = this._segments[this._segNo];
- var mem = seg.Memory;
- var avs = mem.Length - this._lastSegmentLength;
- avs = avs > len
- ? len
- : avs;
- var dmem = mem[this._lastSegmentLength..];
-
- var lsl = this._lastSegmentLength;
- var slen = dmem.Span.Length - lsl;
- stream.Read(buff, 0, slen);
- buff.AsSpan(0, slen).CopyTo(dmem.Span);
- len -= dmem.Span.Length;
-
- this.Length += (ulong)avs;
- this._lastSegmentLength += avs;
-
- if (this._lastSegmentLength == mem.Length)
- {
- this._segNo++;
- this._lastSegmentLength = 0;
- }
- }
- }
-
- ///
- /// Writes the stream unseekable.
- ///
- /// The stream.
- private void WriteStreamUnseekable(Stream stream)
- {
- var read = 0;
- var buff = new byte[this._segmentSize];
- var buffs = buff.AsSpan();
- while ((read = stream.Read(buff, 0, buff.Length - this._lastSegmentLength)) != 0)
- this.Write(MemoryMarshal.Cast(buffs[..read]));
- }
-
- ///
- public bool Read(Span destination, ulong source, out int itemsWritten)
- {
- itemsWritten = 0;
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- source *= (ulong)this._itemSize;
- if (source > this.Count)
- throw new ArgumentOutOfRangeException(nameof(source), "Cannot copy data from beyond the buffer.");
-
- // Find where to begin
- var i = 0;
- for (; i < this._segments.Count; i++)
- {
- var seg = this._segments[i];
- var mem = seg.Memory;
- if ((ulong)mem.Length > source)
- break;
-
- source -= (ulong)mem.Length;
- }
-
- // Do actual copy
- var dl = (int)(this.Length - source);
- var sri = (int)source;
- var dst = MemoryMarshal.AsBytes(destination);
- for (; i < this._segments.Count && dst.Length > 0; i++)
- {
- var seg = this._segments[i];
- var mem = seg.Memory;
- var src = mem.Span;
-
- if (sri != 0)
- {
- src = src[sri..];
- sri = 0;
- }
-
- if (itemsWritten + src.Length > dl)
- src = src[..(dl - itemsWritten)];
-
- if (src.Length > dst.Length)
- src = src[..dst.Length];
-
- src.CopyTo(dst);
- dst = dst[src.Length..];
- itemsWritten += src.Length;
- }
-
- itemsWritten /= this._itemSize;
- return this.Length - source != (ulong)itemsWritten;
- }
-
- ///
- public bool Read(T[] data, int start, int count, ulong source, out int itemsWritten)
- => this.Read(data.AsSpan(start, count), source, out itemsWritten);
-
- ///
- public bool Read(ArraySegment data, ulong source, out int itemsWritten)
- => this.Read(data.AsSpan(), source, out itemsWritten);
-
- ///
- public T[] ToArray()
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- var bytes = new T[this.Count];
- this.Read(bytes, 0, out _);
- return bytes;
- }
-
- ///
- public void CopyTo(Stream destination)
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- var longest = this._segments.Max(x => x.Memory.Length);
- var buff = new byte[longest];
-
- foreach (var seg in this._segments)
- {
- var mem = seg.Memory.Span;
- var spn = buff.AsSpan(0, mem.Length);
-
- mem.CopyTo(spn);
- destination.Write(buff, 0, spn.Length);
- }
- }
-
- ///
- public void Clear()
- {
- if (this._isDisposed)
- throw new ObjectDisposedException("This buffer is disposed.");
-
- this._segNo = 0;
- this._lastSegmentLength = 0;
- this.Length = 0;
- }
-
- ///
- /// Disposes of any resources claimed by this buffer.
- ///
- public void Dispose()
- {
- if (this._isDisposed)
- return;
-
- this._isDisposed = true;
- foreach (var segment in this._segments)
- {
- if (this._clear)
- segment.Memory.Span.Clear();
-
- segment.Dispose();
- }
- }
-
- ///
- /// Grows the.
- ///
- /// The min amount.
- private void Grow(int minAmount)
- {
- var capacity = this.Capacity;
- var length = this.Length;
- var totalAmt = length + (ulong)minAmount;
- if (capacity >= totalAmt)
- return; // we're good
-
- var amt = (int)(totalAmt - capacity);
- var segCount = amt / this._segmentSize;
- if (amt % this._segmentSize != 0)
- segCount++;
-
- // Basically List.EnsureCapacity
- // Default grow behaviour is minimum current*2
- var segCap = this._segments.Count + segCount;
- if (segCap > this._segments.Capacity)
- this._segments.Capacity = segCap < this._segments.Capacity * 2
- ? this._segments.Capacity * 2
- : segCap;
-
- for (var i = 0; i < segCount; i++)
- this._segments.Add(this._pool.Rent(this._segmentSize));
- }
- }
-}
diff --git a/DisCatSharp.Common/Types/SecureRandom.cs b/DisCatSharp.Common/Types/SecureRandom.cs
deleted file mode 100644
index 6daf056b9..000000000
--- a/DisCatSharp.Common/Types/SecureRandom.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Buffers;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Security.Cryptography;
-
-namespace DisCatSharp.Common
-{
- ///
- /// Provides a cryptographically-secure pseudorandom number generator (CSPRNG) implementation compatible with .
- ///
- public sealed class SecureRandom : Random, IDisposable
- {
- ///
- /// Gets the r n g.
- ///
- private readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
-
- private volatile bool _isDisposed;
-
- ///
- /// Creates a new instance of .
- ///
- public SecureRandom()
- { }
-
- ///
- /// Finalizes this instance by disposing it.
- ///
- ~SecureRandom()
- {
- this.Dispose();
- }
-
- ///
- /// Fills a supplied buffer with random bytes.
- ///
- /// Buffer to fill with random bytes.
- public void GetBytes(byte[] buffer) => this._rng.GetBytes(buffer);
-
- ///
- /// Fills a supplied buffer with random nonzero bytes.
- ///
- /// Buffer to fill with random nonzero bytes.
- public void GetNonZeroBytes(byte[] buffer) => this._rng.GetNonZeroBytes(buffer);
-
- ///
- /// Fills a supplied memory region with random bytes.
- ///
- /// Memory region to fill with random bytes.
- public void GetBytes(Span buffer)
- {
- var buff = ArrayPool.Shared.Rent(buffer.Length);
- try
- {
- var buffSpan = buff.AsSpan(0, buffer.Length);
- this._rng.GetBytes(buff);
- buffSpan.CopyTo(buffer);
- }
- finally
- {
- ArrayPool.Shared.Return(buff);
- }
- }
-
- ///
- /// Fills a supplied memory region with random nonzero bytes.
- ///
- /// Memory region to fill with random nonzero bytes.
- public void GetNonZeroBytes(Span buffer)
- {
- var buff = ArrayPool.Shared.Rent(buffer.Length);
- try
- {
- var buffSpan = buff.AsSpan(0, buffer.Length);
- this._rng.GetNonZeroBytes(buff);
- buffSpan.CopyTo(buffer);
- }
- finally
- {
- ArrayPool.Shared.Return(buff);
- }
- }
-
- ///
- /// Generates a signed 8-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public sbyte GetInt8(sbyte min = 0, sbyte max = sbyte.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- var offset = (sbyte)(min < 0 ? -min : 0);
- min += offset;
- max += offset;
-
- return (sbyte)(Math.Abs(this.Generate()) % (max - min) + min - offset);
- }
-
- ///
- /// Generates a unsigned 8-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public byte GetUInt8(byte min = 0, byte max = byte.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- return (byte)(this.Generate() % (max - min) + min);
- }
-
- ///
- /// Generates a signed 16-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public short GetInt16(short min = 0, short max = short.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- var offset = (short)(min < 0 ? -min : 0);
- min += offset;
- max += offset;
-
- return (short)(Math.Abs(this.Generate()) % (max - min) + min - offset);
- }
-
- ///
- /// Generates a unsigned 16-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public ushort GetUInt16(ushort min = 0, ushort max = ushort.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- return (ushort)(this.Generate() % (max - min) + min);
- }
-
- ///
- /// Generates a signed 32-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public int GetInt32(int min = 0, int max = int.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- var offset = min < 0 ? -min : 0;
- min += offset;
- max += offset;
-
- return Math.Abs(this.Generate()) % (max - min) + min - offset;
- }
-
- ///
- /// Generates a unsigned 32-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public uint GetUInt32(uint min = 0, uint max = uint.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- return this.Generate() % (max - min) + min;
- }
-
- ///
- /// Generates a signed 64-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public long GetInt64(long min = 0, long max = long.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- var offset = min < 0 ? -min : 0;
- min += offset;
- max += offset;
-
- return Math.Abs(this.Generate()) % (max - min) + min - offset;
- }
-
- ///
- /// Generates a unsigned 64-bit integer within specified range.
- ///
- /// Minimum value to generate. Defaults to 0.
- /// Maximum value to generate. Defaults to .
- /// Generated random value.
- public ulong GetUInt64(ulong min = 0, ulong max = ulong.MaxValue)
- {
- if (max <= min)
- throw new ArgumentException("Maximum needs to be greater than minimum.", nameof(max));
-
- return this.Generate() % (max - min) + min;
- }
-
- ///
- /// Generates a 32-bit floating-point number between 0.0 and 1.0.
- ///
- /// Generated 32-bit floating-point number.
- public float GetSingle()
- {
- var (i1, i2) = ((float)this.GetInt32(), (float)this.GetInt32());
- return i1 / i2 % 1.0F;
- }
-
- ///
- /// Generates a 64-bit floating-point number between 0.0 and 1.0.
- ///
- /// Generated 64-bit floating-point number.
- public double GetDouble()
- {
- var (i1, i2) = ((double)this.GetInt64(), (double)this.GetInt64());
- return i1 / i2 % 1.0;
- }
-
- ///
- /// Generates a 32-bit integer between 0 and . Upper end exclusive.
- ///
- /// Generated 32-bit integer.
- public override int Next()
- => this.GetInt32();
-
- ///
- /// Generates a 32-bit integer between 0 and . Upper end exclusive.
- ///
- /// Maximum value of the generated integer.
- /// Generated 32-bit integer.
- public override int Next(int maxValue)
- => this.GetInt32(0, maxValue);
-
- ///
- /// Generates a 32-bit integer between and . Upper end exclusive.
- ///
- /// Minimum value of the generate integer.
- /// Maximum value of the generated integer.
- /// Generated 32-bit integer.
- public override int Next(int minValue, int maxValue)
- => this.GetInt32(minValue, maxValue);
-
- ///
- /// Generates a 64-bit floating-point number between 0.0 and 1.0. Upper end exclusive.
- ///
- /// Generated 64-bit floating-point number.
- public override double NextDouble()
- => this.GetDouble();
-
- ///
- /// Fills specified buffer with random bytes.
- ///
- /// Buffer to fill with bytes.
- public override void NextBytes(byte[] buffer)
- => this.GetBytes(buffer);
-
- ///
- /// Fills specified memory region with random bytes.
- ///
- /// Memory region to fill with bytes.
- public new void NextBytes(Span buffer)
- => this.GetBytes(buffer);
-
- ///
- /// Disposes this instance and its resources.
- ///
- public void Dispose()
- {
- if (this._isDisposed)
- return;
-
- this._isDisposed = true;
- this._rng.Dispose();
- }
-
- ///
- /// Generates a random 64-bit floating-point number between 0.0 and 1.0. Upper end exclusive.
- ///
- /// Generated 64-bit floating-point number.
- protected override double Sample()
- => this.GetDouble();
-
- ///
- /// Generates the.
- ///
- /// A T.
- private T Generate() where T : struct
- {
- var size = Unsafe.SizeOf();
- Span buff = stackalloc byte[size];
- this.GetBytes(buff);
- return MemoryMarshal.Read(buff);
- }
- }
-}
diff --git a/DisCatSharp.Common/Types/Serialization/ComplexDecomposer.cs b/DisCatSharp.Common/Types/Serialization/ComplexDecomposer.cs
deleted file mode 100644
index 0878380cd..000000000
--- a/DisCatSharp.Common/Types/Serialization/ComplexDecomposer.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-// This file is part of the DisCatSharp project, based off DSharpPlus.
-//
-// Copyright (c) 2021-2022 AITSYS
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Numerics;
-
-namespace DisCatSharp.Common.Serialization
-{
- ///
- /// Decomposes numbers into tuples (arrays of 2).
- ///
- public sealed class ComplexDecomposer : IDecomposer
- {
- ///
- /// Gets the t complex.
- ///
- private static Type s_complex { get; } = typeof(Complex);
- ///
- /// Gets the t double array.
- ///
- private static Type s_doubleArray { get; } = typeof(double[]);
- ///
- /// Gets the t double enumerable.
- ///
- private static Type s_doubleEnumerable { get; } = typeof(IEnumerable);
- ///
- /// Gets the t object array.
- ///
- private static Type s_objectArray { get; } = typeof(object[]);
- ///
- /// Gets the t object enumerable.
- ///
- private static Type s_objectEnumerable { get; } = typeof(IEnumerable