55 lines
2.1 KiB
C#
55 lines
2.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Lucidiot.Raima;
|
|
|
|
namespace Lucidiot.Magellan {
|
|
public class MapArchiveStorage : ReadOnlyDatabaseStorage, IDisposable {
|
|
private Dictionary<string, MapArchiveEntry> entriesCache;
|
|
private readonly Stream ArchiveStream;
|
|
|
|
public MapArchiveStorage(string path) {
|
|
if (!File.Exists(path))
|
|
throw new FileNotFoundException("Archive file not found.", path);
|
|
this.ArchiveStream = File.OpenRead(path);
|
|
}
|
|
|
|
public MapArchiveStorage(Stream stream) {
|
|
if (!stream.CanSeek)
|
|
throw new ArgumentException("Seeking capability is required on the stream in order to use it as database storage.", "br");
|
|
if (!stream.CanRead)
|
|
throw new ArgumentException("Reading capability is required on the stream in order to use it as database storage.", "br");
|
|
this.ArchiveStream = stream;
|
|
}
|
|
|
|
public MapArchiveEntry? TryFindEntry(string fileName) {
|
|
if (entriesCache == null) {
|
|
ArchiveStream.Seek(0, SeekOrigin.Begin);
|
|
entriesCache = new Dictionary<string, MapArchiveEntry>();
|
|
foreach (MapArchiveEntry entry in MapArchive.ReadHeader(new BinaryReader(ArchiveStream))) {
|
|
entriesCache[entry.FullName] = entry;
|
|
}
|
|
}
|
|
|
|
MapArchiveEntry result;
|
|
if (!entriesCache.TryGetValue(fileName, out result))
|
|
return null;
|
|
return result;
|
|
}
|
|
|
|
public override bool Exists(string fileName) {
|
|
return TryFindEntry(fileName) != null;
|
|
}
|
|
|
|
public override BinaryReader GetReader(string fileName) {
|
|
MapArchiveEntry? entry = TryFindEntry(fileName);
|
|
if (entry == null)
|
|
throw new FileNotFoundException("File does not exist", fileName);
|
|
return new BinaryReader(new Substream(ArchiveStream, entry.Value.Offset, entry.Value.Length));
|
|
}
|
|
|
|
public void Dispose() {
|
|
ArchiveStream.Dispose();
|
|
}
|
|
}
|
|
} |