98 lines
4.3 KiB
C#
98 lines
4.3 KiB
C#
using System;
|
|
using System.IO;
|
|
|
|
namespace Lucidiot.Magellan {
|
|
public static class MapArchive {
|
|
public static MapArchiveEntry[] ReadHeader(string path) {
|
|
if (!File.Exists(path)) throw new FileNotFoundException("Archive file not found.", path);
|
|
using (FileStream stream = File.Open(path, FileMode.Open)) {
|
|
return ReadHeader(stream);
|
|
}
|
|
}
|
|
|
|
public static MapArchiveEntry[] ReadHeader(Stream stream) {
|
|
if (!stream.CanSeek)
|
|
throw new ArgumentException("Reading capability is required on the stream in order to read the header.", "stream");
|
|
using (BinaryReader br = new BinaryReader(stream)) {
|
|
return ReadHeader(br);
|
|
}
|
|
}
|
|
|
|
public static MapArchiveEntry[] ReadHeader(BinaryReader br) {
|
|
uint length1 = br.ReadUInt32();
|
|
uint length2 = br.ReadUInt32();
|
|
if (length1 != length2)
|
|
throw new NotSupportedException("Unexpected header: Two different entry counts found.");
|
|
|
|
MapArchiveEntry[] entries = new MapArchiveEntry[length1];
|
|
for (int i = 0; i < length1; i++) {
|
|
entries[i] = MapArchiveEntry.Parse(br);
|
|
}
|
|
return entries;
|
|
}
|
|
|
|
public static void ExtractAll(string path, string destination) {
|
|
if (!File.Exists(path))
|
|
throw new FileNotFoundException("MGI file not found.", path);
|
|
if (!Directory.Exists(destination))
|
|
throw new DirectoryNotFoundException("Destination path is not a valid directory.");
|
|
|
|
using (FileStream stream = File.Open(path, FileMode.Open)) {
|
|
ExtractAll(stream, destination);
|
|
}
|
|
}
|
|
|
|
public static void ExtractAll(Stream stream, string destination) {
|
|
if (!stream.CanSeek)
|
|
throw new ArgumentException("Seeking capability is required on the stream in order to extract.", "stream");
|
|
if (!stream.CanRead)
|
|
throw new ArgumentException("Reading capability is required on the stream in order to extract.", "stream");
|
|
|
|
using (BinaryReader br = new BinaryReader(stream)) {
|
|
ExtractAll(br, destination);
|
|
}
|
|
}
|
|
|
|
public static void ExtractAll(BinaryReader br, string destination) {
|
|
if (!br.BaseStream.CanSeek)
|
|
throw new ArgumentException("Seeking capability is required on the stream reader in order to extract.", "br");
|
|
|
|
ExtractAll(br, ReadHeader(br), destination);
|
|
}
|
|
|
|
public static void ExtractAll(string path, MapArchiveEntry[] entries, string destination) {
|
|
if (!File.Exists(path))
|
|
throw new FileNotFoundException("Archive file not found.", path);
|
|
if (!Directory.Exists(destination))
|
|
throw new DirectoryNotFoundException("Destination path is not a valid directory.");
|
|
|
|
using (FileStream stream = File.Open(path, FileMode.Open)) {
|
|
ExtractAll(stream, entries, destination);
|
|
}
|
|
}
|
|
|
|
public static void ExtractAll(Stream stream, MapArchiveEntry[] entries, string destination) {
|
|
if (!stream.CanSeek)
|
|
throw new ArgumentException("Seeking capability is required on the stream in order to extract.", "stream");
|
|
if (!stream.CanRead)
|
|
throw new ArgumentException("Reading capability is required on the stream in order to extract.", "stream");
|
|
|
|
using (BinaryReader br = new BinaryReader(stream)) {
|
|
ExtractAll(br, entries, destination);
|
|
}
|
|
}
|
|
|
|
public static void ExtractAll(BinaryReader br, MapArchiveEntry[] entries, string destination) {
|
|
if (!br.BaseStream.CanSeek)
|
|
throw new ArgumentException("Seeking capability is required on the stream reader in order to extract.", "br");
|
|
if (!br.BaseStream.CanRead)
|
|
throw new ArgumentException("Reading capability is required on the stream reader in order to extract.", "br");
|
|
|
|
foreach (MapArchiveEntry entry in entries) {
|
|
string path = Path.Combine(destination, entry.FullName.Replace('\0', '_'));
|
|
entry.Extract(br, path);
|
|
}
|
|
}
|
|
}
|
|
}
|