/// <summary> /// Writes data to a reflexive, reallocating the original. /// </summary> /// <param name="entries">The entries to write.</param> /// <param name="oldCount">The old count.</param> /// <param name="oldAddress">The old address.</param> /// <param name="newCount">The number of entries to write.</param> /// <param name="layout">The layout of the data to write.</param> /// <param name="metaArea">The meta area of the cache file.</param> /// <param name="allocator">The cache file's meta allocator.</param> /// <param name="stream">The stream to manipulate.</param> /// <returns>The address of the new reflexive, or 0 if the entry list is empty and the reflexive was freed.</returns> public static uint WriteReflexive(IEnumerable<StructureValueCollection> entries, int oldCount, uint oldAddress, int newCount, StructureLayout layout, FileSegmentGroup metaArea, MetaAllocator allocator, IStream stream) { if (newCount == 0) { // Free the old reflexive and return if (oldCount > 0 && oldAddress != 0) allocator.Free(oldAddress, oldCount*layout.Size); return 0; } uint newAddress = oldAddress; if (newCount != oldCount) { // Reallocate the reflexive int oldSize = oldCount*layout.Size; int newSize = newCount*layout.Size; if (oldCount > 0 && oldAddress != 0) newAddress = allocator.Reallocate(oldAddress, oldSize, newSize, stream); else newAddress = allocator.Allocate(newSize, stream); } // Write the new values WriteReflexive(entries.Take(newCount), newAddress, layout, metaArea, stream); return newAddress; }
/// <summary> /// Loads a structure layout based upon an XML container's children. /// </summary> /// <param name="parentElement">The element containing the value elements to parse.</param> /// <param name="size">The size of the structure in bytes.</param> /// <returns>The structure layout that was loaded.</returns> public static StructureLayout LoadLayout(XElement parentElement, int size) { StructureLayout layout = new StructureLayout(size); foreach (XElement element in parentElement.Elements()) HandleElement(layout, element); return layout; }
public static void WriteStructure(StructureValueCollection values, StructureLayout layout, IWriter writer) { var structWriter = new StructureWriter(values, writer); layout.Accept(structWriter); if (layout.Size > 0) structWriter.SeekWriter(layout.Size); }
private IWriter _writer; // The stream to write to #endregion Fields #region Constructors private StructureWriter(StructureValueCollection values, StructureLayout layout, IWriter writer) { _writer = writer; _layout = layout; _baseOffset = writer.Position; _offset = _baseOffset; _collection = values; }
private IReader _reader; // The stream to read from #endregion Fields #region Constructors /// <summary> /// (private) Constructs a new StructureReader. /// </summary> /// <param name="reader">The IReader to read from.</param> /// <param name="layout">The structure layout to follow.</param> private StructureReader(IReader reader, StructureLayout layout) { _reader = reader; _layout = layout; _baseOffset = reader.Position; _offset = _baseOffset; _collection = new StructureValueCollection(); }
/// <summary> /// Reads a structure from a stream by following a predefined structure layout. /// </summary> /// <param name="reader">The IReader to read the structure from.</param> /// <param name="layout">The structure layout to follow.</param> /// <returns>A collection of the values that were read.</returns> /// <seealso cref="StructureLayout" /> public static StructureValueCollection ReadStructure(IReader reader, StructureLayout layout) { var structReader = new StructureReader(reader); layout.Accept(structReader); if (layout.Size > 0) structReader.SeekReader(layout.Size); return structReader._collection; }
public ThirdGenLanguage(StructureValueCollection values, FileSegmenter segmenter, FileSegmentGroup localeArea, BuildInformation buildInfo) { _pointerLayout = buildInfo.GetLayout("locale index table entry"); _encryptionKey = buildInfo.LocaleKey; _symbols = buildInfo.LocaleSymbols; _localeArea = localeArea; _sizeAlign = (_encryptionKey != null) ? AES.BlockSize : 1; Load(values, segmenter, localeArea); }
public ThirdGenLanguage(GameLanguage language, StructureValueCollection values, FileSegmenter segmenter, FileSegmentGroup localeArea, EngineDescription buildInfo) { Language = language; _pointerLayout = buildInfo.Layouts.GetLayout("locale index table entry"); _encryptionKey = buildInfo.LocaleKey; _sizeAlign = (_encryptionKey != null) ? AES.BlockSize : 1; Load(values, segmenter, localeArea); }
/// <summary> /// Reads an array of values from the stream and adds it to the value /// collection which is currently being built. /// </summary> /// <param name="name">The name to store the array under.</param> /// <param name="offset">The array's offset (in bytes) from the beginning of the structure.</param> /// <param name="count">The number of elements to read into the array.</param> /// <param name="entryLayout">The layout to follow for each entry in the array.</param> public void VisitArrayField(string name, int offset, int count, StructureLayout entryLayout) { var arrayValue = new StructureValueCollection[count]; for (int i = 0; i < count; i++) { _reader.SeekTo(_baseOffset + offset + i*entryLayout.Size); arrayValue[i] = ReadStructure(_reader, entryLayout); } _collection.SetArray(name, arrayValue); }
public void VisitArrayField(string name, int offset, int count, StructureLayout entryLayout) { if (!_collection.HasArray(name)) return; StructureValueCollection[] arrayValue = _collection.GetArray(name); for (int i = 0; i < count; i++) { _writer.SeekTo(_baseOffset + offset + i*entryLayout.Size); WriteStructure(arrayValue[i], entryLayout, _writer); } }
public MetaReader(IStreamManager streamManager, uint baseOffset, ICacheFile cache, BuildInformation buildInfo, FieldChangeSet ignore) { _streamManager = streamManager; BaseOffset = baseOffset; _cache = cache; _ignoredFields = ignore; // Load layouts _reflexiveLayout = buildInfo.GetLayout("reflexive"); _tagRefLayout = buildInfo.GetLayout("tag reference"); _dataRefLayout = buildInfo.GetLayout("data reference"); }
/// <summary> /// Writes data to a reflexive at a particular address. /// </summary> /// <param name="entries">The entries to write.</param> /// <param name="address">The address to write to.</param> /// <param name="layout">The layout of the data to write.</param> /// <param name="metaArea">The meta area of the cache file.</param> /// <param name="writer">The stream to write to.</param> public static void WriteReflexive(IEnumerable<StructureValueCollection> entries, uint address, StructureLayout layout, FileSegmentGroup metaArea, IWriter writer) { int offset = metaArea.PointerToOffset(address); int index = 0; foreach (StructureValueCollection entry in entries) { writer.SeekTo(offset + index*layout.Size); StructureWriter.WriteStructure(entry, layout, writer); index++; } }
/// <summary> /// Reads a structure from a stream by following a predefined structure layout. /// </summary> /// <param name="reader">The IReader to read the structure from.</param> /// <param name="layout">The structure layout to follow.</param> /// <returns>A collection of the values that were read.</returns> /// <seealso cref="StructureLayout" /> public static StructureValueCollection ReadStructure(IReader reader, StructureLayout layout) { var structReader = new StructureReader(reader); layout.Accept(structReader); if (layout.Size > 0) { structReader.SeekReader(layout.Size); } return(structReader._collection); }
/// <summary> /// Initializes a new instance of the <see cref="DataBlockBuilder" /> class. /// </summary> /// <param name="reader">The stream to read from.</param> /// <param name="tagLocation">The location of the tag to load data blocks for.</param> /// <param name="cacheFile">The cache file.</param> /// <param name="buildInfo">The build info for the cache file.</param> public DataBlockBuilder(IReader reader, SegmentPointer tagLocation, ICacheFile cacheFile, EngineDescription buildInfo) { _reader = reader; _tagLocation = tagLocation; _cacheFile = cacheFile; _tagRefLayout = buildInfo.Layouts.GetLayout("tag reference"); _reflexiveLayout = buildInfo.Layouts.GetLayout("reflexive"); _dataRefLayout = buildInfo.Layouts.GetLayout("data reference"); DataBlocks = new List<DataBlock>(); ReferencedTags = new HashSet<DatumIndex>(); ReferencedResources = new HashSet<DatumIndex>(); }
/// <summary> /// Save meta to the Blam Cache File /// </summary> public MetaWriter(IWriter writer, uint baseOffset, ICacheFile cache, BuildInformation buildInfo, SaveType type, FieldChangeSet changes) { _writer = writer; _baseOffset = baseOffset; _cache = cache; _type = type; _changes = changes; // Load layouts _reflexiveLayout = buildInfo.GetLayout("reflexive"); _tagRefLayout = buildInfo.GetLayout("tag reference"); _dataRefLayout = buildInfo.GetLayout("data reference"); }
public ThirdGenShaderStreamer(ICacheFile cacheFile, EngineDescription desc) { _cacheFile = cacheFile; if (desc.Layouts.HasLayout("pixel shader info")) _pixelShaderInfoLayout = desc.Layouts.GetLayout("pixel shader info"); if (desc.Layouts.HasLayout("vertex shader info")) _vertexShaderInfoLayout = desc.Layouts.GetLayout("vertex shader info"); if (desc.Layouts.HasLayout("shader debug info")) _debugInfoLayout = desc.Layouts.GetLayout("shader debug info"); if (desc.Layouts.HasLayout("updb pointer")) _updbPointerLayout = desc.Layouts.GetLayout("updb pointer"); if (desc.Layouts.HasLayout("code info")) _codeInfoLayout = desc.Layouts.GetLayout("code info"); }
public void VisitArrayField(string name, int offset, int count, StructureLayout entryLayout) { if (!_collection.HasArray(name)) { return; } StructureValueCollection[] arrayValue = _collection.GetArray(name); for (int i = 0; i < count; i++) { _writer.SeekTo(_baseOffset + offset + i * entryLayout.Size); WriteStructure(arrayValue[i], entryLayout, _writer); } }
/// <summary> /// Save meta to the Blam Cache File /// </summary> public MetaWriter(IWriter writer, uint baseOffset, ICacheFile cache, EngineDescription buildInfo, SaveType type, FieldChangeSet changes, Trie stringIdTrie) { _writer = writer; _baseOffset = baseOffset; _cache = cache; _type = type; _changes = changes; _stringIdTrie = stringIdTrie; // Load layouts _reflexiveLayout = buildInfo.Layouts.GetLayout("reflexive"); _tagRefLayout = buildInfo.Layouts.GetLayout("tag reference"); _dataRefLayout = buildInfo.Layouts.GetLayout("data reference"); }
public static StructureValueCollection[] ReadReflexive(IReader reader, int count, uint address, StructureLayout entryLayout, FileSegmentGroup metaArea) { if (entryLayout.Size == 0) throw new ArgumentException("The entry layout must have a size associated with it."); // Handle null pointers if (count <= 0 || !metaArea.ContainsPointer(address)) return new StructureValueCollection[0]; // Convert the address to an offset and seek to it int offset = metaArea.PointerToOffset(address); reader.SeekTo(offset); // Read the entries StructureValueCollection[] result = new StructureValueCollection[count]; for (int i = 0; i < count; i++) result[i] = StructureReader.ReadStructure(reader, entryLayout); return result; }
/// <summary> /// Adds a layout to the collection, associating it with a certain name. /// </summary> /// <param name="name">The name to associate the layout with.</param> /// <param name="layout">The StructureLayout to add.</param> public void AddLayout(string name, StructureLayout layout) { _layouts[name] = layout; }
private bool FindLanguageTable(out ITag tag, out StructureLayout layout) { tag = null; layout = null; if (_tags == null) return false; // Check for a PATG tag, and if one isn't found, then use MATG if (_buildInfo.Layouts.HasLayout("patg")) { tag = _tags.FindTagByClass("patg"); layout = _buildInfo.Layouts.GetLayout("patg"); } if (tag == null) { tag = _tags.FindTagByClass("matg"); layout = _buildInfo.Layouts.GetLayout("matg"); } return (tag != null && layout != null); }
/// <summary> /// Parses an XML element representing an raw byte array and adds the /// field information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private static void HandleRawElement(StructureLayout layout, XElement element, string name, int offset) { int size = XMLUtil.GetNumericAttribute(element, "size"); layout.AddRawField(name, offset, size); }
private ExpressionTable LoadScriptExpressions(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringTableReader stringReader, StructureLayout entryLayout) { int exprCount = (int)values.GetInteger("number of script expressions"); if (exprCount == 0) return new ExpressionTable(); ScriptExpressionsLocation = SegmentPointer.FromPointer(values.GetInteger("script expression table address"), metaArea); ExpressionTable result = new ExpressionTable(); reader.SeekTo(ScriptExpressionsLocation.AsOffset()); for (int i = 0; i < exprCount; i++) { StructureValueCollection exprValues = StructureReader.ReadStructure(reader, entryLayout); result.AddExpression(new ThirdGenExpression(exprValues, (ushort)i, stringReader)); } foreach (IExpression expr in result) { // FIXME: hax if (expr != null) ((ThirdGenExpression)expr).ResolveReferences(result); } return result; }
/// <summary> /// Parses an XML element representing a basic structure field and adds /// the field information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private static void HandleBasicElement(StructureLayout layout, XElement element, string name, int offset) { StructureValueType type = IdentifyValueType(element.Name.LocalName); layout.AddBasicField(name, type, offset); }
public ThirdGenMultilingualStringList(IReader reader, ITag tag, EngineDescription buildInfo) { Tag = tag; _layout = buildInfo.Layouts.GetLayout("unic"); Load(reader); }
/// <summary> /// Writes data to a reflexive, reallocating the original. /// </summary> /// <param name="entries">The entries to write.</param> /// <param name="oldCount">The old count.</param> /// <param name="oldAddress">The old address.</param> /// <param name="layout">The layout of the data to write.</param> /// <param name="metaArea">The meta area of the cache file.</param> /// <param name="allocator">The cache file's meta allocator.</param> /// <param name="stream">The stream to manipulate.</param> /// <returns>The address of the new reflexive, or 0 if the entry list is empty and the reflexive was freed.</returns> public static uint WriteReflexive(ICollection<StructureValueCollection> entries, int oldCount, uint oldAddress, StructureLayout layout, FileSegmentGroup metaArea, MetaAllocator allocator, IStream stream) { return WriteReflexive(entries, oldCount, oldAddress, entries.Count, layout, metaArea, allocator, stream); }
private List<IGlobalObject> LoadScriptObjects(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, StructureLayout entryLayout) { int objectsCount = (int)values.GetInteger("number of script objects"); if (objectsCount == 0) return new List<IGlobalObject>(); ScriptObjectsLocation = SegmentPointer.FromPointer(values.GetInteger("script object table address"), metaArea); List<IGlobalObject> result = new List<IGlobalObject>(); reader.SeekTo(ScriptObjectsLocation.AsOffset()); for (int i = 0; i < objectsCount; i++) { StructureValueCollection objValues = StructureReader.ReadStructure(reader, entryLayout); result.Add(new ThirdGenGlobalObject(objValues, stringIDs)); } return result; }
private List<IGlobal> LoadScriptGlobals(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, ExpressionTable expressions, StructureLayout entryLayout) { int globalsCount = (int)values.GetInteger("number of script globals"); if (globalsCount == 0) return new List<IGlobal>(); ScriptGlobalsLocation = SegmentPointer.FromPointer(values.GetInteger("script global table address"), metaArea); List<IGlobal> result = new List<IGlobal>(); reader.SeekTo(ScriptGlobalsLocation.AsOffset()); for (int i = 0; i < globalsCount; i++) { StructureValueCollection globalValues = StructureReader.ReadStructure(reader, entryLayout); result.Add(new ThirdGenGlobal(globalValues, expressions)); } return result; }
/// <summary> /// Parses an XML element and adds the field that it represents to a /// structure layout. /// </summary> /// <param name="layout">The layout to add the parsed field to.</param> /// <param name="element">The element to parse.</param> private static void HandleElement(StructureLayout layout, XElement element) { // Every structure field at least has a name and an offset string name = XMLUtil.GetStringAttribute(element, "name"); int offset = XMLUtil.GetNumericAttribute(element, "offset"); if (IsArrayElement(element)) HandleArrayElement(layout, element, name, offset); else if (IsRawElement(element)) HandleRawElement(layout, element, name, offset); else HandleBasicElement(layout, element, name, offset); }
/// <summary> /// Parses an XML element representing an array field and adds the field /// information to a structure layout. /// </summary> /// <param name="layout">The structure layout to add the field's information to.</param> /// <param name="element">The XML element to parse.</param> /// <param name="name">The name of the field to add.</param> /// <param name="offset">The offset (in bytes) of the field from the beginning of the structure.</param> private static void HandleArrayElement(StructureLayout layout, XElement element, string name, int offset) { int count = XMLUtil.GetNumericAttribute(element, "count"); int entrySize = XMLUtil.GetNumericAttribute(element, "entrySize"); layout.AddArrayField(name, offset, count, LoadLayout(element, entrySize)); }
public void AddLayout(string name, StructureLayout layout) { _layouts.AddLayout(name, layout); }
private List<IScript> LoadScripts(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, ExpressionTable expressions, StructureLayout entryLayout, BuildInformation buildInfo) { int scriptCount = (int)values.GetInteger("number of scripts"); if (scriptCount == 0) return new List<IScript>(); ScriptsLocation = SegmentPointer.FromPointer(values.GetInteger("script table address"), metaArea); // Read all of the script entries first, then go back and create the objects // ThirdGenScript reads parameters from its constructor - this may or may not need cleaning up to make this more obvious reader.SeekTo(ScriptsLocation.AsOffset()); List<StructureValueCollection> scriptData = new List<StructureValueCollection>(); for (int i = 0; i < scriptCount; i++) scriptData.Add(StructureReader.ReadStructure(reader, entryLayout)); List<IScript> result = new List<IScript>(); foreach (StructureValueCollection scriptValues in scriptData) result.Add(new ThirdGenScript(reader, scriptValues, metaArea, stringIDs, expressions, buildInfo)); return result; }