Skip to content

Commit 799b10b

Browse files
committed
Move enum and field info lookup to separate class.
1 parent 16a94a7 commit 799b10b

File tree

2 files changed

+54
-50
lines changed

2 files changed

+54
-50
lines changed

PhpSerializerNET/PhpDeserializer.cs

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ internal class PhpDeserializer {
1616
private readonly PhpDeserializationOptions _options;
1717
private readonly PhpSerializeToken _token;
1818

19-
private static Dictionary<Type, Dictionary<string, FieldInfo>> FieldInfoCache { get; set; } = new();
20-
private static readonly object FieldInfoCacheCacheSyncObject = new();
2119

22-
private static Dictionary<Type, Dictionary<string, FieldInfo>> EnumInfoCache { get; set; } = new();
23-
private static readonly object EnumInfoCacheSyncObject = new();
2420

2521
public PhpDeserializer(string input, PhpDeserializationOptions options) {
2622
_options = options;
@@ -56,10 +52,6 @@ public static void ClearTypeCache() {
5652
/// </summary>
5753
public static void ClearPropertyInfoCache() {
5854
TypeLookup.ClearPropertyInfoCache();
59-
60-
lock (EnumInfoCacheSyncObject) {
61-
EnumInfoCache.Clear();
62-
}
6355
}
6456

6557
private object DeserializeToken(PhpSerializeToken token) {
@@ -233,7 +225,6 @@ private object DeserializeTokenFromSimpleType(Type givenType, PhpSerializeToken
233225

234226
if (targetType.IsEnum) {
235227
// Enums are converted by name if the token is a string and by underlying value if they are not
236-
237228
if (token.Value == "" && this._options.EmptyStringToDefault) {
238229
return Activator.CreateInstance(targetType);
239230
}
@@ -242,31 +233,7 @@ private object DeserializeTokenFromSimpleType(Type givenType, PhpSerializeToken
242233
return Enum.Parse(targetType, token.Value);
243234
}
244235

245-
246-
FieldInfo foundFieldInfo = null;
247-
if (this._options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo)) {
248-
lock (EnumInfoCacheSyncObject) {
249-
if (!EnumInfoCache.ContainsKey(targetType)) {
250-
EnumInfoCache.Add(targetType, new());
251-
}
252-
if (EnumInfoCache[targetType].ContainsKey(token.Value)) {
253-
foundFieldInfo = EnumInfoCache[targetType][token.Value];
254-
}
255-
}
256-
}
257-
258-
if (foundFieldInfo == null) {
259-
foundFieldInfo = targetType
260-
.GetFields()
261-
.Select(fieldInfo => new { fieldInfo, phpPropertyAttribute = fieldInfo.GetCustomAttribute<PhpPropertyAttribute>() })
262-
.FirstOrDefault(c => c.fieldInfo.Name == token.Value || c.phpPropertyAttribute != null && c.phpPropertyAttribute.Name == token.Value)
263-
?.fieldInfo;
264-
if (this._options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo)) {
265-
lock (EnumInfoCacheSyncObject) {
266-
EnumInfoCache[targetType].Add(token.Value, foundFieldInfo);
267-
}
268-
}
269-
}
236+
FieldInfo foundFieldInfo = TypeLookup.GetEnumInfo(targetType, token.Value, this._options);
270237

271238
if (foundFieldInfo == null) {
272239
throw new DeserializationException(
@@ -315,17 +282,7 @@ private object DeserializeTokenFromSimpleType(Type givenType, PhpSerializeToken
315282

316283
private object MakeStruct(Type targetType, PhpSerializeToken token) {
317284
var result = Activator.CreateInstance(targetType);
318-
Dictionary<string, FieldInfo> fields;
319-
lock (FieldInfoCacheCacheSyncObject) {
320-
if (FieldInfoCache.ContainsKey(targetType)) {
321-
fields = FieldInfoCache[targetType];
322-
} else {
323-
fields = targetType.GetFields().GetAllFields(this._options);
324-
if (this._options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo)) {
325-
FieldInfoCache.Add(targetType, fields);
326-
}
327-
}
328-
}
285+
Dictionary<string, FieldInfo> fields = TypeLookup.GetFieldInfos(targetType, this._options);
329286

330287
for (int i = 0; i < token.Children.Length; i += 2) {
331288
var fieldName = this._options.CaseSensitiveProperties ? token.Children[i].Value : token.Children[i].Value.ToLower();
@@ -401,7 +358,7 @@ private object MakeObject(Type targetType, PhpSerializeToken token) {
401358

402359
private object MakeArray(Type targetType, PhpSerializeToken token) {
403360
var elementType = targetType.GetElementType() ?? throw new InvalidOperationException("targetType.GetElementType() returned null");
404-
Array result = System.Array.CreateInstance(elementType, token.Children.Length / 2);
361+
Array result = Array.CreateInstance(elementType, token.Children.Length / 2);
405362

406363
var arrayIndex = 0;
407364
for (int i = 1; i < token.Children.Length; i += 2) {

PhpSerializerNET/TypeLookup.cs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public static class TypeLookup {
2020
};
2121

2222
private static readonly Dictionary<Type, Dictionary<object, PropertyInfo>> PropertyInfoCache = new();
23+
private static Dictionary<Type, Dictionary<string, FieldInfo>> FieldInfoCache { get; set; } = new();
24+
private static Dictionary<Type, Dictionary<string, FieldInfo>> EnumInfoCache { get; set; } = new();
2325

2426

2527
/// <summary>
@@ -41,10 +43,9 @@ public static void ClearPropertyInfoCache() {
4143
lock (PropertyInfoCache) {
4244
PropertyInfoCache.Clear();
4345
}
44-
45-
// lock (EnumInfoCacheSyncObject) {
46-
// EnumInfoCache.Clear();
47-
// }
46+
lock (EnumInfoCache) {
47+
EnumInfoCache.Clear();
48+
}
4849
}
4950

5051
public static Type FindTypeInAssymbly(string typeName, bool cacheEnabled) {
@@ -96,5 +97,51 @@ public static Dictionary<object, PropertyInfo> GetPropertyInfos(Type type, PhpDe
9697
}
9798
return properties;
9899
}
100+
101+
public static Dictionary<string, FieldInfo> GetFieldInfos(Type targetType, PhpDeserializationOptions options) {
102+
bool cacheEnabled = options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo);
103+
if (cacheEnabled) {
104+
lock (FieldInfoCache) {
105+
if (FieldInfoCache.ContainsKey(targetType)) {
106+
return FieldInfoCache[targetType];
107+
}
108+
}
109+
}
110+
111+
Dictionary<string, FieldInfo> fields = targetType.GetFields().GetAllFields(options);
112+
if (cacheEnabled) {
113+
lock (FieldInfoCache) {
114+
FieldInfoCache.Add(targetType, fields);
115+
}
116+
}
117+
return fields;
118+
}
119+
120+
public static FieldInfo GetEnumInfo(Type targetType, string value, PhpDeserializationOptions options) {
121+
bool cacheEnabled = options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo);
122+
if (cacheEnabled) {
123+
lock (EnumInfoCache) {
124+
if (!EnumInfoCache.ContainsKey(targetType)) {
125+
EnumInfoCache.Add(targetType, new());
126+
}
127+
if (EnumInfoCache[targetType].ContainsKey(value)) {
128+
return EnumInfoCache[targetType][value];
129+
}
130+
}
131+
}
132+
133+
FieldInfo foundFieldInfo = targetType
134+
.GetFields()
135+
.Select(fieldInfo => new { fieldInfo, phpPropertyAttribute = fieldInfo.GetCustomAttribute<PhpPropertyAttribute>() })
136+
.FirstOrDefault(c => c.fieldInfo.Name == value || c.phpPropertyAttribute != null && c.phpPropertyAttribute.Name == value)
137+
?.fieldInfo;
138+
if (cacheEnabled) {
139+
lock (EnumInfoCache) {
140+
EnumInfoCache[targetType].Add(value, foundFieldInfo);
141+
}
142+
}
143+
return foundFieldInfo;
144+
}
99145
}
100146
}
147+

0 commit comments

Comments
 (0)