Skip to content

Commit d43451e

Browse files
authored
General improvements, and the UnitTests add-on (#5)
***NO_CI***
1 parent aeb83ba commit d43451e

File tree

15 files changed

+603
-207
lines changed

15 files changed

+603
-207
lines changed

Shared/MessagePack/ConverterContext.cs

Lines changed: 78 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@ namespace nanoFramework.MessagePack
2222
/// </summary>
2323
public static class ConverterContext
2424
{
25-
private static readonly Type[] _emptyTypes = new Type[0];
25+
private static readonly Type[] s_emptyTypes = new Type[0];
2626
private static readonly NullConverter s_nullConverter = new();
2727
private static readonly MapConverter s_mapConverter = new();
2828
private static readonly ArrayConverter s_arrayConverter = new();
2929

3030
#if NANOFRAMEWORK_1_0
31-
private static readonly Hashtable _mappingDictionary = new();
31+
private static readonly Hashtable s_mappingDictionary = new();
3232
#else
33-
private static readonly ConcurrentDictionary<Type, MemberMapping[]> _mappingDictionary = new();
33+
private static readonly ConcurrentDictionary<Type, MemberMapping[]> s_mappingDictionary = new();
3434
#endif
3535

36-
private static readonly Hashtable ConversionTable = new()
36+
private static readonly Hashtable s_conversionTable = new()
3737
{
3838
{ typeof(IDictionary).FullName!, s_mapConverter },
3939
{ typeof(Hashtable).FullName!, s_mapConverter },
40-
{ typeof(ArrayList).FullName!, new ArrayListConverter()},
40+
{ typeof(ArrayList).FullName!, new ArrayListConverter() },
4141
{ typeof(short).FullName!, new ShortConverter() },
4242
{ typeof(ushort).FullName!, new UshortConverter() },
4343
{ typeof(int).FullName!, new IntConverter() },
@@ -46,7 +46,7 @@ public static class ConverterContext
4646
{ typeof(ulong).FullName!, new UlongConverter() },
4747
{ typeof(byte).FullName!, new ByteConverter() },
4848
{ typeof(sbyte).FullName!, new SbyteConverter() },
49-
{ typeof(float).FullName!, new FloatConverter()},
49+
{ typeof(float).FullName!, new FloatConverter() },
5050
{ typeof(double).FullName!, new DoubleConverter() },
5151
{ typeof(bool).FullName!, new BoolConverter() },
5252
{ typeof(string).FullName!, new StringConverter() },
@@ -55,10 +55,10 @@ public static class ConverterContext
5555
{ typeof(char).FullName!, new CharConverter() },
5656
{ typeof(Guid).FullName!, new GuidConverter() },
5757
{ typeof(byte[]).FullName!, new BinaryConverter() },
58-
{ typeof(int[]).FullName!, new SimpleArrayConverter(typeof(int))},
59-
{ typeof(uint[]).FullName!, new SimpleArrayConverter(typeof(uint))},
60-
{ typeof(long[]).FullName!, new SimpleArrayConverter(typeof(long))},
61-
{ typeof(ulong[]).FullName!, new SimpleArrayConverter(typeof(ulong))},
58+
{ typeof(int[]).FullName!, new SimpleArrayConverter(typeof(int)) },
59+
{ typeof(uint[]).FullName!, new SimpleArrayConverter(typeof(uint)) },
60+
{ typeof(long[]).FullName!, new SimpleArrayConverter(typeof(long)) },
61+
{ typeof(ulong[]).FullName!, new SimpleArrayConverter(typeof(ulong)) },
6262
{ typeof(float[]).FullName!, new SimpleArrayConverter(typeof(float)) },
6363
{ typeof(double[]).FullName!, new SimpleArrayConverter(typeof(double)) },
6464
{ typeof(char[]).FullName!, new SimpleArrayConverter(typeof(char)) },
@@ -73,24 +73,25 @@ public static class ConverterContext
7373
};
7474

7575
/// <summary>
76-
/// Null value converter
76+
/// Null value converter.
7777
/// </summary>
7878
public static IConverter NullConverter => s_nullConverter;
7979

8080
/// <summary>
8181
/// Adds new converter to collection to support more types.
8282
/// </summary>
8383
/// <param name="type">Type of object.</param>
84-
/// <param name="converter">Converter instance which will be used to convert <paramref name="type"/></param>
84+
/// <param name="converter">Converter instance which will be used to convert <paramref name="type"/>.</param>
85+
/// <exception cref="NotSupportedException">Converter by type <see cref="object"/> not support in convertors table.</exception>
8586
[MethodImpl(MethodImplOptions.Synchronized)]
8687
public static void Add(Type type, IConverter converter)
8788
{
8889
if (type == typeof(object))
8990
{
90-
throw new NotSupportedException($"Converter by type {type.Name} not support in convertors table.");
91+
throw new NotSupportedException();
9192
}
9293

93-
ConversionTable.Add(type.FullName!, converter);
94+
s_conversionTable.Add(type.FullName!, converter);
9495
}
9596

9697
/// <summary>
@@ -99,14 +100,14 @@ public static void Add(Type type, IConverter converter)
99100
/// <param name="type">Type of object.</param>
100101
public static void Remove(Type type)
101102
{
102-
ConversionTable.Remove(type.FullName!);
103+
s_conversionTable.Remove(type.FullName!);
103104
}
104105

105106
/// <summary>
106107
/// Remove and then adds converter for given type.
107108
/// </summary>
108109
/// <param name="type">Type of object.</param>
109-
/// <param name="converter">Converter instance which will be used to convert <paramref name="type"/></param>
110+
/// <param name="converter">Converter instance which will be used to convert <paramref name="type"/>.</param>
110111
[MethodImpl(MethodImplOptions.Synchronized)]
111112
public static void Replace(Type type, IConverter converter)
112113
{
@@ -115,20 +116,21 @@ public static void Replace(Type type, IConverter converter)
115116
}
116117

117118
/// <summary>
118-
/// Return converter by type
119+
/// Return converter by type.
119120
/// </summary>
120-
/// <param name="type">Type from converter</param>
121-
/// <returns>Converter interface <see cref="IConverter"/></returns>
121+
/// <param name="type">Type object from converter.</param>
122+
/// <returns>Converter interface <see cref="IConverter"/> or null.</returns>
123+
/// <exception cref="ConverterNotFoundException">If object type is <see cref="object"/>.</exception>
122124
public static IConverter GetConverter(Type type)
123125
{
124126
if (type == typeof(object))
125127
{
126128
throw ExceptionUtility.ConverterNotFound(type);
127129
}
128130

129-
if (ConversionTable.Contains(type.FullName!))
131+
if (s_conversionTable.Contains(type.FullName!))
130132
{
131-
return (IConverter)ConversionTable[type.FullName!]!;
133+
return (IConverter)s_conversionTable[type.FullName!]!;
132134
}
133135

134136
return null!;
@@ -142,10 +144,17 @@ internal static Hashtable GetMappingsValues(Type targetType, object value)
142144

143145
foreach (var memberMapping in memberMappings)
144146
{
147+
#if NANOFRAMEWORK_1_0
148+
if(!memberMapping.OriginalName!.StartsWith(MemberMapping.SET_))
149+
{
150+
#endif
145151
if (memberMapping.TryGetValue(value, out var memberValue) && memberValue != null)
146152
{
147153
result.Add(memberMapping.Name!, memberValue);
148154
}
155+
#if NANOFRAMEWORK_1_0
156+
}
157+
#endif
149158
}
150159
return result;
151160
}
@@ -156,44 +165,55 @@ internal static void SetMappingsValues(Type targetType, object targetObject, Has
156165

157166
foreach (var memberMapping in memberMappings)
158167
{
168+
#if NANOFRAMEWORK_1_0
169+
if(!memberMapping.OriginalName!.StartsWith(MemberMapping.GET_))
170+
{
171+
#endif
159172
if (objectValuesMap.Contains(memberMapping.Name!))
160173
{
161174
var memberMpToken = (ArraySegment)objectValuesMap[memberMapping.Name!]!;
162-
var memberValueMapType = memberMapping.GetMemberType();
163-
var converter = GetConverter(memberValueMapType!);
164-
if (converter != null)
165-
{
166-
memberMapping.SetValue(targetObject, converter.Read(new ByteArrayReader((byte[])memberMpToken))!);
167-
}
168-
else
175+
if (memberMpToken != null)
169176
{
170-
if (memberValueMapType!.IsArray)
177+
var memberValueMapType = memberMapping.GetMemberType();
178+
var converter = GetConverter(memberValueMapType!);
179+
if (converter != null)
171180
{
172-
memberMapping.SetValue(targetObject, ArrayConverter.Read(new ByteArrayReader((byte[])memberMpToken), memberValueMapType)!);
181+
memberMapping.SetValue(targetObject, converter.Read(memberMpToken)!);
173182
}
174183
else
175184
{
176-
memberMapping.SetValue(targetObject, DeserializeObject(memberValueMapType!, new ByteArrayReader((byte[])memberMpToken))!);
185+
if (memberValueMapType!.IsArray)
186+
{
187+
memberMapping.SetValue(targetObject, ArrayConverter.Read(memberMpToken, memberValueMapType)!);
188+
}
189+
else
190+
{
191+
192+
memberMapping.SetValue(targetObject, DeserializeObject(memberValueMapType!, memberMpToken)!);
193+
}
177194
}
178195
}
179196
}
197+
#if NANOFRAMEWORK_1_0
198+
}
199+
#endif
180200
}
181201
}
182202

183203
internal static object CreateInstance(Type targetType)
184204
{
185-
var constructor = targetType.GetConstructor(_emptyTypes) ?? throw new Exception($"Target type {targetType?.FullName} does not have a parameterless constructor");
205+
var constructor = targetType.GetConstructor(s_emptyTypes) ?? throw new Exception($"Target type {targetType?.FullName} does not have a parameterless constructor");
186206
return constructor.Invoke(null);
187207
}
188208

189209
internal static MemberMapping[] GetMemberMapping(Type targetType)
190210
{
191211
#if NANOFRAMEWORK_1_0
192-
var cached = _mappingDictionary[targetType];
212+
var cached = s_mappingDictionary[targetType];
193213
if (cached is not MemberMapping[] memberMappings)
194214
{
195215
#else
196-
if (!_mappingDictionary.TryGetValue(targetType, out var memberMappings))
216+
if (!s_mappingDictionary.TryGetValue(targetType, out var memberMappings))
197217
{
198218
#endif
199219
var mappings = new ArrayList();
@@ -204,9 +224,9 @@ internal static MemberMapping[] GetMemberMapping(Type targetType)
204224
memberMappings = (MemberMapping[])mappings.ToArray(typeof(MemberMapping));
205225

206226
#if NANOFRAMEWORK_1_0
207-
ThreadSafeAddItemCache(_mappingDictionary, targetType, memberMappings);
227+
ThreadSafeAddItemCache(s_mappingDictionary, targetType, memberMappings);
208228
#else
209-
_mappingDictionary.TryAdd(targetType, memberMappings);
229+
s_mappingDictionary.TryAdd(targetType, memberMappings);
210230
#endif
211231
}
212232

@@ -234,6 +254,16 @@ internal static void SerializeObject(Type type, object value, IMessagePackWriter
234254
#nullable enable
235255
internal static object? DeserializeObject(Type type, IMessagePackReader reader)
236256
{
257+
if (type.Name == typeof(IDictionary).Name || type.Name == typeof(Hashtable).Name)
258+
{
259+
return MapConverter.Read(reader);
260+
}
261+
262+
if (type.IsArray)
263+
{
264+
return ArrayConverter.Read(reader, type);
265+
}
266+
237267
var objectMap = reader.GetMassagePackObjectTokens();
238268
if (objectMap != null && objectMap is Hashtable targetObjectMap)
239269
{
@@ -284,18 +314,23 @@ internal static void SerializeObject(Type type, object value, IMessagePackWriter
284314
}
285315

286316
#if NANOFRAMEWORK_1_0
287-
[MethodImpl(MethodImplOptions.Synchronized)]
288317
private static void ThreadSafeAddItemCache(Hashtable hashtable, object key, object value)
289318
{
290319
if (!hashtable.Contains(key))
291320
{
292-
try
293-
{
294-
hashtable.Add(key, value);
295-
}
296-
catch (Exception ex)
321+
lock(s_mappingDictionary)
297322
{
298-
Debug.WriteLine($"Error added key: '{key}', value: '{value}'\r\n{ex}");
323+
try
324+
{
325+
if (!hashtable.Contains(key))
326+
{
327+
hashtable.Add(key, value);
328+
}
329+
}
330+
catch (Exception ex)
331+
{
332+
Debug.WriteLine($"Error added key: '{key}', value: '{value}'\r\n{ex}");
333+
}
299334
}
300335
}
301336
}

Shared/MessagePack/Converters/IConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace nanoFramework.MessagePack.Converters
88
{
99
/// <summary>
10-
/// <see cref="Converter"/> interface.
10+
/// <see cref="IConverter"/> interface.
1111
/// </summary>
1212
public interface IConverter
1313
{

Shared/MessagePack/Converters/MapConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ private static void Write(IDictionary value, IMessagePackWriter writer)
5353
}
5454

5555
#nullable enable
56-
private static Hashtable? Read(IMessagePackReader reader)
56+
internal static Hashtable? Read(IMessagePackReader reader)
5757
{
5858
var length = reader.ReadMapLength();
5959
return ((long)length) > -1 ? ReadMap(reader, length) : null;

Shared/MessagePack/Converters/StringConverter.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Diagnostics.CodeAnalysis;
55
using System.Text;
6+
using nanoFramework.MessagePack.Dto;
67
using nanoFramework.MessagePack.Extensions;
78
using nanoFramework.MessagePack.Stream;
89
using nanoFramework.MessagePack.Utility;
@@ -28,27 +29,24 @@ private static void Write(string value, IMessagePackWriter writer)
2829
writer.Write(data);
2930
}
3031
}
31-
32-
private static string Read(IMessagePackReader reader)
32+
#nullable enable
33+
private static string? Read(IMessagePackReader reader)
3334
{
34-
var type = reader.ReadDataType();
35+
DataTypes type = reader.ReadDataType();
3536

3637
switch (type)
3738
{
3839
case DataTypes.Null:
39-
return null!;
40-
40+
return null;
4141
case DataTypes.Str8:
4242
return ReadString(reader, NumberConverterHelper.ReadUInt8(reader));
43-
4443
case DataTypes.Str16:
4544
return ReadString(reader, NumberConverterHelper.ReadUInt16(reader));
46-
4745
case DataTypes.Str32:
4846
return ReadString(reader, NumberConverterHelper.ReadUInt32(reader));
4947
}
5048

51-
if (TryGetFixStrLength(type, out var length))
49+
if (TryGetFixStrLength(type, out uint length))
5250
{
5351
return ReadString(reader, length);
5452
}
@@ -58,9 +56,9 @@ private static string Read(IMessagePackReader reader)
5856

5957
internal static string ReadString(IMessagePackReader reader, uint length)
6058
{
61-
var buffer = (byte[])reader.ReadBytes(length);
59+
ArraySegment arraySegment = reader.ReadBytes(length);
6260

63-
return Utf8.GetString(buffer, 0, buffer.Length);
61+
return Utf8.GetString(arraySegment.SourceBuffer, (int)arraySegment.SourceOffset + arraySegment.Position, (int)arraySegment.Length);
6462
}
6563

6664
private static bool TryGetFixStrLength(DataTypes type, out uint length)

0 commit comments

Comments
 (0)