Skip to content

Commit e67e1b0

Browse files
committed
Instead of guarding this with "Huxley" which breaks BigEndianess packages, check if it's safe to read a string in bulk. This way we also keep the performance benefits for non huxley packages.
1 parent fd7b75c commit e67e1b0

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

src/UnrealStream.cs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ public class UnrealReader : BinaryReader
166166
{
167167
private readonly byte[] _IndexBuffer = new byte[5];
168168

169+
// Allow bulk reading of strings if the package is not big endian encoded.
170+
// Generally this is the case for most packages, but some games have big endian encoded packages, where a string is serialized per byte.
171+
private bool CanBulkRead => Archive.BigEndianCode == false; // Must get, because this is not initialized before the constructor initiation.
172+
169173
// Dirty hack to implement crypto-reading, pending overhaul ;)
170174
public UnrealReader(IUnrealArchive archive, Stream baseStream) : base(baseStream) => Archive = archive;
171175

@@ -182,14 +186,18 @@ public string ReadString(int length)
182186
if (length > 0) // ANSI
183187
{
184188
byte[] chars = new byte[size];
185-
#if HUXLEY
186-
BaseStream.Read(chars, 0, chars.Length);
187-
#else
188-
for (int i = 0; i < chars.Length; ++i)
189+
190+
if (CanBulkRead)
189191
{
190-
BaseStream.Read(chars, i, 1);
192+
BaseStream.Read(chars, 0, chars.Length);
193+
}
194+
else
195+
{
196+
for (int i = 0; i < chars.Length; ++i)
197+
{
198+
BaseStream.Read(chars, i, 1);
199+
}
191200
}
192-
#endif
193201

194202
return chars[size - 1] == '\0'
195203
? Encoding.ASCII.GetString(chars, 0, chars.Length - 1)
@@ -198,25 +206,28 @@ public string ReadString(int length)
198206

199207
if (length < 0) // UNICODE
200208
{
201-
#if HUXLEY
202-
byte[] chars = new byte[size * 2];
203-
BaseStream.Read(chars, 0, chars.Length);
204-
205-
return chars[(size * 2) - 2] == '\0' && chars[(size * 2) - 1] == '\0'
206-
? Encoding.Unicode.GetString(chars, 0, chars.Length - 2)
207-
: Encoding.Unicode.GetString(chars, 0, chars.Length);
208-
#else
209-
char[] chars = new char[size];
210-
for (int i = 0; i < chars.Length; ++i)
209+
if (CanBulkRead)
211210
{
212-
char w = (char)ReadInt16();
213-
chars[i] = w;
211+
byte[] chars = new byte[size * 2];
212+
BaseStream.Read(chars, 0, chars.Length);
213+
214+
return chars[(size * 2) - 2] == '\0' && chars[(size * 2) - 1] == '\0'
215+
? Encoding.Unicode.GetString(chars, 0, chars.Length - 2)
216+
: Encoding.Unicode.GetString(chars, 0, chars.Length);
214217
}
218+
else
219+
{
220+
char[] chars = new char[size];
221+
for (int i = 0; i < chars.Length; ++i)
222+
{
223+
char w = (char)ReadInt16();
224+
chars[i] = w;
225+
}
215226

216-
return chars[size - 1] == '\0'
217-
? new string(chars, 0, chars.Length - 1)
218-
: new string(chars);
219-
#endif
227+
return chars[size - 1] == '\0'
228+
? new string(chars, 0, chars.Length - 1)
229+
: new string(chars);
230+
}
220231
}
221232

222233
return string.Empty;

0 commit comments

Comments
 (0)