Esempio n. 1
0
        public static long CalculateRomFsSize(IList <IArchiveFileInfo> files, UPath rootDirectory)
        {
            var rootNode = RomFsDirectoryNode.Parse(files, rootDirectory);

            long totalSize = BlockSize_;

            // Calculate meta size
            totalSize += GetHashTableEntryCount(rootNode.DirectoryCount) * 4;
            totalSize += GetHashTableEntryCount(files.Count) * 4;
            totalSize += rootNode.SizeInBytes;
            totalSize += files.Sum(x => MetaData.FileEntry.Size + ((Encoding.Unicode.GetByteCount(x.FilePath.GetName()) + 3) & ~3));

            // Calculate file size
            totalSize  = (totalSize + 0xF) & ~0xF;
            totalSize += files.Sum(x => (x.FileSize + 0xF) & ~0xF);
            totalSize  = (totalSize + BlockSize_ - 1) & ~(BlockSize_ - 1);

            // Calculate hash level sizes
            var levelSize = totalSize - BlockSize_;

            for (var i = 0; i < 2; i++)
            {
                var currentLevelSize = levelSize / BlockSize_ * 0x20;
                currentLevelSize = (currentLevelSize + BlockSize_ - 1) & ~(BlockSize_ - 1);

                totalSize += currentLevelSize;

                levelSize = currentLevelSize;
            }

            return(totalSize);
        }
Esempio n. 2
0
        public static (long, long) Build(Stream input, IList <IArchiveFileInfo> files, UPath rootDirectory)
        {
            // Parse files into file tree
            var rootNode = RomFsDirectoryNode.Parse(files, rootDirectory);

            // Create MetaData Tree
            var metaData = new MetaData
            {
                DirMetaOffset = rootNode.Directories.Count <= 0 ? UnusedEntry_ : 0x18
            };

            metaData.Dirs.Add(new MetaData.DirEntry
            {
                MetaOffset          = 0,
                ParentOffset        = 0,
                NextSiblingOffset   = UnusedEntry_,
                FirstChildOffset    = rootNode.Directories.Count <= 0 ? UnusedEntry_ : 0x18,
                FirstFileOffset     = 0,
                NextDirInSameBucket = UnusedEntry_,
                Hash = CalculatePathHash(0, Encoding.Unicode.GetBytes(string.Empty)),
                Name = string.Empty
            });

            PopulateMetaData(metaData, rootNode, metaData.Dirs[0]);

            // Creating directory hash buckets
            metaData.DirHashTable = Enumerable.Repeat(0xFFFFFFFF, GetHashTableEntryCount(metaData.Dirs.Count)).ToArray();
            PopulateDirHashTable(metaData.Dirs, metaData.DirHashTable);

            // Creating file hash buckets
            metaData.FileHashTable = Enumerable.Repeat(0xFFFFFFFF, GetHashTableEntryCount(metaData.Files.Count)).ToArray();
            PopulateFileHashTable(metaData.Files, metaData.FileHashTable);

            // Write RomFs
            var romFsSizes = WriteRomFs(input, metaData);

            return(romFsSizes);
        }