-
Notifications
You must be signed in to change notification settings - Fork 0
/
ByteExtensionMethods.cs
124 lines (111 loc) · 4.31 KB
/
ByteExtensionMethods.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
119
120
121
122
123
124
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
namespace Zero2Unpacker
{
public static class ByteExtensionMethods
{
public static byte[] EmptyHeader = new byte[]
{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
/// <summary>
/// Find a byte pattern in a byte buffer in reverse.
/// </summary>
/// <param name="fileBuffer"></param>
/// <param name="bytesToFind"></param>
/// <param name="startingIndex"></param>
/// <returns>Index of the beginning of the bytesToFind array in the fileBuffer.</returns>
public static int FindBytesIndexBackWardInByteBuffer(this byte[] fileBuffer, byte[] bytesToFind, int startingIndex = 0)
{
var searchPosition = 0;
for (var i = startingIndex; i > 0; i--)
{
if (fileBuffer[i] != bytesToFind[searchPosition])
{
searchPosition = bytesToFind.Length - 1;
}
else if (fileBuffer[i] == bytesToFind[searchPosition])
{
searchPosition--;
if (searchPosition != -1)
{
continue;
}
return i;
}
}
return -1;
}
/// <summary>
/// Find a byte pattern in a byte buffer.
/// </summary>
/// <param name="fileBuffer"></param>
/// <param name="bytesToFind"></param>
/// <param name="startingIndex"></param>
/// <returns>Index of the beginning of the bytesToFind array in the fileBuffer.</returns>
public static int FindBytesIndexInByteBuffer(this byte[] fileBuffer, byte[] bytesToFind, int startingIndex = 0)
{
var searchPosition = 0;
for (var i = startingIndex; i < fileBuffer.Length; i++)
{
if (fileBuffer[i] != bytesToFind[searchPosition])
{
searchPosition = 0;
}
else if (fileBuffer[i] == bytesToFind[searchPosition])
{
searchPosition++;
if (searchPosition != bytesToFind.Length)
{
continue;
}
return i;
}
}
return -1;
}
public static long BinaryStreamFindArrayBackwards(this BinaryReader binReader, byte[] bytesToFind, long fileSize)
{
while (binReader.BaseStream.Position < fileSize && binReader.BaseStream.Position > 0)
{
var latestBytes = binReader.ReadBytes(0x10);
var index = latestBytes.FindBytesIndexInByteBuffer(EmptyHeader);
if (index > -1)
{
return binReader.BaseStream.Position - 0x10;
}
binReader.BaseStream.Position -= 0x20;
}
return -1;
}
/// <summary>
/// Writes a buffer range to a new file.
/// </summary>
/// <param name="fileBuffer"></param>
/// <param name="zeroFile"></param>
/// <param name="files"></param>
public static void WriteBufferRangeToFile(this byte[] fileBuffer, ZeroFile zeroFile, BlockingCollection<ZeroFile> files)
{
files.Add(new ZeroFile()
{
StartingPosition = zeroFile.StartingPosition,
EndingPosition = zeroFile.EndingPosition,
FileSize = zeroFile.EndingPosition - zeroFile.StartingPosition,
FileId = zeroFile.FileId,
FileName = zeroFile.FileName,
Folder = zeroFile.Folder,
FileHeader = zeroFile.FileHeader
});
Directory.CreateDirectory(zeroFile.Folder);
using var writer = new BinaryWriter(File.Open($"{zeroFile.Folder}{zeroFile.FileName}_{zeroFile.FileId}.{zeroFile.FileHeader.FileExtension}", FileMode.Create));
for (var i = zeroFile.StartingPosition; i < zeroFile.EndingPosition; i++)
{
writer.Write(fileBuffer[i]);
}
}
}
}