From 4767e9877d63ce7a081127dbd444618b3c123b34 Mon Sep 17 00:00:00 2001 From: Valeriy Mironov Date: Sat, 25 Nov 2017 23:02:33 +0200 Subject: [PATCH] Fixed packing negative numbers, allowed some images be optional --- .../ActivityElements/FormattedNumber.cs | 4 ++-- .../WeatherElements/TemperatureNumber.cs | 4 ++-- WatchFace.Parser/Models/Parameter.cs | 12 +++++++----- WatchFace.Parser/Utils/ImagesLoader.cs | 17 +++++++++++++---- WatchFace.Parser/Utils/ParametersConverter.cs | 14 ++++++++++++-- WatchFace.Parser/Writer.cs | 2 +- 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/WatchFace.Parser/Elements/ActivityElements/FormattedNumber.cs b/WatchFace.Parser/Elements/ActivityElements/FormattedNumber.cs index 6f7aecf..9207003 100644 --- a/WatchFace.Parser/Elements/ActivityElements/FormattedNumber.cs +++ b/WatchFace.Parser/Elements/ActivityElements/FormattedNumber.cs @@ -10,10 +10,10 @@ namespace WatchFace.Parser.Elements.ActivityElements [ParameterId(2)] [ParameterImageIndex] - public long SuffixImageIndex { get; set; } + public long? SuffixImageIndex { get; set; } [ParameterId(3)] [ParameterImageIndex] - public long DecimalPointImageIndex { get; set; } + public long? DecimalPointImageIndex { get; set; } } } \ No newline at end of file diff --git a/WatchFace.Parser/Elements/WeatherElements/TemperatureNumber.cs b/WatchFace.Parser/Elements/WeatherElements/TemperatureNumber.cs index b6d4dd7..b7262d8 100644 --- a/WatchFace.Parser/Elements/WeatherElements/TemperatureNumber.cs +++ b/WatchFace.Parser/Elements/WeatherElements/TemperatureNumber.cs @@ -10,10 +10,10 @@ namespace WatchFace.Parser.Elements.WeatherElements [ParameterId(2)] [ParameterImageIndex] - public long MinusImageIndex { get; set; } + public long? MinusImageIndex { get; set; } [ParameterId(3)] [ParameterImageIndex] - public long DegreesImageIndex { get; set; } + public long? DegreesImageIndex { get; set; } } } \ No newline at end of file diff --git a/WatchFace.Parser/Models/Parameter.cs b/WatchFace.Parser/Models/Parameter.cs index 1ba2153..de74250 100644 --- a/WatchFace.Parser/Models/Parameter.cs +++ b/WatchFace.Parser/Models/Parameter.cs @@ -38,8 +38,9 @@ namespace WatchFace.Parser.Models size += 1; if (HasChildren) { + Logger.Trace(() => TraceWithOffset($"{Id} ({rawId:X2}):", traceOffset)); size += WriteList(stream, traceOffset + 1); - Logger.Trace(() => TraceWithOffset($"{Id} ({rawId:X2}): {size} bytes", traceOffset)); + Logger.Trace(() => TraceWithOffset($"{size} bytes", traceOffset)); return size; } size += WriteValue(stream, Value, traceOffset); @@ -60,16 +61,17 @@ namespace WatchFace.Parser.Models public long WriteValue(Stream stream, long value, int traceOffset) { + var unsignedValue = (ulong) value; var size = 0; byte currentByte; - while (value >= 0x80) + while (unsignedValue >= 0x80) { - currentByte = (byte) ((value & 0x7f) | 0x80); + currentByte = (byte) ((unsignedValue & 0x7f) | 0x80); stream.WriteByte(currentByte); size += 1; - value = value >> 7; + unsignedValue = unsignedValue >> 7; } - currentByte = (byte) (value & 0x7f); + currentByte = (byte) (unsignedValue & 0x7f); stream.WriteByte(currentByte); size += 1; return size; diff --git a/WatchFace.Parser/Utils/ImagesLoader.cs b/WatchFace.Parser/Utils/ImagesLoader.cs index 6b2cea9..1fc93d8 100644 --- a/WatchFace.Parser/Utils/ImagesLoader.cs +++ b/WatchFace.Parser/Utils/ImagesLoader.cs @@ -54,12 +54,17 @@ namespace WatchFace.Parser.Utils $"Property {propertyInfo.Name} can't have both ParameterImageIndexAttribute and ParameterImagesCountAttribute" ); - if (propertyType == typeof(long) || (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>))) + if (propertyType == typeof(long) || propertyType.IsGenericType && + (propertyType.GetGenericTypeDefinition() == typeof(List<>) || + propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))) { if (imageIndexAttribute != null) { - lastImageIndexValue = propertyValue; - var mappedIndex = LoadImage(propertyValue); + if (propertyValue == null) continue; + long imageIndex = propertyValue; + + lastImageIndexValue = imageIndex; + var mappedIndex = LoadImage(imageIndex); propertyInfo.SetValue(serializable, mappedIndex); } else if (imagesCountAttribute != null) @@ -69,7 +74,11 @@ namespace WatchFace.Parser.Utils $"Property {propertyInfo.Name} can't be processed becuase ImageIndex isn't present or it is zero" ); - var imagesCount = propertyType.IsGenericType ? propertyValue.Count : propertyValue; + var imagesCount = propertyType.IsGenericType + ? (propertyType.GetGenericTypeDefinition() == typeof(Nullable<>) + ? propertyValue.Value + : propertyValue.Count) + : propertyValue; for (var i = lastImageIndexValue + 1; i < lastImageIndexValue + imagesCount; i++) LoadImage(i.Value); diff --git a/WatchFace.Parser/Utils/ParametersConverter.cs b/WatchFace.Parser/Utils/ParametersConverter.cs index 8402eda..1aa20ad 100644 --- a/WatchFace.Parser/Utils/ParametersConverter.cs +++ b/WatchFace.Parser/Utils/ParametersConverter.cs @@ -38,6 +38,11 @@ namespace WatchFace.Parser.Utils Logger.Trace("{0} '{1}': {2}", currentPath, propertyInfo.Name, propertyValue); result.Add(new Parameter(id, propertyValue)); } + else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + Logger.Trace("{0} '{1}': {2}", currentPath, propertyInfo.Name, propertyValue); + result.Add(new Parameter(id, propertyValue)); + } else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>)) { foreach (var item in propertyValue) @@ -72,11 +77,16 @@ namespace WatchFace.Parser.Utils var propertyInfo = properties[parameter.Id]; var propertyType = propertyInfo.PropertyType; - if (propertyType == typeof(long)) + if (propertyType == typeof(long) || propertyType.IsGenericType && + propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { Logger.Trace("{0} '{1}': {2}", currentPath, propertyInfo.Name, parameter.Value); dynamic propertyValue = propertyInfo.GetValue(result); - if (propertyValue != 0) + + if (propertyType.IsGenericType && propertyValue != null) + throw new ArgumentException($"Parameter {parameter.Id} is already set for {currentType.Name}"); + + if (!propertyType.IsGenericType && propertyValue != 0) throw new ArgumentException($"Parameter {parameter.Id} is already set for {currentType.Name}"); propertyInfo.SetValue(result, parameter.Value); diff --git a/WatchFace.Parser/Writer.cs b/WatchFace.Parser/Writer.cs index 00973f2..bf4df6b 100644 --- a/WatchFace.Parser/Writer.cs +++ b/WatchFace.Parser/Writer.cs @@ -61,7 +61,7 @@ namespace WatchFace.Parser var header = new Header { ParametersSize = (uint) encodedParametersPositions.Length, - Unknown = 0x37 // Value from Sydney (watchface with 0 doesn't work) + Unknown = 0x159 // Maybe some kind of layers (the bigger number needed for more complex watch faces) }; header.WriteTo(_stream);