def _writeDir(self, handle, directory, info): for obj in directory.children: info.currentNode += 1 if obj.isDirectory(): handle.write(struct.pack('>III', 0x01000000 | info.stringTableBuilder.add(obj.name), info.currentRecursionLevel, 0)) lastChildFieldPos = handle.tell() - 4 info.currentRecursionLevel += 1 self._writeDir(handle, obj, info) info.currentRecursionLevel -= 1 # write lastChild field dirEndPos = handle.tell() handle.seek(lastChildFieldPos) handle.write(struct.pack('>I', info.currentNode)) handle.seek(dirEndPos) elif obj.isFile(): handle.write(struct.pack('>III', info.stringTableBuilder.add(obj.name), info.nextDataOffset, len(obj.data))) info.nextDataOffset = alignUp(info.nextDataOffset + len(obj.data), 0x20)
def _writeDir(self, handle, directory, info): for obj in directory.children: info.currentNode += 1 if obj.isDirectory(): handle.write( struct.pack( '>III', 0x01000000 | info.stringTableBuilder.add(obj.name), info.currentRecursionLevel, 0)) lastChildFieldPos = handle.tell() - 4 info.currentRecursionLevel += 1 self._writeDir(handle, obj, info) info.currentRecursionLevel -= 1 # write lastChild field dirEndPos = handle.tell() handle.seek(lastChildFieldPos) handle.write(struct.pack('>I', info.currentNode)) handle.seek(dirEndPos) elif obj.isFile(): handle.write( struct.pack('>III', info.stringTableBuilder.add(obj.name), info.nextDataOffset, len(obj.data))) info.nextDataOffset = alignUp( info.nextDataOffset + len(obj.data), 0x20)
def _writeNodeData(self, handle, node): if node.isDirectory(): for obj in node.children: self._writeNodeData(handle, obj) elif node.isFile(): size = len(node.data) handle.write(node.data) handle.write("\0" * (alignUp(size, 0x20) - size))
def pack(self, handle=None): returnData = False if handle is None: handle = cStringIO.StringIO() returnData = True info = WiiArchiveU8.WriteInfo() # first off, before we do anything else, create the string table info.stringTableBuilder = WiiStringTableBuilder() self._addNodeToStringTable(self.root, info.stringTableBuilder) stringTable = info.stringTableBuilder.data # calculate various fun offsets/sizes nodeCount = self._countNode(self.root) info.startPos = handle.tell() fstStart = 0x20 nodeDataSize = nodeCount * 12 stringTableSize = len(stringTable) fstSize = nodeDataSize + stringTableSize dataOffset = alignUp(fstStart + fstSize, 0x20) # now write the header handle.write("U\xAA8\x2D") handle.write(struct.pack('>III', fstStart, fstSize, dataOffset)) handle.write("\0"*16) # write root node info.currentNode = 1 info.currentRecursionLevel = 0 info.nextDataOffset = dataOffset handle.write(struct.pack('>III', 0x01000000 | info.stringTableBuilder.add(''), 0, nodeCount)) self._writeDir(handle, self.root, info) # write string table handle.write(stringTable) # write data (after padding) handle.write("\0" * (dataOffset - fstSize - fstStart)) self._writeNodeData(handle, self.root) # looks like we are finally done if returnData: data = handle.getvalue() handle.close() return data
def pack(self, handle=None): returnData = False if handle is None: handle = cStringIO.StringIO() returnData = True info = WiiArchiveU8.WriteInfo() # first off, before we do anything else, create the string table info.stringTableBuilder = WiiStringTableBuilder() self._addNodeToStringTable(self.root, info.stringTableBuilder) stringTable = info.stringTableBuilder.data # calculate various fun offsets/sizes nodeCount = self._countNode(self.root) info.startPos = handle.tell() fstStart = 0x20 nodeDataSize = nodeCount * 12 stringTableSize = len(stringTable) fstSize = nodeDataSize + stringTableSize dataOffset = alignUp(fstStart + fstSize, 0x20) # now write the header handle.write("U\xAA8\x2D") handle.write(struct.pack('>III', fstStart, fstSize, dataOffset)) handle.write("\0" * 16) # write root node info.currentNode = 1 info.currentRecursionLevel = 0 info.nextDataOffset = dataOffset handle.write( struct.pack('>III', 0x01000000 | info.stringTableBuilder.add(''), 0, nodeCount)) self._writeDir(handle, self.root, info) # write string table handle.write(stringTable) # write data (after padding) handle.write("\0" * (dataOffset - fstSize - fstStart)) self._writeNodeData(handle, self.root) # looks like we are finally done if returnData: data = handle.getvalue() handle.close() return data