Skip to content

Commit 040f40c

Browse files
authored
Push new factory system
Signed-off-by: Xen <lordofxen@deskasoft.com>
1 parent de0b2b3 commit 040f40c

File tree

8 files changed

+809
-0
lines changed

8 files changed

+809
-0
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// *
2+
// *****************************************************************************
3+
// *
4+
// * Copyright (c) 2025 Deskasoft International
5+
// *
6+
// * Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// * of this software and associated documentation files (the ""Software""), to deal
8+
// * in the Software without restriction, including without limitation the rights
9+
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// * copies of the Software, and to permit persons to whom the Software is
11+
// * furnished to do so, subject to the following conditions:
12+
// *
13+
// * The above copyright notice and this permission notice shall be included in all
14+
// * copies or substantial portions of the Software.
15+
// *
16+
// * THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// * SOFTWARE.
23+
// *
24+
// *
25+
// * Please refer to LICENSE file.
26+
// *
27+
// ******************************************************************************
28+
// *
29+
30+
using System;
31+
using System.Collections.Generic;
32+
using System.Linq;
33+
34+
namespace HashifyNet
35+
{
36+
public sealed partial class HashFactory
37+
{
38+
/// <summary>
39+
/// <inheritdoc cref="IHashFactory.CreateInstance(Type)"/>
40+
/// </summary>
41+
/// <param name="type"><inheritdoc cref="IHashFactory.CreateInstance(Type)"/></param>
42+
/// <returns><inheritdoc cref="IHashFactory.CreateInstance(Type)"/></returns>
43+
/// <exception cref="ArgumentNullException"><inheritdoc cref="IHashFactory.CreateInstance(Type)"/></exception>
44+
/// <exception cref="ArgumentException"><inheritdoc cref="IHashFactory.CreateInstance(Type)"/></exception>
45+
/// <exception cref="NotImplementedException"><inheritdoc cref="IHashFactory.CreateInstance(Type)"/></exception>
46+
public static IHashFunctionBase Create(Type type)
47+
{
48+
return Singleton.CreateInstance(type);
49+
}
50+
51+
/// <summary>
52+
/// <inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/>
53+
/// </summary>
54+
/// <param name="type"><inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/></param>
55+
/// <param name="config"><inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/></param>
56+
/// <returns><inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/></returns>
57+
/// <exception cref="ArgumentNullException"><inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/></exception>
58+
/// <exception cref="ArgumentException"><inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/></exception>
59+
/// <exception cref="NotImplementedException"><inheritdoc cref="IHashFactory.CreateInstance(Type, IHashConfigBase)"/></exception>
60+
public static IHashFunctionBase Create(Type type, IHashConfigBase config)
61+
{
62+
return Singleton.CreateInstance(type, config);
63+
}
64+
65+
/// <summary>
66+
/// Retrieves an array of hash function instances based on the specified hash function type.
67+
/// </summary>
68+
/// <param name="type">The type of hash functions to retrieve. This determines the set of hash algorithms to be instantiated.</param>
69+
/// <param name="defaultConfigMap">An optional dictionary mapping hash function types to their corresponding configuration objects. If provided, the
70+
/// configurations in this dictionary will be used to initialize the hash function instances. If a type is not present
71+
/// in the dictionary, a default configuration will be used if available.</param>
72+
/// <param name="ignoredFunctions">An optional array of hash function types to be ignored during instantiation. Any types present in this array (and any types derive from the types in this array) will be skipped.</param>
73+
/// <returns>An array of <see cref="IHashFunctionBase"/> instances representing the hash functions for the specified type.</returns>
74+
/// <exception cref="InvalidOperationException">Thrown if no hash algorithms are found for the specified <paramref name="type"/>.</exception>
75+
public static IHashFunctionBase[] GetHashFunctions(HashFunctionType type, Dictionary<Type, IHashConfigBase> defaultConfigMap = null, params Type[] ignoredFunctions)
76+
{
77+
Type[] functions = GetHashAlgorithms(type);
78+
79+
if (functions == null || functions.Length < 1)
80+
{
81+
throw new InvalidOperationException("No hash algorithms found.");
82+
}
83+
84+
List<IHashFunctionBase> instances = new List<IHashFunctionBase>();
85+
for (int i = 0; i < functions.Length; ++i)
86+
{
87+
Type funcType = functions[i];
88+
89+
if (ignoredFunctions != null && ignoredFunctions.Length > 0)
90+
{
91+
foreach (Type ignoredType in ignoredFunctions)
92+
{
93+
if ((funcType.IsGenericType && (funcType.GetGenericTypeDefinition() == ignoredType || ignoredType.IsAssignableFrom(funcType.GetGenericTypeDefinition()))) || funcType == ignoredType || ignoredType.IsAssignableFrom(funcType))
94+
{
95+
funcType = null;
96+
break;
97+
}
98+
}
99+
}
100+
101+
if (funcType == null)
102+
{
103+
continue;
104+
}
105+
106+
if (defaultConfigMap != null && defaultConfigMap.ContainsKey(funcType))
107+
{
108+
instances.Add(Singleton.CreateInstance(funcType, defaultConfigMap[funcType]));
109+
}
110+
else
111+
{
112+
instances.Add(Singleton.CreateInstance(funcType));
113+
}
114+
}
115+
116+
return instances.ToArray();
117+
}
118+
119+
/// <summary>
120+
/// Retrieves an array of hash algorithm types based on the specified hash function category.
121+
/// </summary>
122+
/// <remarks>The returned array may include both cryptographic and non-cryptographic hash algorithms if the
123+
/// specified <paramref name="type"/> includes both categories.</remarks>
124+
/// <param name="type">A bitwise combination of <see cref="HashFunctionType"/> values that specifies the category of hash functions to
125+
/// retrieve. Use <see cref="HashFunctionType.Cryptographic"/> to include cryptographic hash algorithms, <see
126+
/// cref="HashFunctionType.Noncryptographic"/> to include non-cryptographic hash algorithms, or both.</param>
127+
/// <returns>An array of <see cref="Type"/> objects representing the hash algorithms that match the specified category. If no
128+
/// algorithms match the specified category, an empty array is returned. If the given <paramref name="type"/> neither contains <seealso cref="HashFunctionType.Cryptographic"/> nor <seealso cref="HashFunctionType.Noncryptographic"/>, the return value will be <see langword="null"/>.</returns>
129+
public static Type[] GetHashAlgorithms(HashFunctionType type)
130+
{
131+
Type[] functions = null;
132+
if ((type & HashFunctionType.Cryptographic) == HashFunctionType.Cryptographic)
133+
{
134+
functions = GetAllCryptographicHashAlgorithms();
135+
}
136+
137+
if ((type & HashFunctionType.Noncryptographic) == HashFunctionType.Noncryptographic)
138+
{
139+
Type[] nonCrypto = GetAllNonCryptographicHashAlgorithms();
140+
if (functions == null)
141+
{
142+
functions = nonCrypto;
143+
}
144+
else
145+
{
146+
functions = functions.Union(nonCrypto).ToArray();
147+
}
148+
}
149+
150+
return functions;
151+
}
152+
153+
private static Type[] GetAllHashAlgorithms()
154+
{
155+
if (_implementations.Count < 1)
156+
{
157+
return null;
158+
}
159+
160+
Type[] types = new Type[_implementations.Keys.Count];
161+
_implementations.Keys.CopyTo(types, 0);
162+
return types;
163+
}
164+
165+
private static Type[] GetAllCryptographicHashAlgorithms()
166+
{
167+
Type[] all = GetAllHashAlgorithms();
168+
if (all == null || all.Length < 1)
169+
{
170+
return null;
171+
}
172+
173+
return all.Where(t =>
174+
t.GetInterfaces().Any(i => i.IsGenericType &&
175+
i.GetGenericTypeDefinition() == typeof(ICryptographicHashFunction<>))
176+
).ToArray();
177+
}
178+
179+
private static Type[] GetAllNonCryptographicHashAlgorithms()
180+
{
181+
Type[] all = GetAllHashAlgorithms();
182+
if (all == null || all.Length < 1)
183+
{
184+
return null;
185+
}
186+
187+
return all.Where(t =>
188+
t.GetInterfaces().Any(i => i.IsGenericType &&
189+
i.GetGenericTypeDefinition() == typeof(IHashFunction<>))
190+
&&
191+
!t.GetInterfaces().Any(i => i.IsGenericType &&
192+
i.GetGenericTypeDefinition() == typeof(ICryptographicHashFunction<>))
193+
).ToArray();
194+
}
195+
}
196+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// *
2+
// *****************************************************************************
3+
// *
4+
// * Copyright (c) 2025 Deskasoft International
5+
// *
6+
// * Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// * of this software and associated documentation files (the ""Software""), to deal
8+
// * in the Software without restriction, including without limitation the rights
9+
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// * copies of the Software, and to permit persons to whom the Software is
11+
// * furnished to do so, subject to the following conditions:
12+
// *
13+
// * The above copyright notice and this permission notice shall be included in all
14+
// * copies or substantial portions of the Software.
15+
// *
16+
// * THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// * SOFTWARE.
23+
// *
24+
// *
25+
// * Please refer to LICENSE file.
26+
// *
27+
// ******************************************************************************
28+
// *
29+
30+
namespace HashifyNet
31+
{
32+
public sealed partial class HashFactory<TAlgorithmInterface, TConfig>
33+
{
34+
/// <summary>
35+
/// <inheritdoc cref="HashFactory{TAlgorithmInterface, TConfig}.CreateInstance()"/>
36+
/// </summary>
37+
/// <returns><inheritdoc cref="HashFactory{TAlgorithmInterface, TConfig}.CreateInstance()"/></returns>
38+
public static TAlgorithmInterface Create()
39+
{
40+
return Singleton.CreateInstance();
41+
}
42+
43+
/// <summary>
44+
/// <inheritdoc cref="HashFactory{TAlgorithmInterface, TConfig}.CreateInstance(TConfig)"/>
45+
/// </summary>
46+
/// <param name="config"><inheritdoc cref="HashFactory{TAlgorithmInterface, TConfig}.CreateInstance(TConfig)"/></param>
47+
/// <returns><inheritdoc cref="HashFactory{TAlgorithmInterface, TConfig}.CreateInstance(TConfig)"/></returns>
48+
public static TAlgorithmInterface Create(TConfig config)
49+
{
50+
return Singleton.CreateInstance(config);
51+
}
52+
}
53+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// *
2+
// *****************************************************************************
3+
// *
4+
// * Copyright (c) 2025 Deskasoft International
5+
// *
6+
// * Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// * of this software and associated documentation files (the ""Software""), to deal
8+
// * in the Software without restriction, including without limitation the rights
9+
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// * copies of the Software, and to permit persons to whom the Software is
11+
// * furnished to do so, subject to the following conditions:
12+
// *
13+
// * The above copyright notice and this permission notice shall be included in all
14+
// * copies or substantial portions of the Software.
15+
// *
16+
// * THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// * SOFTWARE.
23+
// *
24+
// *
25+
// * Please refer to LICENSE file.
26+
// *
27+
// ******************************************************************************
28+
// *
29+
30+
using System;
31+
32+
namespace HashifyNet
33+
{
34+
/// <summary>
35+
/// Provides a factory for creating instances of hash algorithms that implement the specified algorithm interface and
36+
/// configuration type.
37+
/// </summary>
38+
/// <remarks>This factory is designed to create instances of hash algorithms that conform to the specified
39+
/// interface and configuration type. It supports creating algorithms with default configurations or with a
40+
/// user-specified configuration.</remarks>
41+
/// <typeparam name="TAlgorithmInterface">The interface type that the hash algorithm implements. This must be a type that implements <see
42+
/// cref="IHashFunction{TConfig}"/>.</typeparam>
43+
/// <typeparam name="TConfig">The type of the configuration object used to configure the hash algorithm. This must be a type that implements <see
44+
/// cref="IHashConfig{TConfig}"/>.</typeparam>
45+
public sealed partial class HashFactory<TAlgorithmInterface, TConfig> : IGenericHashFactory<TAlgorithmInterface, TConfig> where TAlgorithmInterface : IHashFunction<TConfig>
46+
where TConfig : IHashConfig<TConfig>
47+
{
48+
private static HashFactory<TAlgorithmInterface, TConfig> _singleton = null;
49+
private static HashFactory<TAlgorithmInterface, TConfig> Singleton
50+
{
51+
get
52+
{
53+
if (_singleton == null)
54+
{
55+
_singleton = new HashFactory<TAlgorithmInterface, TConfig>();
56+
}
57+
58+
return _singleton;
59+
}
60+
}
61+
62+
/// <summary>
63+
/// <inheritdoc/>
64+
/// </summary>
65+
/// <returns><inheritdoc/></returns>
66+
public TAlgorithmInterface CreateInstance()
67+
{
68+
return (TAlgorithmInterface)HashFactory.Create(typeof(TAlgorithmInterface));
69+
}
70+
71+
/// <summary>
72+
/// <inheritdoc/>
73+
/// </summary>
74+
/// <param name="config"><inheritdoc/></param>
75+
/// <returns><inheritdoc/></returns>
76+
public TAlgorithmInterface CreateInstance(TConfig config)
77+
{
78+
return (TAlgorithmInterface)HashFactory.Create(typeof(TAlgorithmInterface), config);
79+
}
80+
}
81+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// *
2+
// *****************************************************************************
3+
// *
4+
// * Copyright (c) 2025 Deskasoft International
5+
// *
6+
// * Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// * of this software and associated documentation files (the ""Software""), to deal
8+
// * in the Software without restriction, including without limitation the rights
9+
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// * copies of the Software, and to permit persons to whom the Software is
11+
// * furnished to do so, subject to the following conditions:
12+
// *
13+
// * The above copyright notice and this permission notice shall be included in all
14+
// * copies or substantial portions of the Software.
15+
// *
16+
// * THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
// * SOFTWARE.
23+
// *
24+
// *
25+
// * Please refer to LICENSE file.
26+
// *
27+
// ******************************************************************************
28+
// *
29+
30+
namespace HashifyNet
31+
{
32+
public sealed partial class HashFactory<TAlgorithmInterface>
33+
{
34+
/// <summary>
35+
/// <inheritdoc cref="HashFactory{TAlgorithmInterface}.CreateInstance()"/>
36+
/// </summary>
37+
/// <returns><inheritdoc cref="HashFactory{TAlgorithmInterface}.CreateInstance()"/></returns>
38+
public static TAlgorithmInterface Create()
39+
{
40+
return Singleton.CreateInstance();
41+
}
42+
43+
/// <summary>
44+
/// <inheritdoc cref="HashFactory{TAlgorithmInterface}.CreateInstance(IHashConfigBase)"/>
45+
/// </summary>
46+
/// <param name="config"><inheritdoc cref="HashFactory{TAlgorithmInterface}.CreateInstance(IHashConfigBase)"/></param>
47+
/// <returns><inheritdoc cref="HashFactory{TAlgorithmInterface}.CreateInstance(IHashConfigBase)"/></returns>
48+
public static TAlgorithmInterface Create(IHashConfigBase config)
49+
{
50+
return Singleton.CreateInstance(config);
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)