-
Notifications
You must be signed in to change notification settings - Fork 13
/
SoulsFile.cs
144 lines (129 loc) · 4.68 KB
/
SoulsFile.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System.IO;
namespace SoulsFormats
{
/// <summary>
/// A generic From file supporting transparent DCX reading and writing.
/// </summary>
public abstract class SoulsFile<TFormat> where TFormat : SoulsFile<TFormat>, new()
{
/// <summary>
/// The type of DCX compression to be used when writing.
/// </summary>
public DCX.Type Compression = DCX.Type.None;
/// <summary>
/// Returns true if the data appears to be a file of this type.
/// </summary>
// This should really be a static method, but interfaces do not allow static inheritance; hence the dummy objects below.
internal abstract bool Is(BinaryReaderEx br);
/// <summary>
/// Returns true if the bytes appear to be a file of this type.
/// </summary>
public static bool Is(byte[] bytes)
{
if (bytes.Length == 0)
return false;
BinaryReaderEx br = new BinaryReaderEx(false, bytes);
var dummy = new TFormat();
return dummy.Is(SFUtil.GetDecompressedBR(br, out _));
}
/// <summary>
/// Returns true if the file appears to be a file of this type.
/// </summary>
public static bool Is(string path)
{
using (FileStream stream = File.OpenRead(path))
{
if (stream.Length == 0)
return false;
BinaryReaderEx br = new BinaryReaderEx(false, stream);
var dummy = new TFormat();
return dummy.Is(SFUtil.GetDecompressedBR(br, out _));
}
}
/// <summary>
/// Loads file data from a BinaryReaderEx.
/// </summary>
internal abstract void Read(BinaryReaderEx br);
/// <summary>
/// Loads a file from a byte array, automatically decompressing it if necessary.
/// </summary>
public static TFormat Read(byte[] bytes)
{
BinaryReaderEx br = new BinaryReaderEx(false, bytes);
TFormat file = new TFormat();
br = SFUtil.GetDecompressedBR(br, out file.Compression);
file.Read(br);
return file;
}
/// <summary>
/// Loads a file from the specified path, automatically decompressing it if necessary.
/// </summary>
public static TFormat Read(string path)
{
using (FileStream stream = File.OpenRead(path))
{
BinaryReaderEx br = new BinaryReaderEx(false, stream);
TFormat file = new TFormat();
br = SFUtil.GetDecompressedBR(br, out file.Compression);
file.Read(br);
return file;
}
}
/// <summary>
/// Writes file data to a BinaryWriterEx.
/// </summary>
internal abstract void Write(BinaryWriterEx bw);
/// <summary>
/// Writes file data to a BinaryWriterEx, compressing it afterwards if specified.
/// </summary>
private void Write(BinaryWriterEx bw, DCX.Type compression)
{
if (compression == DCX.Type.None)
{
Write(bw);
}
else
{
BinaryWriterEx bwUncompressed = new BinaryWriterEx(false);
Write(bwUncompressed);
byte[] uncompressed = bwUncompressed.FinishBytes();
DCX.Compress(uncompressed, bw, compression);
}
}
/// <summary>
/// Writes the file to an array of bytes, automatically compressing it if necessary.
/// </summary>
public byte[] Write()
{
return Write(Compression);
}
/// <summary>
/// Writes the file to an array of bytes, compressing it as specified.
/// </summary>
public byte[] Write(DCX.Type compression)
{
BinaryWriterEx bw = new BinaryWriterEx(false);
Write(bw, compression);
return bw.FinishBytes();
}
/// <summary>
/// Writes the file to the specified path, automatically compressing it if necessary.
/// </summary>
public void Write(string path)
{
Write(path, Compression);
}
/// <summary>
/// Writes the file to the specified path, compressing it as specified.
/// </summary>
public void Write(string path, DCX.Type compression)
{
using (FileStream stream = File.Create(path))
{
BinaryWriterEx bw = new BinaryWriterEx(false, stream);
Write(bw, compression);
bw.Finish();
}
}
}
}