ParadoxSaveParser/ParadoxSaveParser.CLI/Modes/Search.cs

49 lines
1.8 KiB
C#

using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.Json;
using ParadoxSaveParser.Lib;
namespace ParadoxSaveParser.CLI;
internal static partial class Modes
{
internal static void Search(string searchQuery, IOPath inputPath, IOPath? outputPath)
{
Stream inputStream = File.OpenRead(inputPath);
try
{
byte[] head4 = new byte[4];
inputStream.ReadExactly(head4);
inputStream.Seek(0, SeekOrigin.Begin);
if (head4.SequenceEqual<byte>([(byte)'P', (byte)'K', 3, 4]))
{
var zipArchive = new ZipArchive(inputStream, ZipArchiveMode.Read);
var zipEntry = zipArchive.Entries.FirstOrDefault(e => e.Name == "gamestate");
if (zipEntry is null)
throw new Exception("'gamestate' file not found in zip archive");
var unzipped = new MemoryStream((int)zipEntry.Length);
zipEntry.Open().CopyTo(unzipped);
zipArchive.Dispose(); // closes inputStream
unzipped.Seek(0, SeekOrigin.Begin);
inputStream = unzipped;
}
using var outputStream = outputPath is null
? Console.OpenStandardOutput()
: File.OpenWrite(outputPath.Value);
var searchExpression = SearchExpressionCompiler.Compile(searchQuery);
var parser = new SaveParserEU4(inputStream, searchExpression);
var parsedValue = parser.Parse();
JsonSerializer.Serialize(outputStream, parsedValue,
ParsedValueJsonContext.Default.DictionaryStringListObject);
outputStream.WriteByte((byte)'\n');
}
finally
{
inputStream.Dispose();
}
}
}