示例#1
0
        public bool OpenAndRead()
        {
            bool Result = false;

            // Open the archive for reading.
            if (OpenArchive(false) == false)
            {
                // Failed to open the archive.
                return(false);
            }

            // Make sure the file is large enough to have the header.
            if (this.fileStream.Length < ArchiveHeader.kSizeOf)
            {
                // File is too small to be a valid archive.
                goto Cleanup;
            }

            // Read the archive header.
            ArchiveHeader header = new ArchiveHeader();

            header.Magic         = reader.ReadInt32();
            header.Version       = reader.ReadInt16();
            header.NumberOfFiles = reader.ReadInt16();

            // Verify the header magic.
            if (header.Magic != ArchiveHeader.kHeaderMagic1)
            {
                // Check if the magic is in big endian.
                if (EndianUtilities.ByteFlip32(header.Magic) == ArchiveHeader.kHeaderMagic1)
                {
                    // Set the endianness for future IO operations.
                    this.Endian        = Endianness.Big;
                    this.reader.Endian = Endianness.Big;

                    // Correct the header values we already read.
                    header.Magic         = EndianUtilities.ByteFlip32(header.Magic);
                    header.Version       = EndianUtilities.ByteFlip16(header.Version);
                    header.NumberOfFiles = EndianUtilities.ByteFlip16(header.NumberOfFiles);
                }
                else
                {
                    // archive header has invalid magic.
                    goto Cleanup;
                }
            }

            // Verify the file version.
            if (header.Version != ArchiveHeader.kVersion)
            {
                // archive is invalid version.
                goto Cleanup;
            }

            // Loop for the number of files and read each file entry.
            for (int i = 0; i < header.NumberOfFiles; i++)
            {
                ArchiveFileEntry fileEntry = new ArchiveFileEntry();

                // Save the current position and read the file name.
                long offset = this.reader.BaseStream.Position;
                fileEntry.FileName = this.reader.ReadNullTerminatedString();

                // Advance to the end of the file name and read the rest of the file entry structure.
                this.reader.BaseStream.Position = offset + 64;
                int fileType = this.reader.ReadInt32();
                fileEntry.CompressedSize   = this.reader.ReadInt32();
                fileEntry.DecompressedSize = this.reader.ReadInt32();
                fileEntry.DataOffset       = this.reader.ReadInt32();

                // Create a unique file id for the file.
                fileEntry.FileId = this.nextFileId++;

                // Check if the type of file is known.
                if (GameResource.KnownResourceTypes.ContainsKey(fileType) == true)
                {
                    // Set the file type and add it as a file extension to the file name.
                    fileEntry.FileType  = GameResource.KnownResourceTypes[fileType];
                    fileEntry.FileName += "." + fileEntry.FileType.ToString();
                }
                else
                {
                    fileEntry.FileType = ResourceType.Unknown;
                }

                // Calculate the unique id for the file and add it to the file loopup dictionary.
                this.fileEntryLookupDictionary.Add(fileEntry.FileId, this.fileEntries.Count);

                // Add the file entry to the list of files.
                this.fileEntries.Add(fileEntry);
            }

            // Successfully parsed the archive.
            Result = true;

Cleanup:
            // Close the archive.
            CloseArchive();

            // Return the result.
            return(Result);
        }