magellan/Lucidiot.Magellan/MapArchive.cs

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);
}
}
}
}