Implement Associations

This commit is contained in:
Michael Becker 2014-12-11 11:42:24 -05:00
parent 54e71e4e08
commit c9c3dfa5b0
4 changed files with 231 additions and 0 deletions

View File

@ -3,6 +3,19 @@
<Associations>
<Association>
<!-- Associate the FileSystem ObjectModel with the UXT DataFormats and the FileSystem Editor -->
<Filters>
<Filter Title="Universal Editor eXtension">
<FileNameFilters>
<FileNameFilter>*.uxt</FileNameFilter>
</FileNameFilters>
<MagicByteSequences>
<MagicByteSequence>
<MagicByte Type="String">Universal Editor extension file</MagicByte>
<MagicByte Type="HexString">00</MagicByte>
</MagicByteSequence>
</MagicByteSequences>
</Filter>
</Filters>
<ObjectModels>
<ObjectModel TypeName="UniversalEditor.ObjectModels.FileSystem.FileSystemObjectModel" />
</ObjectModels>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversalEditor.IO;
namespace UniversalEditor
{
@ -16,6 +17,102 @@ namespace UniversalEditor
}
private static List<Association> _associations = new List<Association>();
public static bool Register(Association assoc)
{
if (_associations.Contains(assoc)) return false;
_associations.Add(assoc);
return true;
}
public static bool Unregister(Association assoc)
{
if (!_associations.Contains(assoc)) return false;
_associations.Remove(assoc);
return true;
}
public static Association[] GetAllAssociations()
{
return _associations.ToArray();
}
public static Association[] FromObjectModelOrDataFormat(ObjectModelReference objectModel = null, DataFormatReference dataFormat = null)
{
Association[] _associations = Association.GetAllAssociations();
List<Association> associations = new List<Association>();
foreach (Association assoc in _associations)
{
if ((objectModel != null && assoc.ObjectModels.Contains(objectModel)) || (dataFormat != null && assoc.DataFormats.Contains(dataFormat)))
{
associations.Add(assoc);
}
}
return associations.ToArray();
}
public static Association[] FromAccessor(Accessor accessor = null, string fileNameFilter = null)
{
Association[] _associations = Association.GetAllAssociations();
List<Association> associations = new List<Association>();
Association[] assocs = _associations;
foreach (Association assoc in assocs)
{
foreach (DataFormatFilter filter in assoc.Filters)
{
if (accessor != null)
{
for (int i = 0; i < filter.MagicBytes.Count; i++)
{
byte?[] bytes = filter.MagicBytes[i];
if ((accessor.Position + bytes.Length) <= accessor.Length)
{
bool ret = true;
byte[] cmp = new byte[bytes.Length];
long offset = accessor.Position;
if (i < filter.MagicByteOffsets.Length)
{
if (filter.MagicByteOffsets[i] < 0)
{
accessor.Seek(filter.MagicByteOffsets[i], SeekOrigin.End);
}
else
{
accessor.Seek(filter.MagicByteOffsets[i], SeekOrigin.Begin);
}
}
accessor.Reader.Read(cmp, 0, cmp.Length);
accessor.Position = offset;
for (int j = 0; j < bytes.Length; j++)
{
if (bytes[j] == null) continue;
if (bytes[j] != cmp[j])
{
ret = false;
break;
}
}
if (ret)
{
associations.Add(assoc);
break;
}
}
}
}
if (fileNameFilter != null)
{
if (filter.FileNameFilters.Contains(fileNameFilter))
{
associations.Add(assoc);
break;
}
}
}
}
return associations.ToArray();
}
private string mvarTitle = String.Empty;
/// <summary>
/// The title of this <see cref="Association" />; for example, "JPEG images".

View File

@ -231,6 +231,11 @@ namespace UniversalEditor.Common
{
listProjectTemplates.Add(template);
}
foreach (Association assoc in mom.Associations)
{
Association.Register(assoc);
}
}
catch
{

View File

@ -812,6 +812,122 @@ namespace UniversalEditor.DataFormats.UEPackage
}
}
MarkupTagElement tagFilters = (tagAssociation.Elements["Filters"] as MarkupTagElement);
if (tagFilters != null)
{
foreach (MarkupElement elFilter in tagFilters.Elements)
{
MarkupTagElement tagFilter = (elFilter as MarkupTagElement);
if (tagFilter == null) continue;
if (tagFilter.FullName != "Filter") continue;
DataFormatFilter filter = new DataFormatFilter();
MarkupAttribute attTitle = tagFilter.Attributes["Title"];
if (attTitle != null)
{
filter.Title = attTitle.Value;
}
MarkupTagElement tagFileNameFilters = (tagFilter.Elements["FileNameFilters"] as MarkupTagElement);
if (tagFileNameFilters != null)
{
foreach (MarkupElement elFileNameFilter in tagFileNameFilters.Elements)
{
MarkupTagElement tagFileNameFilter = (elFileNameFilter as MarkupTagElement);
if (tagFileNameFilter == null) continue;
if (tagFileNameFilter.FullName != "FileNameFilter") continue;
filter.FileNameFilters.Add(tagFileNameFilter.Value);
}
}
MarkupTagElement tagMagicByteSequences = (tagFilter.Elements["MagicByteSequences"] as MarkupTagElement);
if (tagMagicByteSequences != null)
{
foreach (MarkupElement elMagicByteSequence in tagMagicByteSequences.Elements)
{
MarkupTagElement tagMagicByteSequence = (elMagicByteSequence as MarkupTagElement);
if (tagMagicByteSequence == null) continue;
if (tagMagicByteSequence.FullName != "MagicByteSequence") continue;
List<byte?> magicByteSequence = new List<byte?>();
foreach (MarkupElement elMagicByte in tagMagicByteSequence.Elements)
{
MarkupTagElement tagMagicByte = (elMagicByte as MarkupTagElement);
if (tagMagicByte == null) continue;
if (tagMagicByte.FullName != "MagicByte") continue;
MarkupAttribute attType = tagMagicByte.Attributes["Type"];
if (attType == null) continue;
switch (attType.Value.ToLower())
{
case "blank":
{
MarkupAttribute attLength = tagMagicByte.Attributes["Length"];
if (attLength == null) continue;
int iLength = 0;
if (!Int32.TryParse(attLength.Value, out iLength)) continue;
for (int i = 0; i < iLength; i++)
{
magicByteSequence.Add(null);
}
break;
}
case "string":
{
string value = tagMagicByte.Value;
for (int i = 0; i < value.Length; i++)
{
magicByteSequence.Add((byte)value[i]);
}
break;
}
case "byte":
{
string value = tagMagicByte.Value.ToLower();
byte realvalue = 0;
if (value.StartsWith("0x") || value.StartsWith("&h"))
{
value = value.Substring(2);
realvalue = Byte.Parse(value, System.Globalization.NumberStyles.HexNumber);
}
else
{
realvalue = Byte.Parse(value);
}
for (int i = 0; i < value.Length; i++)
{
magicByteSequence.Add(realvalue);
}
break;
}
case "hexstring":
{
string value = tagMagicByte.Value.ToLower();
byte realvalue = 0;
for (int i = 0; i < value.Length; i += 2)
{
string val = value.Substring(i, 2);
realvalue = Byte.Parse(value, System.Globalization.NumberStyles.HexNumber);
magicByteSequence.Add(realvalue);
}
break;
}
}
}
filter.MagicBytes.Add(magicByteSequence.ToArray());
}
}
association.Filters.Add(filter);
}
}
package.Associations.Add(association);
}
}