/// <summary>
        /// Loads or creates a new instance of the user-defined program information table.
        /// </summary>
        /// <param name="localFilePath">Absolute path to a file storing the user-specified program information.</param>
        /// <returns>If the file path is valid, the returned table contains the user's locally defined program information. Otherwise, a new,
        /// empty table is returned.</returns>
        public static IProgramInformationTable Initialize(string localFilePath)
        {
            UserSpecifiedProgramInformationTable table = null;

            try
            {
                using (var fileStream = StreamUtilities.OpenFileStream(localFilePath))
                {
                    if (fileStream != null)
                    {
                        var serializer = new System.Xml.Serialization.XmlSerializer(typeof(UserSpecifiedProgramInformationTable));
                        table = serializer.Deserialize(fileStream) as UserSpecifiedProgramInformationTable;
                    }
                }
            }
            catch (Exception)
            {
                // TODO Silently fail to load user-defined ROMs for now. Eventually need to report back to user once this is supported.
                table = null;
            }
            if (table == null)
            {
                // Return an empty instance, which can be harmlessly merged into the master in-memory database.
                table = new UserSpecifiedProgramInformationTable();
            }
            return(table);
        }
Exemplo n.º 2
0
            protected override int GetMemo(string filePath, object data)
            {
                CalledGetMemo = true;
                var stream    = StreamUtilities.OpenFileStream(filePath, StorageAccess);
                var memoValue = ComputeMemoValue(stream);

                return(memoValue);
            }
Exemplo n.º 3
0
        public void FileMemo_AddValidMemoThenAddInvalidMemorForSamePath_MemoIsRemoved()
        {
            var testFileName = "~/add-valid-then-add-invalid-dat";
            int memo         = 42; // just use a bogus memo
            var memos        = new TestFileMemo();

            using (StreamUtilities.OpenFileStream(testFileName, memos.Storage))
            {
                Assert.True(memos.AddMemo(testFileName, memo));
                Assert.False(memos.AddMemo(testFileName, TestFileMemo.InitialMemoValue));
            }
        }
Exemplo n.º 4
0
        public void StreamUtilitiesWithTestStorage_CallOpenFileStream_ReturnsValidStream()
        {
            var storage  = new TestStorageAccess();
            var testPath = @"~/open_create_path.dat";

            using (var stream = StreamUtilities.OpenFileStream(testPath, storage))
            {
                Assert.True(StreamUtilities.FileExists(testPath, storage));
                Assert.NotNull(stream);
            }
            Assert.False(StreamUtilities.FileExists(testPath, storage));
        }
