From be5c9b58148d542a43e6bc8dc6dbb13de6cdf366 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 8 Oct 2023 15:28:19 +0100 Subject: [PATCH] [Symbian Installation File] Adjust parsing so options are parsed first to have their name available when used as conditions. --- Aaru.Archives/Symbian/Conditions.cs | 29 ++++++++++++++++++++++-- Aaru.Archives/Symbian/Info.cs | 12 +++++++++- Aaru.Archives/Symbian/Open.cs | 12 +++++++++- Aaru.Archives/Symbian/Parser.cs | 34 ++++++++++++++++++++++++----- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/Aaru.Archives/Symbian/Conditions.cs b/Aaru.Archives/Symbian/Conditions.cs index 065db4a3d..eaccc0103 100644 --- a/Aaru.Archives/Symbian/Conditions.cs +++ b/Aaru.Archives/Symbian/Conditions.cs @@ -32,6 +32,7 @@ using System; using System.IO; +using System.Linq; using System.Text; namespace Aaru.Archives; @@ -172,7 +173,19 @@ public sealed partial class Symbian }; if((int)attributeExpression.attribute > 0x2000) - sb.Append($"option({attributeExpression.attribute - 0x2000}, ENABLED)"); + { + int optionIndex = (int)attributeExpression.attribute - 0x2000; + + if(optionIndex <= _options.Count) + { + OptionRecord option = _options[optionIndex - 1]; + option.names.TryGetValue("EN", out string optionName); + optionName ??= option.names.Values.FirstOrDefault() ?? optionIndex.ToString(); + sb.Append($"option(\"{optionName}\", ENABLED)"); + } + else + sb.Append($"option({optionIndex}, ENABLED"); + } else sb.Append($"{attributeExpression.attribute}"); @@ -270,7 +283,19 @@ public sealed partial class Symbian } } else - sb.Append($"option({attribute.Value - 0x2000}, {(numberExpression.number > 0 ? "ENABLED" : "DISABLED")})"); + { + int optionIndex = (int)attribute - 0x2000; + + if(optionIndex <= _options.Count) + { + OptionRecord option = _options[optionIndex - 1]; + option.names.TryGetValue("EN", out string optionName); + optionName ??= option.names.Values.FirstOrDefault() ?? optionIndex.ToString(); + sb.Append($"option(\"{optionName}\", {(numberExpression.number == 0 ? "DISABLED" : "ENABLED")})"); + } + else + sb.Append($"option({optionIndex}, {(numberExpression.number == 0 ? "DISABLED" : "ENABLED")}"); + } attribute = null; diff --git a/Aaru.Archives/Symbian/Info.cs b/Aaru.Archives/Symbian/Info.cs index 66e378ac7..124b700b8 100644 --- a/Aaru.Archives/Symbian/Info.cs +++ b/Aaru.Archives/Symbian/Info.cs @@ -303,9 +303,19 @@ public sealed partial class Symbian var conditionLevel = 0; _options = new List(); + // Get only the options records do { - Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel); + Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, true); + } while(currentFile < sh.files); + + // Get all other records + offset = sh.files_ptr; + currentFile = 0; + conditionLevel = 0; + do + { + Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, false); } while(currentFile < sh.files); description.AppendLine(); diff --git a/Aaru.Archives/Symbian/Open.cs b/Aaru.Archives/Symbian/Open.cs index 0d6600dbb..e903f9268 100644 --- a/Aaru.Archives/Symbian/Open.cs +++ b/Aaru.Archives/Symbian/Open.cs @@ -132,9 +132,19 @@ public sealed partial class Symbian uint offset = sh.files_ptr; var conditionLevel = 0; + // Get only the options records do { - Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel); + Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, true); + } while(currentFile < sh.files); + + // Get all other records + offset = sh.files_ptr; + currentFile = 0; + conditionLevel = 0; + do + { + Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, false); } while(currentFile < sh.files); // Files appear on .sis in the reverse order they should be processed diff --git a/Aaru.Archives/Symbian/Parser.cs b/Aaru.Archives/Symbian/Parser.cs index 8dfc14eb0..3c0bae384 100644 --- a/Aaru.Archives/Symbian/Parser.cs +++ b/Aaru.Archives/Symbian/Parser.cs @@ -45,7 +45,7 @@ namespace Aaru.Archives; public sealed partial class Symbian { void Parse(BinaryReader br, ref uint offset, ref uint currentFile, uint maxFiles, List languages, - ref int conditionLevel) + ref int conditionLevel, bool optionsOnly) { currentFile++; @@ -84,6 +84,9 @@ public sealed partial class Symbian if(!_release6) offset -= sizeof(uint) * 3; + if(optionsOnly) + break; + var decodedFileRecord = new DecodedFileRecord { type = simpleFileRecord.record.type, @@ -276,6 +279,8 @@ public sealed partial class Symbian multipleFileRecord.originalLengths = multipleFileRecord.lengths; offset = (uint)br.BaseStream.Position; + if(optionsOnly) + break; br.BaseStream.Seek(multipleFileRecord.record.sourceNamePtr, SeekOrigin.Begin); buffer = br.ReadBytes((int)multipleFileRecord.record.sourceNameLen); @@ -485,7 +490,8 @@ public sealed partial class Symbian br.BaseStream.Seek(offset, SeekOrigin.Begin); - _options.Add(optionsLineRecord.options[i]); + if(optionsOnly) + _options.Add(optionsLineRecord.options[i]); } offset = (uint)br.BaseStream.Position; @@ -504,7 +510,11 @@ public sealed partial class Symbian length = br.ReadUInt32() }; - offset = (uint)(br.BaseStream.Position + conditionalRecord.length); + offset = (uint)(br.BaseStream.Position + conditionalRecord.length); + + if(optionsOnly) + break; + conditionSb = new StringBuilder(); nullAttribute = null; @@ -527,7 +537,11 @@ public sealed partial class Symbian length = br.ReadUInt32() }; - offset = (uint)(br.BaseStream.Position + conditionalRecord.length); + offset = (uint)(br.BaseStream.Position + conditionalRecord.length); + + if(optionsOnly) + break; + conditionSb = new StringBuilder(); nullAttribute = null; @@ -544,15 +558,23 @@ public sealed partial class Symbian tabulationChars[i] = '\t'; tabulation = new string(tabulationChars); - _conditions.Add(tabulation + "else"); offset = (uint)(br.BaseStream.Position + Marshal.SizeOf()); + if(optionsOnly) + break; + + _conditions.Add(tabulation + "else"); + break; case FileRecordType.EndIf: conditionLevel++; - _conditions.Add(tabulation + "endif()" + Environment.NewLine); offset = (uint)(br.BaseStream.Position + Marshal.SizeOf()); + if(optionsOnly) + break; + + _conditions.Add(tabulation + "endif()" + Environment.NewLine); + break; case FileRecordType.Skip: offset = (uint)br.BaseStream.Seek(sizeof(FileRecordType), SeekOrigin.Current);