Parser now creates lists only when it is necessary

This commit is contained in:
Timerix 2025-04-10 16:12:48 +05:00
parent 08f1d7b0f5
commit 74d09c51a0
5 changed files with 31 additions and 23 deletions

View File

@ -38,7 +38,7 @@ internal static partial class Modes
var parser = new SaveParserEU4(inputStream, searchExpression); var parser = new SaveParserEU4(inputStream, searchExpression);
var parsedValue = parser.Parse(); var parsedValue = parser.Parse();
JsonSerializer.Serialize(outputStream, parsedValue, JsonSerializer.Serialize(outputStream, parsedValue,
ParsedValueJsonContext.Default.DictionaryStringListObject); ParsedValueJsonContext.Default.DictionaryStringObject);
outputStream.WriteByte((byte)'\n'); outputStream.WriteByte((byte)'\n');
} }
finally finally

View File

@ -3,7 +3,7 @@
namespace ParadoxSaveParser.Lib; namespace ParadoxSaveParser.Lib;
[JsonSourceGenerationOptions(MaxDepth = 1024, WriteIndented = true)] [JsonSourceGenerationOptions(MaxDepth = 1024, WriteIndented = true)]
[JsonSerializable(typeof(Dictionary<string, List<object>>))] [JsonSerializable(typeof(Dictionary<string, object>))]
[JsonSerializable(typeof(List<object>))] [JsonSerializable(typeof(List<object>))]
[JsonSerializable(typeof(string))] [JsonSerializable(typeof(string))]
[JsonSerializable(typeof(long))] [JsonSerializable(typeof(long))]

View File

@ -216,7 +216,7 @@ public class SaveParserEU4
} }
private static bool IsEmptyCollection(object value) private static bool IsEmptyCollection(object value)
=> value is Dictionary<string, List<object>> { Count: 0 } or List<object> { Count: 0 }; => value is Dictionary<string, object> { Count: 0 } or List<object> { Count: 0 };
// doesn't move next // doesn't move next
private object ParseListOrDict() private object ParseListOrDict()
@ -264,9 +264,9 @@ public class SaveParserEU4
} }
// moves next // moves next
private Dictionary<string, List<object>> ParseDict() private Dictionary<string, object> ParseDict()
{ {
Dictionary<string, List<object>> dict = new(); Dictionary<string, object> dict = new();
// root is a dict without closing bracket, so this method must check _tokenIndex < _tokens.Count // root is a dict without closing bracket, so this method must check _tokenIndex < _tokens.Count
for (int localIndex = 0; _tokens.MoveNext(); localIndex++) for (int localIndex = 0; _tokens.MoveNext(); localIndex++)
@ -327,23 +327,32 @@ public class SaveParserEU4
string keyStr = keySB.ToString(); string keyStr = keySB.ToString();
_stringBuilderPool.Return(keySB); _stringBuilderPool.Return(keySB);
if (!dict.TryGetValue(keyStr, out var list))
{
list = new List<object>();
dict.Add(keyStr, list);
}
// do dot add empty collections into list // Paradox save format has another way of defining list:
if (IsEmptyCollection(value)) // a = 1
continue; // a = 2
list.Add(value); // It means `a = { 1 2 }`
if (dict.TryGetValue(keyStr, out var firstValue))
{
// Do dot add empty collections into list.
// `key:{}` is okay, but i don't want to see `key:[{},{},{},{},{},{}]`
if (IsEmptyCollection(value))
continue;
if (firstValue is List<object> existingList)
existingList.Add(value);
else dict[keyStr] = new List<object> { firstValue, value };
}
else
{
dict.Add(keyStr, value);
}
} }
return dict; return dict;
} }
public Dictionary<string, List<object>> Parse() public Dictionary<string, object> Parse()
{ {
var root = ParseDict(); var root = ParseDict();
return root; return root;

View File

@ -5,5 +5,5 @@ public interface ISaveDataFilter
public string SearchString { get; } public string SearchString { get; }
public ISearchExpression SearchExpression { get; } public ISearchExpression SearchExpression { get; }
public void Apply(Dictionary<string, List<object>> data); public void Apply(Dictionary<string, object> data);
} }

View File

@ -1,5 +1,5 @@
using System.Linq; using System.Linq;
using ParsedDict = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<object>>; using ParsedDict = System.Collections.Generic.Dictionary<string, object>;
namespace ParadoxSaveParser.WebAPI.SaveDataFilters; namespace ParadoxSaveParser.WebAPI.SaveDataFilters;
@ -38,12 +38,11 @@ public class SaveDataFilterEU4 : ISaveDataFilter
public void Apply(ParsedDict data) public void Apply(ParsedDict data)
{ {
var countries = (ParsedDict)data["countries"][0]; var countries = (ParsedDict)data["countries"];
var countries_filtered = countries.Where(pair var countries_filtered = countries.Where(pair
=> pair.Value.Count > 0 => ((ParsedDict)pair.Value).TryGetValue("raw_development", out var raw_development)
&& ((ParsedDict)pair.Value[0]).TryGetValue("raw_development", out var raw_development) && (double)raw_development > 0
&& (double)raw_development[0] > 0
).ToDictionary(); ).ToDictionary();
data["countries"][0] = countries_filtered; data["countries"] = countries_filtered;
} }
} }