Skip to content

Commit

Permalink
Merge pull request #1540 from neuecc/nrt
Browse files Browse the repository at this point in the history
Add more nullable ref annotations
  • Loading branch information
AArnott committed Dec 3, 2022
2 parents a43dbc8 + 79eda92 commit 95249b1
Show file tree
Hide file tree
Showing 16 changed files with 653 additions and 630 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#nullable disable

using System;
using System.Collections.Generic;
using System.Reflection;
Expand All @@ -12,12 +10,12 @@ namespace MessagePack.Formatters
{
// Note:This implementation is 'not' fastest, should more improve.
public sealed class EnumAsStringFormatter<T> : IMessagePackFormatter<T>
where T : struct, Enum
{
private readonly IReadOnlyDictionary<string, T> nameValueMapping;
private readonly IReadOnlyDictionary<T, string> valueNameMapping;
private readonly IReadOnlyDictionary<string, string> clrToSerializationName;
private readonly IReadOnlyDictionary<string, string> serializationToClrName;
private readonly bool enumMemberOverridesPresent;
private readonly IReadOnlyDictionary<string, string>? clrToSerializationName;
private readonly IReadOnlyDictionary<string, string>? serializationToClrName;
private readonly bool isFlags;

public EnumAsStringFormatter()
Expand All @@ -27,26 +25,25 @@ public EnumAsStringFormatter()
var fields = typeof(T).GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);
var nameValueMapping = new Dictionary<string, T>(fields.Length);
var valueNameMapping = new Dictionary<T, string>();
Dictionary<string, string> clrToSerializationName = null;
Dictionary<string, string> serializationToClrName = null;
Dictionary<string, string>? clrToSerializationName = null;
Dictionary<string, string>? serializationToClrName = null;

foreach (FieldInfo enumValueMember in fields)
{
string name = enumValueMember.Name;
T value = (T)enumValueMember.GetValue(null);
T value = (T)enumValueMember.GetValue(null)!;

// Consider the case where the serialized form of the enum value is overridden via an attribute.
var attribute = enumValueMember.GetCustomAttribute<EnumMemberAttribute>();
if (attribute?.IsValueSetExplicitly ?? false)
if (attribute is { IsValueSetExplicitly: true, Value: not null })
{
clrToSerializationName = clrToSerializationName ?? new Dictionary<string, string>();
serializationToClrName = serializationToClrName ?? new Dictionary<string, string>();
clrToSerializationName ??= new();
serializationToClrName ??= new();

clrToSerializationName.Add(name, attribute.Value);
serializationToClrName.Add(attribute.Value, name);

name = attribute.Value;
this.enumMemberOverridesPresent = true;
}

nameValueMapping[name] = value;
Expand All @@ -62,7 +59,7 @@ public EnumAsStringFormatter()
public void Serialize(ref MessagePackWriter writer, T value, MessagePackSerializerOptions options)
{
// Enum.ToString() is slow, so avoid it when we can.
if (!this.valueNameMapping.TryGetValue(value, out string valueString))
if (!this.valueNameMapping.TryGetValue(value, out string? valueString))
{
// fallback for flags, values with no name, etc
valueString = this.GetSerializedNames(value.ToString());
Expand All @@ -73,7 +70,11 @@ public void Serialize(ref MessagePackWriter writer, T value, MessagePackSerializ

public T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
string name = reader.ReadString();
string? name = reader.ReadString();
if (name is null)
{
MessagePackSerializationException.ThrowUnexpectedNilWhileDeserializing<T>();
}

// Avoid Enum.Parse when we can because it is too slow.
if (!this.nameValueMapping.TryGetValue(name, out T value))
Expand All @@ -86,7 +87,7 @@ public T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions

private string GetClrNames(string serializedNames)
{
if (this.enumMemberOverridesPresent && this.isFlags && serializedNames.IndexOf(", ", StringComparison.Ordinal) >= 0)
if (this.serializationToClrName is not null && this.isFlags && serializedNames.IndexOf(", ", StringComparison.Ordinal) >= 0)
{
return Translate(serializedNames, this.serializationToClrName);
}
Expand All @@ -97,7 +98,7 @@ private string GetClrNames(string serializedNames)

private string GetSerializedNames(string clrNames)
{
if (this.enumMemberOverridesPresent && this.isFlags && clrNames.IndexOf(", ", StringComparison.Ordinal) >= 0)
if (this.clrToSerializationName is not null && this.isFlags && clrNames.IndexOf(", ", StringComparison.Ordinal) >= 0)
{
return Translate(clrNames, this.clrToSerializationName);
}
Expand All @@ -118,7 +119,7 @@ private static string Translate(string items, IReadOnlyDictionary<string, string
elements[i] = elements[i].Substring(1);
}

if (mapping.TryGetValue(elements[i], out string substituteValue))
if (mapping.TryGetValue(elements[i], out string? substituteValue))
{
elements[i] = substituteValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,8 @@ public void Serialize(ref MessagePackWriter writer, object? value, MessagePackSe
{
// check IDictionary first
writer.WriteMapHeader(d.Count);
System.Collections.IDictionaryEnumerator enumerator = d.GetEnumerator();
while (enumerator.MoveNext())
foreach (System.Collections.DictionaryEntry item in d.GetEntryEnumerator())
{
System.Collections.DictionaryEntry item = enumerator.Entry;
this.Serialize(ref writer, item.Key, options);
this.Serialize(ref writer, item.Value, options);
}
Expand Down

0 comments on commit 95249b1

Please sign in to comment.