-
Notifications
You must be signed in to change notification settings - Fork 88
/
Copy pathStringTable.cs
119 lines (112 loc) · 2.75 KB
/
StringTable.cs
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Decompiler
{
/// <summary>
/// Generates a dictionary of indexes and the strings at those given indexed for use with the PushString instruction
/// </summary>
public class StringTable
{
private byte[] _table;
private static readonly byte[] _nl = {92, 110}, _cr = {92, 114}, _qt = {92, 34};
private Dictionary<int, string> _dictionary;
public StringTable(Stream scriptFile, int[] stringtablelocs, int blockcount, int wholesize)
{
_table = new byte[wholesize];
for (int i = 0, off = 0; i < blockcount; i++, off += 0x4000)
{
int tablesize = ((i + 1)*0x4000 >= wholesize) ? wholesize%0x4000 : 0x4000;
scriptFile.Position = stringtablelocs[i];
scriptFile.Read(_table, off, tablesize);
}
_dictionary = new Dictionary<int, string>();
List<byte> Working = new List<byte>(100);
for (int i = 0, index = 0, max = _table.Length;i<max;i++)
{
for (index = i; i < max; i++)
{
byte b = _table[i];
switch (b)
{
case 0:
goto addString;
case 10:
Working.AddRange(_nl);
break;
case 13:
Working.AddRange(_cr);
break;
case 34:
Working.AddRange(_qt);
break;
default:
Working.Add(b);
break;
}
}
addString:
_dictionary.Add(index, Encoding.ASCII.GetString(Working.ToArray()));
Working.Clear();
}
}
public bool StringExists(int index)
{
return index >= 0 && index < _table.Length;
}
public string this[int index]
{
get
{
if (_dictionary.ContainsKey(index))
{
return _dictionary[index];//keep the fast dictionary access
}
//enable support when the string index doesnt fall straight after a null terminator
if (index < 0 || index >= _table.Length)
{
throw new IndexOutOfRangeException("The index given was outside the range of the String table");
}
List<byte> Working = new List<byte>(100);
for (int i = index, max = _table.Length; i < max; i++)
{
byte b = _table[i];
switch (b)
{
case 0:
goto addString;
case 10:
Working.AddRange(_nl);
break;
case 13:
Working.AddRange(_cr);
break;
case 34:
Working.AddRange(_qt);
break;
default:
Working.Add(b);
break;
}
}
addString:
return Encoding.ASCII.GetString(Working.ToArray());
}
}
public IEnumerator<KeyValuePair<int, string>> GetEnumerator()
{
return _dictionary.GetEnumerator();
}
public int[] Keys
{
get { return _dictionary.Keys.ToArray(); }
}
public string[] Values
{
get { return _dictionary.Values.ToArray(); }
}
}
}