Esempio n. 1
0
        /// <summary>
        /// Deserializes a BIN archive.
        /// </summary>
        /// <param name="source">BIN archive as BinaryFormat.</param>
        /// <returns>The NodeContainerFormat.</returns>
        public NodeContainerFormat Convert(BinaryFormat source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (source.Stream.Length < 0x10)
            {
                throw new FormatException("Not a valid BIN file.");
            }

            source.Stream.Seek(0);
            var reader = new DataReader(source.Stream)
            {
                Endianness = _params.Endianness,
            };

            BinFileHeader header = reader.Read <BinFileHeader>();

            if (header.MagicNumber != 0x00077DF9)
            {
                throw new FormatException($"Unrecognized file magic number: {header.MagicNumber:X8}");
            }

            NodeContainerFormat result = new ();

            for (int i = 0; i < header.FileCount; i++)
            {
                string fileSubPath = string.Empty;
                string fileName    = $"{i + 1:0000}";
                if (_params.FileNames.Count > 0 && i < _params.FileNames.Count)
                {
                    string[] path = _params.FileNames[i].Split('/');
                    fileSubPath = string.Join('/', path[0..^ 1]);
Esempio n. 2
0
        /// <summary>
        /// Serializes a BIN archive.
        /// </summary>
        /// <param name="source">Collection of files as NodeContainerFormat.</param>
        /// <returns>The BinaryFormat.</returns>
        public BinaryFormat Convert(NodeContainerFormat source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (source.Root.Children.Count == 0)
            {
                throw new FormatException("No files selected.");
            }

            _params.Stream ??= DataStreamFactory.FromMemory();

            _params.Stream.Seek(0);
            var writer = new DataWriter(_params.Stream)
            {
                Endianness = _params.Endianness,
            };

            if (_params.BlockSize == 0)
            {
                _params.BlockSize = 0x800;
            }

            BinFileHeader header = new BinFileHeader
            {
                MagicNumber = 0x00077DF9,
                BlockSize   = _params.BlockSize,
                FileCount   = source.Root.Children.Count,
                Padding     = 0,
            };

            writer.WriteOfType(header);
            int headerSize = 0x10 + (header.FileCount * 0x10);

            writer.Stream.SetLength(headerSize);

            for (int i = 0; i < source.Root.Children.Count; i++)
            {
                Node node = source.Root.Children[i];

                writer.Stream.Seek(0, SeekOrigin.End);
                writer.WritePadding(0x00, header.BlockSize);
                long startBlock = writer.Stream.Position / header.BlockSize;

                writer.Stream.Seek(0x10 + (i * 0x10), SeekOrigin.Begin);
                writer.Write(startBlock);

                FileType type = node.Tags["Type"];
                switch (type)
                {
                case FileType.Empty:
                    writer.Write(0);     // size
                    writer.Write(0);     // inflated size
                    break;

                case FileType.Dummy:
                    writer.Write(0x70);       // size
                    writer.Write(0x835F837E); // inflated size
                    writer.Stream.Seek(0, SeekOrigin.End);
                    writer.Write(_dummy);
                    break;

                case FileType.Normal:
                    writer.Write((int)node.Stream.Length); // size
                    writer.Write(0);                       // inflated size
                    writer.Stream.Seek(0, SeekOrigin.End);
                    node.Stream.WriteTo(writer.Stream);
                    break;

                case FileType.Compressed:
                    writer.Write((int)node.Stream.Length);        // size
                    writer.Write((int)node.Tags["InflatedSize"]); // inflated size
                    writer.Stream.Seek(0, SeekOrigin.End);
                    node.Stream.WriteTo(writer.Stream);
                    break;

                case FileType.CompressedAlternateEndian:
                    var alternateEndianness = _params.Endianness == EndiannessMode.BigEndian ? EndiannessMode.LittleEndian : EndiannessMode.BigEndian;
                    writer.Write((int)node.Stream.Length);        // size
                    writer.Endianness = alternateEndianness;
                    writer.Write((int)node.Tags["InflatedSize"]); // inflated size
                    writer.Endianness = _params.Endianness;
                    writer.Stream.Seek(0, SeekOrigin.End);
                    node.Stream.WriteTo(writer.Stream);
                    break;

                default:
                    throw new FormatException($"Unsupported file type: {type}");
                }
            }

            return(new BinaryFormat(_params.Stream));
        }