예제 #1
0
        /// <summary>
        /// Parse a ClrMamePro DAT and return all found games and roms within
        /// </summary>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="indexId">Index ID for the DAT</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
        protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
        {
            // Open a file reader
            Encoding         enc  = FileExtensions.GetEncoding(filename);
            ClrMameProReader cmpr = new ClrMameProReader(FileExtensions.TryOpenRead(filename), enc)
            {
                DosCenter = false,
                Quotes    = Quotes,
            };

            while (!cmpr.EndOfStream)
            {
                try
                {
                    cmpr.ReadNextLine();

                    // Ignore everything not top-level
                    if (cmpr.RowType != CmpRowType.TopLevel)
                    {
                        continue;
                    }

                    // Switch on the top-level name
                    switch (cmpr.TopLevel.ToLowerInvariant())
                    {
                    // Header values
                    case "clrmamepro":
                    case "romvault":
                        ReadHeader(cmpr, keep);
                        break;

                    // Sets
                    case "set":             // Used by the most ancient DATs
                    case "game":            // Used by most CMP DATs
                    case "machine":         // Possibly used by MAME CMP DATs
                        ReadSet(cmpr, false, filename, indexId);
                        break;

                    case "resource":        // Used by some other DATs to denote a BIOS set
                        ReadSet(cmpr, true, filename, indexId);
                        break;

                    default:
                        break;
                    }
                }
                catch (Exception ex)
                {
                    string message = $"'{filename}' - There was an error parsing line {cmpr.LineNumber} '{cmpr.CurrentLine}'";
                    logger.Error(ex, message);
                    if (throwOnError)
                    {
                        cmpr.Dispose();
                        throw new Exception(message, ex);
                    }
                }
            }

            cmpr.Dispose();
        }
예제 #2
0
        /// <summary>
        /// Parse a DOSCenter DAT and return all found games and roms within
        /// </summary>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="indexId">Index ID for the DAT</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param>
        protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
        {
            // Open a file reader
            Encoding         enc  = FileExtensions.GetEncoding(filename);
            ClrMameProReader cmpr = new ClrMameProReader(FileExtensions.TryOpenRead(filename), enc)
            {
                DosCenter = true
            };

            while (!cmpr.EndOfStream)
            {
                try
                {
                    cmpr.ReadNextLine();

                    // Ignore everything not top-level
                    if (cmpr.RowType != CmpRowType.TopLevel)
                    {
                        continue;
                    }

                    // Switch on the top-level name
                    switch (cmpr.TopLevel.ToLowerInvariant())
                    {
                    // Header values
                    case "doscenter":
                        ReadHeader(cmpr);
                        break;

                    // Sets
                    case "game":
                        ReadGame(cmpr, filename, indexId);
                        break;

                    default:
                        break;
                    }
                }
                catch (Exception ex)
                {
                    string message = $"'{filename}' - There was an error parsing line {cmpr.LineNumber} '{cmpr.CurrentLine}'";
                    logger.Error(ex, message);
                    if (throwOnError)
                    {
                        cmpr.Dispose();
                        throw new Exception(message, ex);
                    }
                }
            }

            cmpr.Dispose();
        }
