diff --git a/GameRes/ArcFile.cs b/GameRes/ArcFile.cs
index 8911d4f3..5cd0d1e5 100644
--- a/GameRes/ArcFile.cs
+++ b/GameRes/ArcFile.cs
@@ -43,6 +43,9 @@ namespace GameRes
/// Short archive format description.
public string Description { get { return m_interface.Description; } }
+ /// Tags of formats related to this archive format (could be null).
+ public IEnumerable ContainedFormats { get { return m_interface.ContainedFormats; } }
+
/// Memory-mapped view of the archive.
public ArcView File { get { return m_arc; } }
diff --git a/GameRes/ArchiveFormat.cs b/GameRes/ArchiveFormat.cs
index 00a989b3..6a5ca538 100644
--- a/GameRes/ArchiveFormat.cs
+++ b/GameRes/ArchiveFormat.cs
@@ -26,6 +26,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
namespace GameRes
{
@@ -41,8 +42,34 @@ namespace GameRes
///
public abstract bool IsHierarchic { get; }
+ ///
+ /// Tags of formats related to this archive format (could be null).
+ ///
+ public IEnumerable ContainedFormats { get; protected set; }
+
public abstract ArcFile TryOpen (ArcView view);
+ ///
+ /// Create GameRes.Entry corresponding to extension.
+ ///
+ /// May be thrown if filename contains invalid
+ /// characters.
+ public EntryType Create (string filename) where EntryType : Entry, new()
+ {
+ EntryType entry = null;
+ var formats = FormatCatalog.Instance.LookupFileName (filename);
+ if (formats.Any())
+ {
+ if (ContainedFormats != null && ContainedFormats.Any())
+ formats = formats.OrderByDescending (f => ContainedFormats.Contains (f.Tag));
+ entry = new EntryType { Type = formats.First().Type };
+ }
+ if (null == entry)
+ entry = new EntryType();
+ entry.Name = filename;
+ return entry;
+ }
+
///
/// Extract file referenced by into current directory.
///
diff --git a/GameRes/FormatCatalog.cs b/GameRes/FormatCatalog.cs
index 7b46a4fa..1e2c520a 100644
--- a/GameRes/FormatCatalog.cs
+++ b/GameRes/FormatCatalog.cs
@@ -239,6 +239,13 @@ namespace GameRes
{
var ext = new Lazy (() => Path.GetExtension (filename).TrimStart ('.').ToLowerInvariant(), false);
var tried = Enumerable.Empty();
+ IEnumerable preferred = null;
+ if (VFS.IsVirtual)
+ {
+ var arc_fs = VFS.Top as ArchiveFileSystem;
+ if (arc_fs != null)
+ preferred = arc_fs.Source.ContainedFormats;
+ }
for (;;)
{
var range = LookupSignature (signature);
@@ -247,6 +254,8 @@ namespace GameRes
// check formats that match filename extension first
if (range.Skip (1).Any()) // if range.Count() > 1
range = range.OrderByDescending (f => f.Extensions.Any (e => e == ext.Value));
+ if (preferred != null && preferred.Any())
+ range = range.OrderByDescending (f => preferred.Contains (f.Tag));
foreach (var impl in range)
{
yield return impl;
@@ -268,7 +277,7 @@ namespace GameRes
EntryType entry = null;
var formats = LookupFileName (filename);
if (formats.Any())
- entry = formats.First().Create();
+ entry = new EntryType { Type = formats.First().Type };
if (null == entry)
entry = new EntryType();
entry.Name = filename;
diff --git a/GameRes/GameRes.cs b/GameRes/GameRes.cs
index 30958893..aa0f82b2 100644
--- a/GameRes/GameRes.cs
+++ b/GameRes/GameRes.cs
@@ -109,14 +109,6 @@ namespace GameRes
/// Resource access scheme suitable for serialization.
public virtual ResourceScheme Scheme { get; set; }
- ///
- /// Create empty Entry that corresponds to implemented resource.
- ///
- public EntryType Create () where EntryType : Entry, new()
- {
- return new EntryType { Type = this.Type };
- }
-
protected IResource ()
{
Extensions = new string[] { GetDefaultExtension() };