using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; namespace Oni { internal abstract class Importer { private readonly ImporterFile file; private Dictionary dependencies; public Importer() { this.file = new ImporterFile(); } protected Importer(long templateChecksum) { this.file = new ImporterFile(templateChecksum); } public ImporterFile ImporterFile => file; public virtual void Import(string filePath, string outputDirPath) { } public virtual void BeginImport() { file.BeginImport(); dependencies = new Dictionary(); } public BinaryWriter RawWriter => file.RawWriter; public void AddDependency(string filePath, TemplateTag type) { if (!dependencies.ContainsKey(filePath)) dependencies[filePath] = new ImporterTask(filePath, type); } public ICollection Dependencies { get { if (dependencies == null) return new ImporterTask[0]; return dependencies.Values; } } public ImporterDescriptor CreateInstance(TemplateTag tag, string name = null) => file.CreateInstance(tag, name); public int WriteRawPart(byte[] data) => file.WriteRawPart(data); public int WriteRawPart(string text) => file.WriteRawPart(text); public void Write(string outputDirPath) => file.Write(outputDirPath); protected static string MakeInstanceName(TemplateTag tag, string name) { string tagName = tag.ToString(); if (!name.StartsWith(tagName, StringComparison.Ordinal)) name = tagName + name; return name; } public static string EncodeFileName(string name, Dictionary fileNames = null) { foreach (char c in Path.GetInvalidFileNameChars()) name = name.Replace(c.ToString(), string.Format(CultureInfo.InvariantCulture, "%{0:X2}", (int)c)); if (fileNames != null) { string existingName; while (fileNames.TryGetValue(name, out existingName)) { int i = 0; if (name.Length > 4) i = 4; while (i < name.Length && char.ToLowerInvariant(name[i]) != char.ToLowerInvariant(existingName[i])) i++; name = name.Substring(0, i) + string.Format(CultureInfo.InvariantCulture, "%{0:X2}", (int)name[i]) + name.Substring(i + 1); } fileNames[name] = name; } return name; } public static string DecodeFileName(string fileName) { fileName = Path.GetFileNameWithoutExtension(fileName); var buffer = new StringBuilder(); for (int i, startIndex = 0; startIndex != -1; startIndex = i) { i = fileName.IndexOf('%', startIndex); if (i == -1) { buffer.Append(fileName, startIndex, fileName.Length - startIndex); } else { buffer.Append(fileName, startIndex, i - startIndex); buffer.Append((char)Int32.Parse(fileName.Substring(i + 1, 2), NumberStyles.HexNumber)); i += 3; } } return buffer.ToString(); } } }