예제 #3
0
        /// <summary>
        /// Read set information
        /// </summary>
        /// <param name="cmpr">ClrMameProReader to use to parse the header</param>
        /// <param name="resource">True if the item is a resource (bios), false otherwise</param>
        /// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="indexId">Index ID for the DAT</param>
        private void ReadSet(
            ClrMameProReader cmpr,
            bool resource,
            bool statsOnly,

            // Standard Dat parsing
            string filename,
            int indexId)
        {
            // Prepare all internal variables
            bool    containsItems = false;
            Machine machine       = new Machine()
            {
                MachineType = (resource ? MachineType.Bios : MachineType.NULL),
            };

            // If there's no subtree to the header, skip it
            if (cmpr == null || cmpr.EndOfStream)
            {
                return;
            }

            // While we don't hit an end element or end of stream
            while (!cmpr.EndOfStream)
            {
                cmpr.ReadNextLine();

                // Ignore comments and nothingness
                if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment)
                {
                    continue;
                }

                // If we reached the end of a section, break
                if (cmpr.RowType == CmpRowType.EndTopLevel)
                {
                    break;
                }

                // Handle any standalone items
                if (cmpr.RowType == CmpRowType.Standalone && cmpr.Standalone != null)
                {
                    string itemKey = cmpr.Standalone?.Key.ToLowerInvariant();
                    string itemVal = cmpr.Standalone?.Value;

                    switch (itemKey)
                    {
                    case "name":
                        machine.Name = itemVal;
                        break;

                    case "description":
                        machine.Description = itemVal;
                        break;

                    case "year":
                        machine.Year = itemVal;
                        break;

                    case "manufacturer":
                        machine.Manufacturer = itemVal;
                        break;

                    case "category":
                        machine.Category = itemVal;
                        break;

                    case "cloneof":
                        machine.CloneOf = itemVal;
                        break;

                    case "romof":
                        machine.RomOf = itemVal;
                        break;

                    case "sampleof":
                        machine.SampleOf = itemVal;
                        break;
                    }
                }

                // Handle any internal items
                else if (cmpr.RowType == CmpRowType.Internal &&
                         !string.IsNullOrWhiteSpace(cmpr.InternalName) &&
                         cmpr.Internal != null)
                {
                    containsItems = true;
                    string itemKey = cmpr.InternalName;

                    // Create the proper DatItem based on the type
                    ItemType itemType = itemKey.AsItemType() ?? ItemType.Rom;
                    DatItem  item     = DatItem.Create(itemType);

                    // Then populate it with information
                    item.CopyMachineInformation(machine);

                    item.Source.Index = indexId;
                    item.Source.Name  = filename;

                    // Loop through all of the attributes
                    foreach (var kvp in cmpr.Internal)
                    {
                        string attrKey = kvp.Key;
                        string attrVal = kvp.Value;

                        switch (attrKey)
                        {
                        //If the item is empty, we automatically skip it because it's a fluke
                        case "":
                            continue;

                        // Regular attributes
                        case "name":
                            item.SetName(attrVal);
                            break;

                        case "size":
                            if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).Size = Utilities.CleanLong(attrVal);
                            }

                            break;

                        case "crc":
                            if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).CRC = attrVal;
                            }

                            break;

                        case "md5":
                            if (item.ItemType == ItemType.Disk)
                            {
                                (item as Disk).MD5 = attrVal;
                            }
                            else if (item.ItemType == ItemType.Media)
                            {
                                (item as Media).MD5 = attrVal;
                            }
                            else if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).MD5 = attrVal;
                            }

                            break;

                        case "sha1":
                            if (item.ItemType == ItemType.Disk)
                            {
                                (item as Disk).SHA1 = attrVal;
                            }
                            else if (item.ItemType == ItemType.Media)
                            {
                                (item as Media).SHA1 = attrVal;
                            }
                            else if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).SHA1 = attrVal;
                            }

                            break;

                        case "sha256":
                            if (item.ItemType == ItemType.Media)
                            {
                                (item as Media).SHA256 = attrVal;
                            }
                            else if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).SHA256 = attrVal;
                            }

                            break;

                        case "sha384":
                            if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).SHA384 = attrVal;
                            }

                            break;

                        case "sha512":
                            if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).SHA512 = attrVal;
                            }

                            break;

                        case "spamsum":
                            if (item.ItemType == ItemType.Media)
                            {
                                (item as Media).SpamSum = attrVal;
                            }
                            else if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).SpamSum = attrVal;
                            }

                            break;

                        case "status":
                            ItemStatus tempFlagStatus = attrVal.AsItemStatus();
                            if (item.ItemType == ItemType.Disk)
                            {
                                (item as Disk).ItemStatus = tempFlagStatus;
                            }
                            else if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).ItemStatus = tempFlagStatus;
                            }

                            break;

                        case "date":
                            if (item.ItemType == ItemType.Release)
                            {
                                (item as Release).Date = attrVal;
                            }
                            else if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).Date = attrVal;
                            }

                            break;

                        case "default":
                            if (item.ItemType == ItemType.BiosSet)
                            {
                                (item as BiosSet).Default = attrVal.AsYesNo();
                            }
                            else if (item.ItemType == ItemType.Release)
                            {
                                (item as Release).Default = attrVal.AsYesNo();
                            }

                            break;

                        case "description":
                            if (item.ItemType == ItemType.BiosSet)
                            {
                                (item as BiosSet).Description = attrVal;
                            }

                            break;

                        case "region":
                            if (item.ItemType == ItemType.Release)
                            {
                                (item as Release).Region = attrVal;
                            }

                            break;

                        case "language":
                            if (item.ItemType == ItemType.Release)
                            {
                                (item as Release).Language = attrVal;
                            }

                            break;
                        }
                    }

                    // Now process and add the rom
                    ParseAddHelper(item, statsOnly);
                }
            }

            // If no items were found for this machine, add a Blank placeholder
            if (!containsItems)
            {
                Blank blank = new Blank()
                {
                    Source = new Source
                    {
                        Index = indexId,
                        Name  = filename,
                    },
                };

                blank.CopyMachineInformation(machine);

                // Now process and add the rom
                ParseAddHelper(blank, statsOnly);
            }
        }
