diff --git a/Configuration/SystemConfig.cs b/Configuration/SystemConfig.cs index cd289b4e..3a9aaed3 100644 --- a/Configuration/SystemConfig.cs +++ b/Configuration/SystemConfig.cs @@ -4,9 +4,7 @@ namespace TweetDuck.Configuration{ sealed class SystemConfig{ - private static readonly FileSerializer<SystemConfig> Serializer = new FileSerializer<SystemConfig>{ - HandleUnknownProperties = FileSerializer<SystemConfig>.IgnoreProperties("EnableBrowserGCReload", "BrowserMemoryThreshold") - }; + private static readonly FileSerializer<SystemConfig> Serializer = new FileSerializer<SystemConfig>(); public static readonly bool IsHardwareAccelerationSupported = File.Exists(Path.Combine(Program.ProgramPath, "libEGL.dll")) && File.Exists(Path.Combine(Program.ProgramPath, "libGLESv2.dll")); diff --git a/Configuration/UserConfig.cs b/Configuration/UserConfig.cs index 2b271c7e..0fcedcf9 100644 --- a/Configuration/UserConfig.cs +++ b/Configuration/UserConfig.cs @@ -11,9 +11,7 @@ namespace TweetDuck.Configuration{ sealed class UserConfig{ - private static readonly FileSerializer<UserConfig> Serializer = new FileSerializer<UserConfig>{ - HandleUnknownProperties = FileSerializer<UserConfig>.IgnoreProperties("AppLocale", "ShowDataCollectionNotification") - }; + private static readonly FileSerializer<UserConfig> Serializer = new FileSerializer<UserConfig>(); static UserConfig(){ Serializer.RegisterTypeConverter(typeof(WindowState), WindowState.Converter); diff --git a/Core/Other/Analytics/AnalyticsFile.cs b/Core/Other/Analytics/AnalyticsFile.cs index 7fca222b..46e8b495 100644 --- a/Core/Other/Analytics/AnalyticsFile.cs +++ b/Core/Other/Analytics/AnalyticsFile.cs @@ -3,9 +3,7 @@ namespace TweetDuck.Core.Other.Analytics{ sealed class AnalyticsFile{ - private static readonly FileSerializer<AnalyticsFile> Serializer = new FileSerializer<AnalyticsFile>{ - HandleUnknownProperties = FileSerializer<AnalyticsFile>.IgnoreProperties("CountGCReloads") - }; + private static readonly FileSerializer<AnalyticsFile> Serializer = new FileSerializer<AnalyticsFile>(); static AnalyticsFile(){ Serializer.RegisterTypeConverter(typeof(DateTime), new SingleTypeConverter<DateTime>{ diff --git a/Data/Serialization/FileSerializer.cs b/Data/Serialization/FileSerializer.cs index 92c689ce..70bf29d7 100644 --- a/Data/Serialization/FileSerializer.cs +++ b/Data/Serialization/FileSerializer.cs @@ -52,9 +52,6 @@ private static string UnescapeStream(StreamReader reader){ private static readonly ITypeConverter BasicSerializerObj = new BasicTypeConverter(); - public delegate void HandleUnknownPropertiesHandler(T obj, Dictionary<string, string> data); - public HandleUnknownPropertiesHandler HandleUnknownProperties { get; set; } - private readonly Dictionary<string, PropertyInfo> props; private readonly Dictionary<Type, ITypeConverter> converters; @@ -93,71 +90,60 @@ public void Write(string file, T obj){ } public void Read(string file, T obj){ - Dictionary<string, string> unknownProperties = new Dictionary<string, string>(4); + string contents; using(StreamReader reader = new StreamReader(new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))){ - switch(reader.Peek()){ - case -1: - throw new FormatException("File is empty."); - case 0: - case 1: - throw new FormatException("Input appears to be a binary file."); + contents = UnescapeStream(reader); + } + + if (string.IsNullOrWhiteSpace(contents)){ + throw new FormatException("File is empty."); + } + else if (contents[0] <= (char)1){ + throw new FormatException("Input appears to be a binary file."); + } + + int currentPos = 0; + + do{ + string line; + int nextPos = contents.IndexOf(NewLineReal, currentPos); + + if (nextPos == -1){ + line = contents.Substring(currentPos); + currentPos = -1; + + if (string.IsNullOrEmpty(line)){ + break; + } + } + else{ + line = contents.Substring(currentPos, nextPos-currentPos); + currentPos = nextPos+NewLineReal.Length; } - - string contents = UnescapeStream(reader); - int currentPos = 0; - - do{ - string line; - int nextPos = contents.IndexOf(NewLineReal, currentPos); - - if (nextPos == -1){ - line = contents.Substring(currentPos); - currentPos = -1; - - if (string.IsNullOrEmpty(line)){ - break; - } - } - else{ - line = contents.Substring(currentPos, nextPos-currentPos); - currentPos = nextPos+NewLineReal.Length; - } - int space = line.IndexOf(' '); + int space = line.IndexOf(' '); - if (space == -1){ - throw new SerializationException($"Invalid file format, missing separator: {line}"); + if (space == -1){ + throw new SerializationException($"Invalid file format, missing separator: {line}"); + } + + string property = line.Substring(0, space); + string value = UnescapeLine(line.Substring(space+1)); + + if (props.TryGetValue(property, out PropertyInfo info)){ + if (!converters.TryGetValue(info.PropertyType, out ITypeConverter serializer)){ + serializer = BasicSerializerObj; } - string property = line.Substring(0, space); - string value = UnescapeLine(line.Substring(space+1)); - - if (props.TryGetValue(property, out PropertyInfo info)){ - if (!converters.TryGetValue(info.PropertyType, out ITypeConverter serializer)){ - serializer = BasicSerializerObj; - } - - if (serializer.TryReadType(info.PropertyType, value, out object converted)){ - info.SetValue(obj, converted); - } - else{ - throw new SerializationException($"Invalid file format, cannot convert value: {value} (property: {property})"); - } + if (serializer.TryReadType(info.PropertyType, value, out object converted)){ + info.SetValue(obj, converted); } else{ - unknownProperties[property] = value; + throw new SerializationException($"Invalid file format, cannot convert value: {value} (property: {property})"); } - }while(currentPos != -1); - } - - if (unknownProperties.Count > 0){ - HandleUnknownProperties?.Invoke(obj, unknownProperties); - - if (unknownProperties.Count > 0){ - throw new SerializationException($"Invalid file format, unknown properties: {string.Join(", ", unknownProperties.Keys)}"); } - } + }while(currentPos != -1); } public void ReadIfExists(string file, T obj){ @@ -167,14 +153,6 @@ public void ReadIfExists(string file, T obj){ }catch(DirectoryNotFoundException){} } - public static HandleUnknownPropertiesHandler IgnoreProperties(params string[] properties){ - return (obj, data) => { - foreach(string property in properties){ - data.Remove(property); - } - }; - } - private sealed class BasicTypeConverter : ITypeConverter{ bool ITypeConverter.TryWriteType(Type type, object value, out string converted){ switch(Type.GetTypeCode(type)){