-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathProgram.cs
More file actions
101 lines (84 loc) · 3.85 KB
/
Program.cs
File metadata and controls
101 lines (84 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
//Intending for parsing https://github.com/HearthSim/python-fsb5/blob/master/fsb5/vorbis_headers.py
namespace HeaderGenerator
{
public class Program
{
private const string FILE_START = "lookup = {";
private const string SEARCH_TERM = "',\n";
private const string DUMMY_HEX_ESCAPE = @"\x00";
private static readonly Regex EscapeRegex = new Regex(@"\\x([a-f0-9]{2})", RegexOptions.Compiled);
public static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("Need to provide path to vorbis_headers.py as an arg");
return;
}
var fileContent = File.ReadAllText(args[0]);
fileContent = fileContent[FILE_START.Length..];
//Each entry should be of the format "{id}: b'first line'\nb'second line'\n...\nb'last line
//Note there is no closing quote on the last line as it is part of the search term.
var entries = fileContent.Split(SEARCH_TERM);
var result = new Dictionary<uint, byte[]>();
foreach (var entry in entries)
{
var colonPos = entry.IndexOf(':');
var num = entry[..colonPos];
var body = entry[(colonPos + 1)..].TrimStart().TrimEnd('}', '\n', '\r');
var contentStringBuilder = new StringBuilder();
foreach (var line in body.Split("\n"))
{
var trimmed = line.Trim().EndsWith("'") || line.Trim().EndsWith("\"")
? line.Trim()
: line.TrimStart(); //Preserve whitespace at end if this is the last line of the block.
if (trimmed.StartsWith("b"))
trimmed = trimmed[2..];
if (trimmed.EndsWith("'") || trimmed.EndsWith('"'))
trimmed = trimmed[..^1];
contentStringBuilder.Append(trimmed);
}
var contentString = contentStringBuilder.ToString();
contentString = contentString.Replace("\\n", "\n")
.Replace("\\t", "\t")
.Replace("\\r", "\r")
.Replace("\\0", "\0")
.Replace("\\'", "\'")
.Replace("\\\"", "\"")
.Replace("\\\\", "\\");
var matches = EscapeRegex.Matches(contentString);
var offsetDict = new Dictionary<int, byte>();
foreach (Match match in matches)
{
var hexString = match.Groups[1].Value;
var charValue = byte.Parse(hexString, NumberStyles.HexNumber);
offsetDict[match.Index] = charValue;
}
List<byte> headerBytes = new List<byte>();
for (var i = 0; i < contentString.Length; i++)
{
if (offsetDict.ContainsKey(i))
{
headerBytes.Add(offsetDict[i]);
i += DUMMY_HEX_ESCAPE.Length - 1;
continue;
}
headerBytes.Add((byte) contentString[i]);
}
result[uint.Parse(num)] = headerBytes.ToArray();
Console.WriteLine($"Parsed {num} => {headerBytes.ToArray().Length} bytes");
}
var jsonValue = JsonSerializer.Serialize(result, new JsonSerializerOptions
{
WriteIndented = true
});
File.WriteAllText("vorbis_headers.json", jsonValue);
}
}
}