예제 #4
0
        /// <summary>
        /// Read header information
        /// </summary>
        /// <param name="cmpr">ClrMameProReader to use to parse the header</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        private void ReadHeader(ClrMameProReader cmpr, bool keep)
        {
            bool superdat = false;

            // If there's no subtree to the header, skip it
            if (cmpr == null || cmpr.EndOfStream)
            {
                return;
            }

            // While we don't hit an end element or end of stream
            while (!cmpr.EndOfStream)
            {
                cmpr.ReadNextLine();

                // Ignore comments, internal items, and nothingness
                if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment || cmpr.RowType == CmpRowType.Internal)
                {
                    continue;
                }

                // If we reached the end of a section, break
                if (cmpr.RowType == CmpRowType.EndTopLevel)
                {
                    break;
                }

                // If the standalone value is null, we skip
                if (cmpr.Standalone == null)
                {
                    continue;
                }

                string itemKey = cmpr.Standalone?.Key.ToLowerInvariant();
                string itemVal = cmpr.Standalone?.Value;

                // For all other cases
                switch (itemKey)
                {
                case "name":
                    Header.Name ??= itemVal;
                    superdat |= itemVal.Contains(" - SuperDAT");

                    if (keep && superdat)
                    {
                        Header.Type ??= "SuperDAT";
                    }

                    break;

                case "description":
                    Header.Description ??= itemVal;
                    break;

                case "rootdir":
                    Header.RootDir ??= itemVal;
                    break;

                case "category":
                    Header.Category ??= itemVal;
                    break;

                case "version":
                    Header.Version ??= itemVal;
                    break;

                case "date":
                    Header.Date ??= itemVal;
                    break;

                case "author":
                    Header.Author ??= itemVal;
                    break;

                case "email":
                    Header.Email ??= itemVal;
                    break;

                case "homepage":
                    Header.Homepage ??= itemVal;
                    break;

                case "url":
                    Header.Url ??= itemVal;
                    break;

                case "comment":
                    Header.Comment ??= itemVal;
                    break;

                case "header":
                    Header.HeaderSkipper ??= itemVal;
                    break;

                case "type":
                    Header.Type ??= itemVal;
                    superdat |= itemVal.Contains("SuperDAT");
                    break;

                case "forcemerging":
                    if (Header.ForceMerging == MergingFlag.None)
                    {
                        Header.ForceMerging = itemVal.AsMergingFlag();
                    }

                    break;

                case "forcezipping":
                    if (Header.ForcePacking == PackingFlag.None)
                    {
                        Header.ForcePacking = itemVal.AsPackingFlag();
                    }

                    break;

                case "forcepacking":
                    if (Header.ForcePacking == PackingFlag.None)
                    {
                        Header.ForcePacking = itemVal.AsPackingFlag();
                    }

                    break;
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Read header information
        /// </summary>
        /// <param name="cmpr">ClrMameProReader to use to parse the header</param>
        private void ReadHeader(ClrMameProReader cmpr)
        {
            // If there's no subtree to the header, skip it
            if (cmpr == null || cmpr.EndOfStream)
            {
                return;
            }

            // While we don't hit an end element or end of stream
            while (!cmpr.EndOfStream)
            {
                cmpr.ReadNextLine();

                // Ignore comments, internal items, and nothingness
                if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment || cmpr.RowType == CmpRowType.Internal)
                {
                    continue;
                }

                // If we reached the end of a section, break
                if (cmpr.RowType == CmpRowType.EndTopLevel)
                {
                    break;
                }

                // If the standalone value is null, we skip
                if (cmpr.Standalone == null)
                {
                    continue;
                }

                string itemKey = cmpr.Standalone?.Key.ToLowerInvariant().TrimEnd(':');
                string itemVal = cmpr.Standalone?.Value;

                // For all other cases
                switch (itemKey)
                {
                case "name":
                    Header.Name = Header.Name ?? itemVal;
                    break;

                case "description":
                    Header.Description = Header.Description ?? itemVal;
                    break;

                case "dersion":
                    Header.Version = Header.Version ?? itemVal;
                    break;

                case "date":
                    Header.Date = Header.Date ?? itemVal;
                    break;

                case "author":
                    Header.Author = Header.Author ?? itemVal;
                    break;

                case "homepage":
                    Header.Homepage = Header.Homepage ?? itemVal;
                    break;

                case "comment":
                    Header.Comment = Header.Comment ?? itemVal;
                    break;
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Read set information
        /// </summary>
        /// <param name="cmpr">ClrMameProReader to use to parse the header</param>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="indexId">Index ID for the DAT</param>
        private void ReadGame(ClrMameProReader cmpr, string filename, int indexId)
        {
            // Prepare all internal variables
            bool    containsItems = false;
            Machine machine       = new Machine()
            {
                MachineType = MachineType.NULL,
            };

            // If there's no subtree to the header, skip it
            if (cmpr == null || cmpr.EndOfStream)
            {
                return;
            }

            // While we don't hit an end element or end of stream
            while (!cmpr.EndOfStream)
            {
                cmpr.ReadNextLine();

                // Ignore comments and nothingness
                if (cmpr.RowType == CmpRowType.None || cmpr.RowType == CmpRowType.Comment)
                {
                    continue;
                }

                // If we reached the end of a section, break
                if (cmpr.RowType == CmpRowType.EndTopLevel)
                {
                    break;
                }

                // Handle any standalone items
                if (cmpr.RowType == CmpRowType.Standalone && cmpr.Standalone != null)
                {
                    string itemKey = cmpr.Standalone?.Key.ToLowerInvariant();
                    string itemVal = cmpr.Standalone?.Value;

                    switch (itemKey)
                    {
                    case "name":
                        machine.Name        = (itemVal.ToLowerInvariant().EndsWith(".zip") ? itemVal.Remove(itemVal.Length - 4) : itemVal);
                        machine.Description = (itemVal.ToLowerInvariant().EndsWith(".zip") ? itemVal.Remove(itemVal.Length - 4) : itemVal);
                        break;
                    }
                }

                // Handle any internal items
                else if (cmpr.RowType == CmpRowType.Internal &&
                         string.Equals(cmpr.InternalName, "file", StringComparison.OrdinalIgnoreCase) &&
                         cmpr.Internal != null)
                {
                    containsItems = true;

                    // Create the proper DatItem based on the type
                    Rom item = DatItem.Create(ItemType.Rom) as Rom;

                    // Then populate it with information
                    item.CopyMachineInformation(machine);
                    item.Source = new Source
                    {
                        Index = indexId,
                        Name  = filename,
                    };

                    // Loop through all of the attributes
                    foreach (var kvp in cmpr.Internal)
                    {
                        string attrKey = kvp.Key;
                        string attrVal = kvp.Value;

                        switch (attrKey)
                        {
                        //If the item is empty, we automatically skip it because it's a fluke
                        case "":
                            continue;

                        // Regular attributes
                        case "name":
                            item.Name = attrVal;
                            break;

                        case "size":
                            item.Size = Sanitizer.CleanLong(attrVal);
                            break;

                        case "crc":
                            item.CRC = attrVal;
                            break;

                        case "date":
                            item.Date = attrVal;
                            break;
                        }
                    }

                    // Now process and add the rom
                    ParseAddHelper(item);
                }
            }

            // If no items were found for this machine, add a Blank placeholder
            if (!containsItems)
            {
                Blank blank = new Blank()
                {
                    Source = new Source
                    {
                        Index = indexId,
                        Name  = filename,
                    },
                };

                blank.CopyMachineInformation(machine);

                // Now process and add the rom
                ParseAddHelper(blank);
            }
        }