Added tracing, fixed loading all available watch faces

fonts_experiment
Valeriy Mironov 2017-11-22 01:51:49 +02:00
parent de156812e8
commit 4dc2d05f1a
40 changed files with 510 additions and 200 deletions

View File

@ -1,14 +1,18 @@
using System;
using System.IO;
using Newtonsoft.Json;
using NLog;
using NLog.Config;
using NLog.Targets;
using SixLabors.ImageSharp;
using WatchFace;
using WatchFace.Models;
namespace Cmd
{
internal class Program
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private static int Main(string[] args)
{
var inputFileName = args[0];
@ -18,33 +22,29 @@ namespace Cmd
return 1;
}
var useTrace = args.Length > 1 && args[1] == "--debug";
SetupLogger(useTrace);
Reader reader;
Console.WriteLine("Opening watch face '{0}'", inputFileName);
Logger.Debug("Opening watch face '{0}'", inputFileName);
using (var fileStream = File.OpenRead(inputFileName))
{
reader = new Reader(fileStream);
Console.WriteLine("Reading watch face parameters...");
Logger.Debug("Reading watch face parameters...");
reader.Parse();
}
//foreach (var resource in reader.Resources)
//{
// Console.WriteLine("{0:D}: ", resource.Id);
// foreach (var descriptor in resource.Children) WriteParameter(4, descriptor);
//}
Console.WriteLine("Parsing parameters...");
Logger.Debug("Parsing parameters...");
var watchFace = WatchFace.WatchFace.Parse(reader.Resources);
var path = Path.GetDirectoryName(inputFileName);
var name = Path.GetFileNameWithoutExtension(inputFileName);
var unpackedPath = Path.Combine(path, $"{name}_unpacked");
if (!Directory.Exists(unpackedPath)) Directory.CreateDirectory(unpackedPath);
Console.WriteLine("Unpacking watch face to '{0}'", unpackedPath);
Logger.Debug("Unpacking watch face to '{0}'", unpackedPath);
var configFileName = Path.Combine(unpackedPath, "config.json");
Console.WriteLine("Eporting config...");
Logger.Debug("Eporting config...");
using (var fileStream = File.OpenWrite(configFileName))
using (var writer = new StreamWriter(fileStream))
{
@ -53,7 +53,7 @@ namespace Cmd
writer.Flush();
}
Console.WriteLine("Eporting images...");
Logger.Debug("Eporting images...");
var index = 0;
foreach (var image in reader.Images)
{
@ -61,31 +61,25 @@ namespace Cmd
index++;
}
Console.WriteLine("Everything done!");
Logger.Debug("Everything done!");
Console.ReadKey();
return 0;
}
private static void SetupLogger(bool useTrace)
{
var config = new LoggingConfiguration();
var consoleTarget = new ColoredConsoleTarget();
config.AddTarget("console", consoleTarget);
var rule1 = new LoggingRule("*", useTrace ? LogLevel.Trace : LogLevel.Debug, consoleTarget);
config.LoggingRules.Add(rule1);
LogManager.Configuration = config;
}
private static void Usage()
{
Console.WriteLine("Usage: wf.exe [watchface bin]");
Console.WriteLine();
}
private static void WriteParameter(int offset, Parameter parameter)
{
for (var i = 0; i < offset; i++)
Console.Write(' ');
Console.Write("{0:D}: ", parameter.Id);
if (parameter.IsComplex)
{
Console.WriteLine();
foreach (var parameter1 in parameter.Children) WriteParameter(offset + 4, parameter1);
}
else
{
Console.WriteLine("{0:D} (0x{0:x})", parameter.Value);
}
}
}
}

View File