Exemplo n.º 5
0
        public void FileMemo_AddMemoOfFileThatIsThenDeletedAndAddedAgain_MemoAddedThenRemoved()
        {
            var testFileName = "~/delete-this-test-file.dat";
            int memo         = 42; // just use a bogus memo
            var memos        = new TestFileMemo();

            using (StreamUtilities.OpenFileStream(testFileName, memos.Storage))
            {
                Assert.True(memos.AddMemo(testFileName, memo));
            }

            Assert.False(memos.AddMemo(testFileName, memo));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Given an absolute path to a ROM file, attempt to determine the format of the ROM.
        /// </summary>
        /// <param name="filePath">Absolute path to the potential ROM file.</param>
        /// <returns>The format of the file. If it does not appear to be a ROM, then <c>RomFormat.None</c> is returned.</returns>
        internal static RomFormat CheckFormat(string filePath)
        {
            var format = CheckMemo(filePath);

            if (format == RomFormat.None)
            {
                using (var file = StreamUtilities.OpenFileStream(filePath))
                {
                    format = CheckFormat(file);
                }
            }
            return(format);
        }
Exemplo n.º 7
0
        public void Crc32_OfFileWithAlternateFirstByte_IsCorrect()
        {
            // We use a privately defined type for the storage access to check initialize and remove, which will
            // hopefully guarantee that we use the expected storage during this test.
            var storageAcces = new Crc32TestStorageAccess();
            var testFileName = "~/Crc32_OfFileWithAlternateFirstByte_IsCorrect.dat";

            StreamUtilities.Initialize(storageAcces);
            using (var fileStream = StreamUtilities.OpenFileStream(testFileName))
            {
                var testData = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
                fileStream.Write(testData, 0, testData.Length);
                var crc32 = Crc32.OfFile(testFileName, replaceFirstByte: true, alternateFirstByte: 0x42);
                Assert.Equal(0x066F5C62u, crc32);
            }
        }
Exemplo n.º 8
0
        public void Crc24_OfFile_IsCorrect()
        {
            // We use a privately defined type for the storage access to check initialize and remove, which will
            // hopefully guarantee that we use the expected storage during this test.
            var storageAcces = new Crc24TestStorageAccess();

            StreamUtilities.Initialize(storageAcces);
            var testFileName = "~/Crc24_OfFile_IsCorrect.dat";

            using (var fileStream = StreamUtilities.OpenFileStream(testFileName))
            {
                var testData = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
                fileStream.Write(testData, 0, testData.Length);
                var crc24 = Crc24.OfFile(testFileName);
                Assert.Equal(0x004F40DAu, crc24);
            }
        }
Exemplo n.º 9
0
        public void Crc32_OfFileWithIgnoreRange_IsCorrect()
        {
            // We use a privately defined type for the storage access to check initialize and remove, which will
            // hopefully guarantee that we use the expected storage during this test.
            var storageAcces = new Crc32TestStorageAccess();

            StreamUtilities.Initialize(storageAcces);
            var testFileName = "~/Crc32_OfFileWithIgnoreRange_IsCorrect.dat";

            using (var fileStream = StreamUtilities.OpenFileStream(testFileName))
            {
                var testData = new byte[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
                fileStream.Write(testData, 0, testData.Length);
                var ignoreRanges = new[] { new Range <int>(1, 2) };
                var crc32        = Crc32.OfFile(testFileName, ignoreRanges);
                Assert.Equal(0xB4DA8CCAu, crc32);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Locates the first data block of the requested type in the ROM.
        /// </summary>
        /// <typeparam name="T">The type of LUIGI block to locate.</typeparam>
        /// <returns>The data block, or <c>null</c> if no block of the requested type is in the ROM.</returns>
        internal T LocateDataBlock <T>() where T : LuigiDataBlock
        {
            var dataBlock = default(T);

            if (StreamUtilities.FileExists(RomPath))
            {
                using (var file = StreamUtilities.OpenFileStream(RomPath))
                {
                    if (file != null)
                    {
                        if (file.Length > 0)
                        {
                            var desiredBlockType = LuigiDataBlock.GetBlockType <T>();
                            var luigiHeader      = LuigiFileHeader.Inflate(file);
                            var bytesRead        = luigiHeader.DeserializeByteCount;

                            // Start looking for desired block immediately after header.
                            var block = LuigiDataBlock.Inflate(file);
                            bytesRead += block.DeserializeByteCount;
                            if (StopIfScrambleKeyBlockFound(desiredBlockType, block.Type))
                            {
                                // Stop looking. If we hit the scramble key, there's nothing more to be looked at.
                                bytesRead = (int)file.Length;
                            }
                            while ((bytesRead < file.Length) && (block.Type != desiredBlockType) && (block.Type != LuigiDataBlockType.EndOfFile))
                            {
                                block      = LuigiDataBlock.Inflate(file);
                                bytesRead += block.DeserializeByteCount;
                                if (StopIfScrambleKeyBlockFound(desiredBlockType, block.Type))
                                {
                                    break;
                                }
                            }
                            if (block.Type == desiredBlockType)
                            {
                                dataBlock = block as T;
                            }
                        }
                    }
                }
            }
            return(dataBlock);
        }
Exemplo n.º 11
0
        public void StreamUtilitiesWithTestStorage_CallLastWriteTimeUtcAfterWritingToStream_ReturnsReasonableLastWriteTime()
        {
            var storage  = new TestStorageAccess();
            var testPath = @"~/test_file_to_write.dat";

            using (var stream = StreamUtilities.OpenFileStream(testPath, storage))
            {
                var beforeWrite     = DateTime.UtcNow;
                int numBytesToWrite = 128;
                for (byte i = 0; i < numBytesToWrite; ++i)
                {
                    stream.WriteByte(i);
                }
                Assert.Equal(numBytesToWrite, StreamUtilities.FileSize(testPath, storage));
                var afterWrite = DateTime.UtcNow;
                var lastWrite  = StreamUtilities.LastFileWriteTimeUtc(testPath, storage);
                Assert.True(lastWrite >= beforeWrite);
                Assert.True(lastWrite <= afterWrite);
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Given an absolute path to a ROM file, attempt to determine the format of the ROM.
        /// </summary>
        /// <param name="filePath">Absolute path to the potential ROM file.</param>
        /// <returns>The format of the file. If it does not appear to be a ROM, then <c>RomFormat.None</c> is returned.</returns>
        internal static RomFormat CheckFormat(string filePath)
        {
            var format = CheckMemo(filePath);

            if (format == RomFormat.None)
            {
                using (System.IO.Stream file = StreamUtilities.OpenFileStream(filePath))
                {
                    var fileSizeCheck = file != null;
                    if (fileSizeCheck)
                    {
                        var allowOddRomFileSize = !ProgramFileKind.Rom.HasCustomRomExtension(filePath);
                        fileSizeCheck = IsValidFileSize(file, allowOddRomFileSize);
                    }
                    if (fileSizeCheck)
                    {
                        format = RomFormat.Bin;
                    }
                }
            }
            return(format);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Checks the format of the ROM at the given absolute path.
        /// </summary>
        /// <param name="filePath">Absolute path to a ROM file.</param>
        /// <returns>The format of the ROM.</returns>
        internal static RomFormat CheckFormat(string filePath)
        {
            var format = CheckMemo(filePath);

            if (format == RomFormat.None)
            {
                using (var file = StreamUtilities.OpenFileStream(filePath))
                {
                    if (file != null)
                    {
                        if (file.Length > 0)
                        {
                            if (LuigiFileHeader.GetHeader(filePath) != null)
                            {
                                format = RomFormat.Luigi;
                                AddMemo(filePath, format);
                            }
                        }
                    }
                }
            }
            return(format);
        }
Exemplo n.º 14
0
            /// <inheritdoc />
            protected override LuigiFileHeader GetMemo(string filePath, object data)
            {
                LuigiFileHeader luigiHeader = null;

                try
                {
                    using (var file = StreamUtilities.OpenFileStream(filePath))
                    {
                        var    reader = new INTV.Core.Utility.BinaryReader(file);
                        byte[] header = reader.ReadBytes(MagicKey.Length);
                        if (header.SequenceEqual(MagicKey))
                        {
                            file.Seek(0, System.IO.SeekOrigin.Begin);
                            luigiHeader = LuigiFileHeader.Inflate(file);
                        }
                    }
                }
                catch (Exception)
                {
                    // Just in case the header looks OK, but turns out to be bad.
                }
                return(luigiHeader);
            }
Exemplo n.º 15
0
        /// <summary>
        /// Examines the given data stream and attempts to determine if it is in .bin format.
        /// </summary>
        /// <param name="filePath">The path to the ROM file.</param>
        /// <param name="configFilePath">The path to the config file.</param>
        /// <returns>A valid BinFormatRom if the file appears to be a valid .bin (or similar) file, otherwise <c>null</c>.</returns>
        /// <remarks>Apparently, there may be odd-sized files floating around out there, in which case this will fail.</remarks>
        internal static new BinFormatRom Create(string filePath, string configFilePath)
        {
            BinFormatRom bin    = null;
            var          format = CheckFormat(filePath);

            if (format == RomFormat.Bin)
            {
                using (System.IO.Stream configFile = (configFilePath == null) ? null : StreamUtilities.OpenFileStream(configFilePath))
                {
                    // any valid .bin file will be even sized -- except for some available through the Digital Press. For some reason, these all seem to be a multiple of
                    // 8KB + 1 byte in size. So allow those through, too.
                    var configFileCheck = ((configFile != null) && (configFile.Length > 0)) || configFile == null;
                    if (configFileCheck)
                    {
                        bin = new BinFormatRom()
                        {
                            Format = RomFormat.Bin, IsValid = true, RomPath = filePath, ConfigPath = configFilePath
                        };
                    }
                }
            }
            return(bin);
        }