public override void OnRebuild(VoidPtr address, int length, bool force) { _currentlyBuilding = this; _builder.Write(this, address, length); _currentlyBuilding = null; _builder = null; }
public override int OnCalculateSize(bool force) { _currentlyBuilding = this; int size = (_builder = new SakuraiArchiveBuilder(this)).GetSize(); _currentlyBuilding = null; return(size); }
private void Setup(SakuraiArchiveNode node, SakuraiEntryNode parent, int offset, string name) { _name = name; _root = node; _offset = offset; _parent = parent; if (_initSize <= 0) { _initSize = _root.GetSize(_offset); } _root.EntryCache[_offset] = this; if ((_externalEntry = _root.TryGetExternal(offset)) != null) { _externalEntry.References.Add(this); } }
public unsafe void Write(SakuraiArchiveNode node, VoidPtr address, int length) { _baseAddress = address + 0x20; _currentAddress = _baseAddress; //Write header SakuraiArchiveHeader *hdr = (SakuraiArchiveHeader *)address; hdr->_sectionCount = _sectionCount; hdr->_externalSubRoutineCount = _referenceCount; hdr->_lookupEntryCount = _lookupManager.Count; hdr->_fileSize = length; hdr->_pad1 = hdr->_pad2 = hdr->_pad3 = 0; List <int> _sectionOffsets = new List <int>(); //Write section data foreach (TableEntryNode section in node.SectionList) { SakuraiEntryNode entry = section; //If this section is referenced from an entry, //write that entry instead if (section.References.Count > 0) { entry = section.References[0]; } _sectionOffsets.Add(entry.Write(_currentAddress)); _currentAddress += entry.TotalSize; } //Write lookup values hdr->_lookupOffset = (int)_currentAddress - (int)_baseAddress; _lookupManager.Write(ref _currentAddress); //These can only be accessed after the lookup offset and count //have been written to the header. sStringEntry *sectionAddr = hdr->Sections; sStringEntry *refAddr = hdr->ExternalSubRoutines; }
/// <summary> /// Don't call this outside of the Parse functions. /// This is here to eliminate redundant code. /// </summary> private static T CommonInit <T>(SakuraiArchiveNode root, SakuraiEntryNode parent, VoidPtr addr, params object[] parameters) where T : SakuraiEntryNode { int offset = root.Offset(addr); bool attributes = parameters.Contains("Attributes"); if (offset <= 0 && !attributes) { return(null); } if (attributes) { parameters = new object[0]; } T n = Activator.CreateInstance(typeof(T), parameters) as T; n.Setup(root, parent, offset); n.OnParse(addr); return(n); }
public SakuraiArchiveBuilder(SakuraiArchiveNode node) { _rootNode = node; }
private void Setup(SakuraiArchiveNode node, SakuraiEntryNode parent, int offset) { Setup(node, parent, offset, null); }
public void ParseSelf(SakuraiArchiveNode root, SakuraiEntryNode parent, VoidPtr address) { Setup(root, parent, Offset(address)); OnParse(address); }
public void ParseSelf(SakuraiArchiveNode root, SakuraiEntryNode parent, int offset) { Setup(root, parent, offset); OnParse(Address(offset)); }
/// <summary> /// Use this to parse a node of a specific type at the given address. /// This will automatically add the node to the entry cache, get its size, /// set its offset value, and attach its external entry if it has one. /// Be sure to send the proper constructor parameters for the given type /// as well, or an error will be thrown. /// </summary> public static T Parse <T>(SakuraiArchiveNode root, SakuraiEntryNode parent, VoidPtr address, params object[] parameters) where T : SakuraiEntryNode { return(CommonInit <T>(root, parent, address, parameters)); }