@ -11,6 +11,8 @@
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -39,6 +41,9 @@
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.4.12\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="SixLabors.Core, Version=0.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.Core.1.0.0-beta0004\lib\netstandard1.1\SixLabors.Core.dll</HintPath>
</Reference>
@ -59,8 +64,8 @@
<Private>True</Private>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.2.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.4.1\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.Globalization.Calendars">
<HintPath>..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll</HintPath>
@ -118,7 +123,7 @@
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
@ -146,4 +151,11 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\NETStandard.Library.2.0.1\build\netstandard2.0\NETStandard.Library.targets" Condition="Exists('..\packages\NETStandard.Library.2.0.1\build\netstandard2.0\NETStandard.Library.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\NETStandard.Library.2.0.1\build\netstandard2.0\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NETStandard.Library.2.0.1\build\netstandard2.0\NETStandard.Library.targets'))" />
</Target>
</Project>

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.NETCore.Platforms" version="2.0.1" targetFramework="net461" />
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />
<package id="NETStandard.Library" version="2.0.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
<package id="NLog" version="4.4.12" targetFramework="net461" />
<package id="SixLabors.Core" version="1.0.0-beta0004" targetFramework="net461" />
<package id="SixLabors.ImageSharp" version="1.0.0-beta0002" targetFramework="net461" />
<package id="System.AppContext" version="4.3.0" targetFramework="net461" />
@ -12,7 +13,7 @@
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net461" />
<package id="System.Console" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.DiagnosticSource" version="4.4.1" targetFramework="net461" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net461" />
<package id="System.Globalization" version="4.3.0" targetFramework="net461" />
@ -44,7 +45,7 @@
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net461" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net461" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net461" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net461" />

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.ActivityElements;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -8,39 +9,44 @@ namespace WatchFace.Elements
{
public class Activity
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Calories { get; set; }
public Number Pulse { get; set; }
public Number Steps { get; set; }
public Number StepsGoal { get; set; }
public FormattedNumber Distance { get; set; }
public static Activity Parse(List<Parameter> descriptor)
public static Activity Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Activity();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Steps = Number.Parse(parameter.Children);
result.Steps = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.StepsGoal = Number.Parse(parameter.Children);
result.StepsGoal = Number.Parse(parameter.Children, currentPath);
break;
case 3:
result.Calories = Number.Parse(parameter.Children);
result.Calories = Number.Parse(parameter.Children, currentPath);
break;
case 4:
result.Pulse = Number.Parse(parameter.Children);
result.Pulse = Number.Parse(parameter.Children, currentPath);
break;
case 5:
result.Distance = FormattedNumber.Parse(parameter.Children);
result.Distance = FormattedNumber.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,21 +8,26 @@ namespace WatchFace.Elements.ActivityElements
{
public class FormattedNumber
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Number { get; set; }
public long SuffixImageIndex { get; set; }
public long DecimalPointImageIndex { get; set; }
public static FormattedNumber Parse(List<Parameter> descriptor)
public static FormattedNumber Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new FormattedNumber();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children);
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.SuffixImageIndex = parameter.Value;
@ -30,8 +36,9 @@ namespace WatchFace.Elements.ActivityElements
result.DecimalPointImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,31 +8,36 @@ namespace WatchFace.Elements
{
public class AnalogDialFace
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public ClockHand Hours { get; set; }
public ClockHand Minutes { get; set; }
public ClockHand Seconds { get; set; }
public static AnalogDialFace Parse(List<Parameter> descriptor)
public static AnalogDialFace Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new AnalogDialFace();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Hours = ClockHand.Parse(parameter.Children);
result.Hours = ClockHand.Parse(parameter.Children, currentPath);
break;
case 2:
result.Minutes = ClockHand.Parse(parameter.Children);
result.Minutes = ClockHand.Parse(parameter.Children, currentPath);
break;
case 3:
result.Seconds = ClockHand.Parse(parameter.Children);
result.Seconds = ClockHand.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -6,20 +7,25 @@ namespace WatchFace.Elements
{
public class Background
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Image Image { get; set; }
public static Background Parse(List<Parameter> parameters)
public static Background Parse(List<Parameter> parameters, string path)
{
Logger.Trace("Reading {0}", path);
var result = new Background();
foreach (var parameter in parameters)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Image = Image.Parse(parameter.Children);
result.Image = Image.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NLog;
using WatchFace.JsonConverters;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class CircleScale
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long CenterX { get; set; }
public long CenterY { get; set; }
public long RadiusX { get; set; }
public long RadiusY { get; set; }
public long StartAngle { get; set; }
public long EndAngle { get; set; }
public long Width { get; set; }
[JsonConverter(typeof(HexStringJsonConverter))]
public long Color { get; set; }
public static CircleScale Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new CircleScale();
foreach (var parameter in descriptor)
switch (parameter.Id)
{
case 1:
result.CenterX = parameter.Value;
break;
case 2:
result.CenterY = parameter.Value;
break;
case 3:
result.RadiusX = parameter.Value;
break;
case 4:
result.RadiusY = parameter.Value;
break;
case 5:
result.StartAngle = parameter.Value;
break;
case 6:
result.EndAngle = parameter.Value;
break;
case 7:
result.Width = parameter.Value;
break;
case 8:
result.Color = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter, path);
}
return result;
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using NLog;
using WatchFace.JsonConverters;
using WatchFace.Models;
@ -8,7 +9,8 @@ namespace WatchFace.Elements.BasicElements
{
public class ClockHand
{
public long Unknown { get; set; }
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long Unknown1 { get; set; }
[JsonConverter(typeof(HexStringJsonConverter))]
public long Color { get; set; }
@ -17,33 +19,38 @@ namespace WatchFace.Elements.BasicElements
public List<Coordinates> Shape { get; set; }
public Image CenterImage { get; set; }
public static ClockHand Parse(List<Parameter> descriptor)
public static ClockHand Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new ClockHand {Shape = new List<Coordinates>()};
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Unknown = parameter.Value;
result.Unknown1 = parameter.Value;
break;
case 2:
result.Color = parameter.Value;
break;
case 3:
result.Center = Coordinates.Parse(parameter.Children);
result.Center = Coordinates.Parse(parameter.Children, currentPath);
break;
case 4:
result.Shape.Add(Coordinates.Parse(parameter.Children));
result.Shape.Add(Coordinates.Parse(parameter.Children, currentPath));
break;
case 5:
result.CenterImage = Image.Parse(parameter.Children);
result.CenterImage = Image.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,16 +1,19 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class Coordinates
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long X { get; set; }
public long Y { get; set; }
public static Coordinates Parse(List<Parameter> descriptor)
public static Coordinates Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
@ -25,7 +28,7 @@ namespace WatchFace.Elements.BasicElements
result.Y = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
return result;
}

View File

@ -1,17 +1,20 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class Image
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long X { get; set; }
public long Y { get; set; }
public long ImageIndex { get; set; }
public static Image Parse(List<Parameter> descriptor)
public static Image Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
@ -29,7 +32,7 @@ namespace WatchFace.Elements.BasicElements
result.ImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
return result;
}

View File

@ -1,18 +1,21 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class ImageSet
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long X { get; set; }
public long Y { get; set; }
public long ImageIndex { get; set; }
public long ImagesCount { get; set; }
public static ImageSet Parse(List<Parameter> descriptor)
public static ImageSet Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
@ -33,7 +36,7 @@ namespace WatchFace.Elements.BasicElements
result.ImagesCount = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
return result;
}

View File

@ -1,22 +1,25 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class Number
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long TopLeftX { get; set; }
public long TopLeftY { get; set; }
public long BottomRightX { get; set; }
public long BottomRightY { get; set; }
public long Unknown1 { get; set; }
public long Unknown2 { get; set; }
public long Unknown5 { get; set; }
public long Unknown6 { get; set; }
public long ImageIndex { get; set; }
public long ImagesCount { get; set; }
public static Number Parse(List<Parameter> descriptor)
public static Number Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
@ -37,10 +40,10 @@ namespace WatchFace.Elements.BasicElements
result.BottomRightY = parameter.Value;
break;
case 5:
result.Unknown1 = parameter.Value;
result.Unknown5 = parameter.Value;
break;
case 6:
result.Unknown2 = parameter.Value;
result.Unknown6 = parameter.Value;
break;
case 7:
result.ImageIndex = parameter.Value;
@ -49,7 +52,7 @@ namespace WatchFace.Elements.BasicElements
result.ImagesCount = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
return result;
}

View File

@ -1,32 +1,38 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class Scale
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long StartImageIndex { get; set; }
public List<Coordinates> Segments { get; set; }
public static Scale Parse(List<Parameter> descriptor)
public static Scale Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Scale {Segments = new List<Coordinates>()};
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.StartImageIndex = parameter.Value;
break;
case 2:
result.Segments.Add(Coordinates.Parse(parameter.Children));
result.Segments.Add(Coordinates.Parse(parameter.Children, currentPath));
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,32 +1,38 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.BasicElements
{
public class TwoDigits
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public ImageSet Tens { get; set; }
public ImageSet Ones { get; set; }
public static TwoDigits Parse(List<Parameter> descriptor)
public static TwoDigits Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new TwoDigits();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Tens = ImageSet.Parse(parameter.Children);
result.Tens = ImageSet.Parse(parameter.Children, currentPath);
break;
case 2:
result.Ones = ImageSet.Parse(parameter.Children);
result.Ones = ImageSet.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,27 +8,36 @@ namespace WatchFace.Elements
{
public class Battery
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Text { get; set; }
public ImageSet Icon { get; set; }
public Scale Scale { get; set; }
public static Battery Parse(List<Parameter> descriptor)
public static Battery Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Battery();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Text = Number.Parse(parameter.Children);
result.Text = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.Icon = ImageSet.Parse(parameter.Children);
result.Icon = ImageSet.Parse(parameter.Children, currentPath);
break;
case 3:
result.Scale = Scale.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Elements.DateElements;
using WatchFace.Models;
@ -8,27 +9,32 @@ namespace WatchFace.Elements
{
public class Date
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public MonthAndDay MonthAndDay { get; set; }
public ImageSet WeekDay { get; set; }
public static Date Parse(List<Parameter> descriptor)
public static Date Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Date();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.MonthAndDay = MonthAndDay.Parse(parameter.Children);
result.MonthAndDay = MonthAndDay.Parse(parameter.Children, currentPath);
break;
case 2:
result.WeekDay = ImageSet.Parse(parameter.Children);
result.WeekDay = ImageSet.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,40 +1,46 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.DateElements
{
public class MonthAndDay
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public SeparateMonthAndDay Separate { get; set; }
public OneLineMonthAndDay Joined { get; set; }
public long Unknown1 { get; set; }
public long Unknown2 { get; set; }
public long Unknown3 { get; set; }
public long Unknown4 { get; set; }
public static MonthAndDay Parse(List<Parameter> descriptor)
public static MonthAndDay Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new MonthAndDay();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Separate = SeparateMonthAndDay.Parse(parameter.Children);
result.Separate = SeparateMonthAndDay.Parse(parameter.Children, currentPath);
break;
case 2:
result.Joined = OneLineMonthAndDay.Parse(parameter.Children);
result.Joined = OneLineMonthAndDay.Parse(parameter.Children, currentPath);
break;
case 3:
result.Unknown1 = parameter.Value;
result.Unknown3 = parameter.Value;
break;
case 4:
result.Unknown2 = parameter.Value;
result.Unknown4 = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,27 +8,32 @@ namespace WatchFace.Elements.DateElements
{
public class OneLineMonthAndDay
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Number { get; set; }
public long DelimiterImageIndex { get; set; }
public static OneLineMonthAndDay Parse(List<Parameter> descriptor)
public static OneLineMonthAndDay Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new OneLineMonthAndDay();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children);
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.DelimiterImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,27 +8,32 @@ namespace WatchFace.Elements.DateElements
{
public class SeparateMonthAndDay
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Month { get; set; }
public Number Day { get; set; }
public static SeparateMonthAndDay Parse(List<Parameter> descriptor)
public static SeparateMonthAndDay Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new SeparateMonthAndDay();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Month = Number.Parse(parameter.Children);
result.Month = Number.Parse(parameter.Children, currentPath);
break;
case 3:
result.Day = Number.Parse(parameter.Children);
result.Day = Number.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,23 +8,32 @@ namespace WatchFace.Elements
{
public class Scales
{
public Scale Steps { get; set; }
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Scale LinearSteps { get; set; }
public CircleScale CircleSteps { get; set; }
public static Scales Parse(List<Parameter> descriptor)
public static Scales Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Scales();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 2:
result.Steps = Scale.Parse(parameter.Children);
result.LinearSteps = Scale.Parse(parameter.Children, currentPath);
break;
case 3:
result.CircleSteps = CircleScale.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.StatusElements;
using WatchFace.Models;
@ -7,35 +8,40 @@ namespace WatchFace.Elements
{
public class Status
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Switch Bluetooth { get; set; }
public Flag Alarm { get; set; }
public Flag Lock { get; set; }
public Flag DoNotDisturb { get; set; }
public static Status Parse(List<Parameter> descriptor)
public static Status Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Status();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Bluetooth = Switch.Parse(parameter.Children);
result.Bluetooth = Switch.Parse(parameter.Children, currentPath);
break;
case 2:
result.Alarm = Flag.Parse(parameter.Children);
result.Alarm = Flag.Parse(parameter.Children, currentPath);
break;
case 3:
result.Lock = Flag.Parse(parameter.Children);
result.Lock = Flag.Parse(parameter.Children, currentPath);
break;
case 4:
result.DoNotDisturb = Flag.Parse(parameter.Children);
result.DoNotDisturb = Flag.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,27 +8,32 @@ namespace WatchFace.Elements.StatusElements
{
public class Flag
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Coordinates Coordinates { get; set; }
public long ImageIndex { get; set; }
public static Flag Parse(List<Parameter> descriptor)
public static Flag Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Flag();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Coordinates = Coordinates.Parse(parameter.Children);
result.Coordinates = Coordinates.Parse(parameter.Children, currentPath);
break;
case 2:
result.ImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,21 +8,25 @@ namespace WatchFace.Elements.StatusElements
{
public class Switch
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Coordinates Coordinates { get; set; }
public long ImageIndexOn { get; set; }
public long ImageIndexOff { get; set; }
public static Switch Parse(List<Parameter> descriptor)
public static Switch Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Switch();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Coordinates = Coordinates.Parse(parameter.Children);
result.Coordinates = Coordinates.Parse(parameter.Children, currentPath);
break;
case 2:
result.ImageIndexOn = parameter.Value;
@ -30,8 +35,9 @@ namespace WatchFace.Elements.StatusElements
result.ImageIndexOff = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Elements.TimeElements;
using WatchFace.Models;
@ -8,35 +9,40 @@ namespace WatchFace.Elements
{
public class Time
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public TwoDigits Hours { get; set; }
public TwoDigits Minutes { get; set; }
public TwoDigits Seconds { get; set; }
public AmPm AmPm { get; set; }
public static Time Parse(List<Parameter> descriptor)
public static Time Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Time();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Hours = TwoDigits.Parse(parameter.Children);
result.Hours = TwoDigits.Parse(parameter.Children, currentPath);
break;
case 2:
result.Minutes = TwoDigits.Parse(parameter.Children);
result.Minutes = TwoDigits.Parse(parameter.Children, currentPath);
break;
case 3:
result.Seconds = TwoDigits.Parse(parameter.Children);
result.Seconds = TwoDigits.Parse(parameter.Children, currentPath);
break;
case 4:
result.AmPm = AmPm.Parse(parameter.Children);
result.AmPm = AmPm.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,18 +1,21 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.TimeElements
{
public class AmPm
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public long ImageIndexPm { get; set; }
public long ImageIndexAm { get; set; }
public long X { get; set; }
public long Y { get; set; }
public static AmPm Parse(List<Parameter> descriptor)
public static AmPm Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
@ -33,7 +36,7 @@ namespace WatchFace.Elements.TimeElements
result.ImageIndexPm = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
return result;
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.WeatherElements;
using WatchFace.Models;
@ -7,31 +8,36 @@ namespace WatchFace.Elements
{
public class Weather
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public WeatherIcon Icon { get; set; }
public Temperature Temperature { get; set; }
public AirPollution AirPollution { get; set; }
public static Weather Parse(List<Parameter> descriptor)
public static Weather Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Weather();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Icon = WeatherIcon.Parse(parameter.Children);
result.Icon = WeatherIcon.Parse(parameter.Children, currentPath);
break;
case 2:
result.Temperature = Temperature.Parse(parameter.Children);
result.Temperature = Temperature.Parse(parameter.Children, currentPath);
break;
case 3:
result.AirPollution = AirPollution.Parse(parameter.Children);
result.AirPollution = AirPollution.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,23 +8,28 @@ namespace WatchFace.Elements.WeatherElements
{
public class AirPollution
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public ImageSet Icon { get; set; }
public static AirPollution Parse(List<Parameter> descriptor)
public static AirPollution Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new AirPollution();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 2:
result.Icon = ImageSet.Parse(parameter.Children);
result.Icon = ImageSet.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,29 +1,34 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements.WeatherElements
{
public class JoinedTemperature
public class OneLineTemperature
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Number { get; set; }
public long MinusSignImageIndex { get; set; }
public long DelimiterImageIndex { get; set; }
public long Unknown { get; set; }
public long Unknown4 { get; set; }
public long DegreesImageIndex { get; set; }
public static JoinedTemperature Parse(List<Parameter> descriptor)
public static OneLineTemperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new JoinedTemperature();
var result = new OneLineTemperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children);
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.MinusSignImageIndex = parameter.Value;
@ -32,14 +37,15 @@ namespace WatchFace.Elements.WeatherElements
result.DelimiterImageIndex = parameter.Value;
break;
case 4:
result.Unknown = parameter.Value;
result.Unknown4 = parameter.Value;
break;
case 5:
result.DegreesImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,32 +1,47 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements.WeatherElements
{
public class SeparateTemperature
{
public SignedNumber Day { get; set; }
public SignedNumber Night { get; set; }
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public TemperatureNumber Day { get; set; }
public TemperatureNumber Night { get; set; }
public Coordinates Unknown3 { get; set; }
public Coordinates Unknown4 { get; set; }
public static SeparateTemperature Parse(List<Parameter> descriptor)
public static SeparateTemperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new SeparateTemperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Day = SignedNumber.Parse(parameter.Children);
result.Day = TemperatureNumber.Parse(parameter.Children, currentPath);
break;
case 2:
result.Night = SignedNumber.Parse(parameter.Children);
result.Night = TemperatureNumber.Parse(parameter.Children, currentPath);
break;
case 3:
result.Unknown3 = Coordinates.Parse(parameter.Children, currentPath);
break;
case 4:
result.Unknown4 = Coordinates.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,28 +1,38 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.WeatherElements
{
public class Temperature
{
public TextTemperature Text { get; set; }
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public TemperatureNumber Current { get; set; }
public TodayTemperature Today { get; set; }
public static Temperature Parse(List<Parameter> descriptor)
public static Temperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new Temperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Current = TemperatureNumber.Parse(parameter.Children, currentPath);
break;
case 2:
result.Text = TextTemperature.Parse(parameter.Children);
result.Today = TodayTemperature.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,33 +1,43 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
namespace WatchFace.Elements.WeatherElements
{
public class SignedNumber
public class TemperatureNumber
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Number Number { get; set; }
public long MinusImageIndex { get; set; }
public long DegreesImageIndex { get; set; }
public static SignedNumber Parse(List<Parameter> descriptor)
public static TemperatureNumber Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new SignedNumber();
var result = new TemperatureNumber();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Number = Number.Parse(parameter.Children);
result.Number = Number.Parse(parameter.Children, currentPath);
break;
case 2:
result.MinusImageIndex = parameter.Value;
break;
case 3:
result.DegreesImageIndex = parameter.Value;
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,32 +1,38 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Models;
namespace WatchFace.Elements.WeatherElements
{
public class TextTemperature
public class TodayTemperature
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public SeparateTemperature Separate { get; set; }
public JoinedTemperature Joined { get; set; }
public OneLineTemperature OneLine { get; set; }
public static TextTemperature Parse(List<Parameter> descriptor)
public static TodayTemperature Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new TextTemperature();
var result = new TodayTemperature();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Separate = SeparateTemperature.Parse(parameter.Children);
result.Separate = SeparateTemperature.Parse(parameter.Children, currentPath);
break;
case 2:
result.Joined = JoinedTemperature.Parse(parameter.Children);
result.OneLine = OneLineTemperature.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements.BasicElements;
using WatchFace.Models;
@ -7,23 +8,36 @@ namespace WatchFace.Elements.WeatherElements
{
public class WeatherIcon
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Coordinates Coordinates { get; set; }
public Coordinates Unknown3 { get; set; }
public Coordinates Unknown4 { get; set; }
public static WeatherIcon Parse(List<Parameter> descriptor)
public static WeatherIcon Parse(List<Parameter> descriptor, string path)
{
Logger.Trace("Reading {0}", path);
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new WeatherIcon();
foreach (var parameter in descriptor)
{
var currentPath = string.Concat(path, '.', parameter.Id.ToString());
switch (parameter.Id)
{
case 1:
result.Coordinates = Coordinates.Parse(parameter.Children);
result.Coordinates = Coordinates.Parse(parameter.Children, currentPath);
break;
case 3:
result.Unknown3 = Coordinates.Parse(parameter.Children, currentPath);
break;
case 4:
result.Unknown4 = Coordinates.Parse(parameter.Children, currentPath);
break;
default:
throw new InvalidParameterException(parameter);
throw new InvalidParameterException(parameter, path);
}
}
return result;
}
}

View File

@ -5,8 +5,8 @@ namespace WatchFace
{
public class InvalidParameterException : Exception
{
public InvalidParameterException(Parameter paramter) : base(
$"Parameter with Id: {paramter.Id} is not supported in this position."
public InvalidParameterException(Parameter paramter, string path) : base(
$"Parameter with Id: {paramter.Id} is not supported in this position: {path}."
) { }
}
}

View File

@ -7,7 +7,7 @@ namespace WatchFace.JsonConverters
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue($"0x{value:x}");
writer.WriteValue($"0x{value:X6}");
}
public override bool CanConvert(Type objectType)

View File

@ -1,10 +1,14 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using NLog;
namespace WatchFace.Models
{
public class Parameter
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Parameter(byte id, long value)
{
Id = id;
@ -22,37 +26,38 @@ namespace WatchFace.Models
public List<Parameter> Children { get; }
public bool IsComplex => Children != null;
public static Parameter ReadFrom(Stream fileStream)
public static List<Parameter> ReadList(Stream stream, int traceOffset = 0)
{
var result = new List<Parameter>();
while (stream.Position < stream.Length)
{
var parameter = ReadFrom(stream, traceOffset);
result.Add(parameter);
}
return result;
}
public static Parameter ReadFrom(Stream fileStream, int traceOffset = 0)
{
var rawId = fileStream.ReadByte();
var id = (byte) ((rawId & 0xf8) >> 3);
var flags = (ParameterFlags) (rawId & 0x7);
var value = ReadValue(fileStream);
if (flags.HasFlag(ParameterFlags.hasChildren))
{
var readBytes = fileStream.ReadByte();
var buffer = new byte[readBytes];
fileStream.Read(buffer, 0, readBytes);
Logger.Trace(()=> TraceWithOffset($"{id} ({rawId:X2}): {value} bytes", traceOffset));
var buffer = new byte[value];
fileStream.Read(buffer, 0, (int) value);
var stream = new MemoryStream(buffer);
var list = ReadList(stream);
var list = ReadList(stream, traceOffset + 1);
return new Parameter(id, list);
}
var value = ReadValue(fileStream);
Logger.Trace(()=> TraceWithOffset($"{id} ({rawId:X2}): {value} ({value:X2})", traceOffset));
return new Parameter(id, value);
}
public static List<Parameter> ReadList(Stream stream)
{
var result = new List<Parameter>();
while (stream.Position < stream.Length)
{
var parameter = ReadFrom(stream);
result.Add(parameter);
}
return result;
}
private static long ReadValue(Stream fileStream)
{
long value = 0;
@ -68,5 +73,13 @@ namespace WatchFace.Models
value = value | ((long) (currentByte & 0x7f) << offset);
return value;
}
private static string TraceWithOffset(string message, int offset)
{
var builder = new StringBuilder();
for (var i = 0; i < offset; i++) builder.Append(" ");
builder.Append(message);
return builder.ToString();
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using NLog;
using SixLabors.ImageSharp;
using WatchFace.Models;
@ -8,6 +9,8 @@ namespace WatchFace
{
public class Reader
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly FileStream _fileStream;
public Reader(FileStream streamReader)
@ -20,15 +23,28 @@ namespace WatchFace
public void Parse()
{
Logger.Trace("Reading header...");
var header = Header.ReadFrom(_fileStream);
Logger.Trace("Header was read:");
Logger.Trace("Signature: {0}, Unknown: {1}, ParametersSize: {2}, IsValid: {3}", header.Signature,
header.Unknown,
header.ParametersSize, header.IsValid);
if (!header.IsValid) return;
Logger.Trace("Reading parameter offsets...");
var parametersStream = StreamBlock(_fileStream, (int) header.ParametersSize);
Logger.Trace("Parameter offsets were read from file");
Logger.Trace("Reading parameters descriptor...");
var mainParam = Parameter.ReadFrom(parametersStream);
var parameters = Parameter.ReadList(parametersStream);
Logger.Trace("Parameters descriptor was read:");
var coordinatesTableSize = mainParam.Children[0].Value;
var imagesTableLength = mainParam.Children[1].Value;
Logger.Trace($"CoordinatesTableSize: {coordinatesTableSize}, ImagesTableLength: {imagesTableLength}");
Logger.Trace("Reading face parameters...");
var parameters = Parameter.ReadList(parametersStream);
Logger.Trace("Watch face parameters were read:");
ParseResources(coordinatesTableSize, parameters);
ParseImages(imagesTableLength);
@ -41,10 +57,13 @@ namespace WatchFace
Resources = new List<Parameter>(parameters.Count);
foreach (var parameter in parameters)
{
Logger.Trace("Reading descriptor for parameter {0}", parameter.Id);
var descriptorOffset = parameter.Children[0].Value;
var descriptorLength = parameter.Children[1].Value;
Logger.Trace("Descriptor offset: {0}, Descriptor length: {1}", descriptorOffset, descriptorLength);
coordsStream.Seek(descriptorOffset, SeekOrigin.Begin);
var descriptorStream = StreamBlock(coordsStream, (int) descriptorLength);
Logger.Trace("Parsing descriptor for parameter {0}...", parameter.Id);
Resources.Add(new Parameter(parameter.Id, Parameter.ReadList(descriptorStream)));
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using NLog;
using WatchFace.Elements;
using WatchFace.Models;
@ -7,6 +8,7 @@ namespace WatchFace
{
public class WatchFace
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public Background Background { get; set; }
public Time Time { get; set; }
public Date Date { get; set; }
@ -19,44 +21,48 @@ namespace WatchFace
public static WatchFace Parse(List<Parameter> descriptor)
{
Logger.Trace("Rading root");
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
var result = new WatchFace();
foreach (var resource in descriptor)
{
var currentPath = resource.Id.ToString();
switch (resource.Id)
{
case 2:
result.Background = Background.Parse(resource.Children);
result.Background = Background.Parse(resource.Children, currentPath);
break;
case 3:
result.Time = Time.Parse(resource.Children);
result.Time = Time.Parse(resource.Children, currentPath);
break;
case 4:
result.Activity = Activity.Parse(resource.Children);
result.Activity = Activity.Parse(resource.Children, currentPath);
break;
case 5:
result.Date = Date.Parse(resource.Children);
result.Date = Date.Parse(resource.Children, currentPath);
break;
case 6:
result.Weather = Weather.Parse(resource.Children);
result.Weather = Weather.Parse(resource.Children, currentPath);
break;
case 7:
result.Scales = Scales.Parse(resource.Children);
result.Scales = Scales.Parse(resource.Children, currentPath);
break;
case 8:
result.Status = Status.Parse(resource.Children);
result.Status = Status.Parse(resource.Children, currentPath);
break;
case 9:
result.Battery = Battery.Parse(resource.Children);
result.Battery = Battery.Parse(resource.Children, currentPath);
break;
case 10:
result.AnalogDialFace = AnalogDialFace.Parse(resource.Children);
result.AnalogDialFace = AnalogDialFace.Parse(resource.Children, currentPath);
break;
default:
throw new InvalidParameterException(resource);
throw new InvalidParameterException(resource, "");
}
}
return result;
}
}

View File

@ -6,6 +6,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NLog" Version="4.4.12" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0002" />
</ItemGroup>