示例#1
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Chip-specific fields
            if (mappings.Keys.Contains(Field.DatItem_Name))
            {
                Name = mappings[Field.DatItem_Name];
            }

            if (mappings.Keys.Contains(Field.DatItem_Tag))
            {
                Tag = mappings[Field.DatItem_Tag];
            }

            if (mappings.Keys.Contains(Field.DatItem_ChipType))
            {
                ChipType = mappings[Field.DatItem_ChipType].AsChipType();
            }

            if (mappings.Keys.Contains(Field.DatItem_Clock))
            {
                Clock = Sanitizer.CleanLong(mappings[Field.DatItem_Clock]);
            }
        }
示例#2
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle DataArea-specific fields
            if (mappings.Keys.Contains(Field.DatItem_AreaName))
            {
                Name = mappings[Field.DatItem_AreaName];
            }

            if (mappings.Keys.Contains(Field.DatItem_AreaSize))
            {
                Size = Sanitizer.CleanLong(mappings[Field.DatItem_AreaSize]);
            }

            if (mappings.Keys.Contains(Field.DatItem_AreaWidth))
            {
                Width = Sanitizer.CleanLong(mappings[Field.DatItem_AreaWidth]);
            }

            if (mappings.Keys.Contains(Field.DatItem_AreaEndianness))
            {
                Endianness = mappings[Field.DatItem_AreaEndianness].AsEndianness();
            }
        }
示例#3
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Input-specific fields
            if (mappings.Keys.Contains(Field.DatItem_Service))
            {
                Service = mappings[Field.DatItem_Service].AsYesNo();
            }

            if (mappings.Keys.Contains(Field.DatItem_Tilt))
            {
                Tilt = mappings[Field.DatItem_Tilt].AsYesNo();
            }

            if (mappings.Keys.Contains(Field.DatItem_Players))
            {
                Players = Sanitizer.CleanLong(mappings[Field.DatItem_Players]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Coins))
            {
                Coins = Sanitizer.CleanLong(mappings[Field.DatItem_Coins]);
            }

            if (ControlsSpecified)
            {
                foreach (Control control in Controls)
                {
                    control.SetFields(mappings);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Sound-specific fields
            if (mappings.Keys.Contains(Field.DatItem_Channels))
            {
                Channels = Sanitizer.CleanLong(mappings[Field.DatItem_Channels]);
            }
        }
示例#5
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Device-specific fields
            if (mappings.Keys.Contains(Field.DatItem_DeviceType))
            {
                DeviceType = mappings[Field.DatItem_DeviceType].AsDeviceType();
            }

            if (mappings.Keys.Contains(Field.DatItem_Tag))
            {
                Tag = mappings[Field.DatItem_Tag];
            }

            if (mappings.Keys.Contains(Field.DatItem_FixedImage))
            {
                FixedImage = mappings[Field.DatItem_FixedImage];
            }

            if (mappings.Keys.Contains(Field.DatItem_Mandatory))
            {
                Mandatory = Sanitizer.CleanLong(mappings[Field.DatItem_Mandatory]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Interface))
            {
                Interface = mappings[Field.DatItem_Interface];
            }

            if (InstancesSpecified)
            {
                foreach (Instance instance in Instances)
                {
                    instance.SetFields(mappings);
                }
            }

            if (ExtensionsSpecified)
            {
                foreach (Extension extension in Extensions)
                {
                    extension.SetFields(mappings);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Read dataarea information
        /// </summary>
        /// <param name="reader">XmlReader representing a dataarea block</param>
        /// <param name="dataArea">DataArea representing the enclosing area</param>
        private List <DatItem> ReadDataArea(XmlReader reader, DataArea dataArea)
        {
            List <DatItem> items = new List <DatItem>();

            while (!reader.EOF)
            {
                // We only want elements
                if (reader.NodeType != XmlNodeType.Element)
                {
                    reader.Read();
                    continue;
                }

                // Get the elements from the software
                switch (reader.Name)
                {
                case "rom":
                    var rom = new Rom
                    {
                        Name       = reader.GetAttribute("name"),
                        Size       = Sanitizer.CleanLong(reader.GetAttribute("size")),
                        CRC        = reader.GetAttribute("crc"),
                        SHA1       = reader.GetAttribute("sha1"),
                        Offset     = reader.GetAttribute("offset"),
                        Value      = reader.GetAttribute("value"),
                        ItemStatus = reader.GetAttribute("status").AsItemStatus(),
                        LoadFlag   = reader.GetAttribute("loadflag").AsLoadFlag(),

                        DataArea = dataArea,
                    };

                    items.Add(rom);
                    reader.Read();
                    break;

                default:
                    reader.Read();
                    break;
                }
            }

            return(items);
        }
示例#7
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Location-specific fields
            if (mappings.Keys.Contains(Field.DatItem_Location_Name))
            {
                Name = mappings[Field.DatItem_Location_Name];
            }

            if (mappings.Keys.Contains(Field.DatItem_Location_Number))
            {
                Number = Sanitizer.CleanLong(mappings[Field.DatItem_Location_Number]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Location_Inverted))
            {
                Inverted = mappings[Field.DatItem_Location_Inverted].AsYesNo();
            }
        }
示例#8
0
        /// <summary>
        /// Read part information
        /// </summary>
        /// <param name="reader">XmlReader representing a part block</param>
        /// <param name="machine">Machine information to pass to contained items</param>
        /// <param name="part">Part information to pass to contained items</param>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="indexId">Index ID for the DAT</param>
        private bool ReadPart(XmlReader reader, Machine machine, Part part, string filename, int indexId)
        {
            // If we have an empty port, skip it
            if (reader == null)
            {
                return(false);
            }

            // Get lists ready
            part.Features = new List <PartFeature>();
            List <DatItem> items = new List <DatItem>();

            while (!reader.EOF)
            {
                // We only want elements
                if (reader.NodeType != XmlNodeType.Element)
                {
                    reader.Read();
                    continue;
                }

                // Get the elements from the software
                switch (reader.Name)
                {
                case "feature":
                    var feature = new PartFeature()
                    {
                        Name  = reader.GetAttribute("name"),
                        Value = reader.GetAttribute("value"),
                    };

                    part.Features.Add(feature);

                    reader.Read();
                    break;

                case "dataarea":
                    var dataArea = new DataArea
                    {
                        Name       = reader.GetAttribute("name"),
                        Size       = Sanitizer.CleanLong(reader.GetAttribute("size")),
                        Width      = Sanitizer.CleanLong(reader.GetAttribute("width")),
                        Endianness = reader.GetAttribute("endianness").AsEndianness(),
                    };

                    List <DatItem> roms = ReadDataArea(reader.ReadSubtree(), dataArea);

                    // If we got valid roms, add them to the list
                    if (roms != null)
                    {
                        items.AddRange(roms);
                    }

                    // Skip the dataarea now that we've processed it
                    reader.Skip();
                    break;

                case "diskarea":
                    var diskArea = new DiskArea
                    {
                        Name = reader.GetAttribute("name"),
                    };

                    List <DatItem> disks = ReadDiskArea(reader.ReadSubtree(), diskArea);

                    // If we got valid disks, add them to the list
                    if (disks != null)
                    {
                        items.AddRange(disks);
                    }

                    // Skip the diskarea now that we've processed it
                    reader.Skip();
                    break;

                case "dipswitch":
                    var dipSwitch = new DipSwitch
                    {
                        Name = reader.GetAttribute("name"),
                        Tag  = reader.GetAttribute("tag"),
                        Mask = reader.GetAttribute("mask"),
                    };

                    // Now read the internal tags
                    ReadDipSwitch(reader.ReadSubtree(), dipSwitch);

                    items.Add(dipSwitch);

                    // Skip the dipswitch now that we've processed it
                    reader.Skip();
                    break;

                default:
                    reader.Read();
                    break;
                }
            }

            // Loop over all of the items, if they exist
            string key = string.Empty;

            foreach (DatItem item in items)
            {
                // Add all missing information
                switch (item.ItemType)
                {
                case ItemType.DipSwitch:
                    (item as DipSwitch).Part = part;
                    break;

                case ItemType.Disk:
                    (item as Disk).Part = part;
                    break;

                case ItemType.Rom:
                    (item as Rom).Part = part;

                    // If the rom is continue or ignore, add the size to the previous rom
                    // TODO: Can this be done on write? We technically lose information this way.
                    // Order is not guaranteed, and since these don't tend to have any way
                    // of determining what the "previous" item was after this, that info would
                    // have to be stored *with* the item somehow
                    if ((item as Rom).LoadFlag == LoadFlag.Continue || (item as Rom).LoadFlag == LoadFlag.Ignore)
                    {
                        int     index   = Items[key].Count - 1;
                        DatItem lastrom = Items[key][index];
                        if (lastrom.ItemType == ItemType.Rom)
                        {
                            (lastrom as Rom).Size += (item as Rom).Size;
                            Items[key].RemoveAt(index);
                            Items[key].Add(lastrom);
                        }

                        continue;
                    }

                    break;
                }

                item.Source = new Source(indexId, filename);
                item.CopyMachineInformation(machine);

                // Finally add each item
                key = ParseAddHelper(item);
            }

            return(items.Any());
        }
示例#9
0
        /// <summary>
        /// Read games information
        /// </summary>
        /// <param name="reader">IniReader to use to parse the credits</param>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="indexId">Index ID for the DAT</param>
        private void ReadGamesSection(IniReader reader, string filename, int indexId)
        {
            // If the reader is somehow null, skip it
            if (reader == null)
            {
                return;
            }

            reader.ReadNextLine();
            while (!reader.EndOfStream && reader.Section.ToLowerInvariant() == "games")
            {
                // We don't care about whitespace or comments
                // We're keeping keyvalue in case a file has '=' in the row
                if (reader.RowType != IniRowType.Invalid && reader.RowType != IniRowType.KeyValue)
                {
                    reader.ReadNextLine();
                    continue;
                }

                // Roms are not valid row formats, usually
                string line = reader.CurrentLine;

                // If we don't have a valid game, keep reading
                if (!line.StartsWith("¬"))
                {
                    reader.ReadNextLine();
                    continue;
                }

                // Some old RC DATs have this behavior
                if (line.Contains("¬N¬O"))
                {
                    line = line.Replace("¬N¬O", string.Empty) + "¬¬";
                }

                /*
                 * The rominfo order is as follows:
                 * 1 - parent name
                 * 2 - parent description
                 * 3 - game name
                 * 4 - game description
                 * 5 - rom name
                 * 6 - rom crc
                 * 7 - rom size
                 * 8 - romof name
                 * 9 - merge name
                 */
                string[] rominfo = line.Split('¬');
                Rom      rom     = new Rom
                {
                    Name       = rominfo[5],
                    Size       = Sanitizer.CleanLong(rominfo[7]),
                    CRC        = rominfo[6],
                    ItemStatus = ItemStatus.None,

                    Machine = new Machine
                    {
                        Name        = rominfo[3],
                        Description = rominfo[4],
                        CloneOf     = rominfo[1],
                        RomOf       = rominfo[8],
                    },

                    MergeTag = rominfo[9],

                    Source = new Source
                    {
                        Index = indexId,
                        Name  = filename,
                    },
                };

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

                reader.ReadNextLine();
            }
        }
示例#10
0
        /// <summary>
        /// Parse a MAME Listrom 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>
        /// <remarks>
        /// In a new style MAME listrom DAT, each game has the following format:
        ///
        /// ROMs required for driver "005".
        /// Name                                   Size Checksum
        /// 1346b.cpu-u25                          2048 CRC(8e68533e) SHA1(a257c556d31691068ed5c991f1fb2b51da4826db)
        /// 6331.sound-u8                            32 BAD CRC(1d298cb0) SHA1(bb0bb62365402543e3154b9a77be9c75010e6abc) BAD_DUMP
        /// 16v8h-blue.u24                          279 NO GOOD DUMP KNOWN
        /// </remarks>
        protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false)
        {
            // Open a file reader
            Encoding     enc = FileExtensions.GetEncoding(filename);
            StreamReader sr  = new StreamReader(FileExtensions.TryOpenRead(filename), enc);

            string gamename = string.Empty;

            while (!sr.EndOfStream)
            {
                try
                {
                    string line = sr.ReadLine().Trim();

                    // If we have a blank line, we just skip it
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    // If we have the descriptor line, ignore it
                    else if (line == "Name                                   Size Checksum")
                    {
                        continue;
                    }

                    // If we have the beginning of a game, set the name of the game
                    else if (line.StartsWith("ROMs required for"))
                    {
                        gamename = Regex.Match(line, @"^ROMs required for \S*? string.Empty(.*?)string.Empty\.").Groups[1].Value;
                    }

                    // If we have a machine with no required roms (usually internal devices), skip it
                    else if (line.StartsWith("No ROMs required for"))
                    {
                        continue;
                    }

                    // Otherwise, we assume we have a rom that we need to add
                    else
                    {
                        // First, we preprocess the line so that the rom name is consistently correct
                        string[] split = line.Split(new string[] { "    " }, StringSplitOptions.RemoveEmptyEntries);

                        // If the line doesn't have the 4 spaces of padding, check for 3
                        if (split.Length == 1)
                        {
                            split = line.Split(new string[] { "   " }, StringSplitOptions.RemoveEmptyEntries);
                        }

                        // If the split is still unsuccessful, log it and skip
                        if (split.Length == 1)
                        {
                            logger.Warning($"Possibly malformed line: '{line}'");
                        }

                        string romname = split[0];
                        line = line.Substring(romname.Length);

                        // Next we separate the ROM into pieces
                        split = line.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);

                        // Standard Disks have 2 pieces (name, sha1)
                        if (split.Length == 1)
                        {
                            Disk disk = new Disk()
                            {
                                Name = romname,
                                SHA1 = Sanitizer.CleanListromHashData(split[0]),

                                Machine = new Machine
                                {
                                    Name = gamename,
                                },

                                Source = new Source
                                {
                                    Index = indexId,
                                    Name  = filename,
                                },
                            };

                            ParseAddHelper(disk);
                        }

                        // Baddump Disks have 4 pieces (name, BAD, sha1, BAD_DUMP)
                        else if (split.Length == 3 && line.EndsWith("BAD_DUMP"))
                        {
                            Disk disk = new Disk()
                            {
                                Name       = romname,
                                SHA1       = Sanitizer.CleanListromHashData(split[1]),
                                ItemStatus = ItemStatus.BadDump,

                                Machine = new Machine
                                {
                                    Name = gamename,
                                },

                                Source = new Source
                                {
                                    Index = indexId,
                                    Name  = filename,
                                },
                            };

                            ParseAddHelper(disk);
                        }

                        // Standard ROMs have 4 pieces (name, size, crc, sha1)
                        else if (split.Length == 3)
                        {
                            Rom rom = new Rom()
                            {
                                Name = romname,
                                Size = Sanitizer.CleanLong(split[0]),
                                CRC  = Sanitizer.CleanListromHashData(split[1]),
                                SHA1 = Sanitizer.CleanListromHashData(split[2]),

                                Machine = new Machine
                                {
                                    Name = gamename,
                                },

                                Source = new Source
                                {
                                    Index = indexId,
                                    Name  = filename,
                                },
                            };

                            ParseAddHelper(rom);
                        }

                        // Nodump Disks have 5 pieces (name, NO, GOOD, DUMP, KNOWN)
                        else if (split.Length == 4 && line.EndsWith("NO GOOD DUMP KNOWN"))
                        {
                            Disk disk = new Disk()
                            {
                                Name       = romname,
                                ItemStatus = ItemStatus.Nodump,

                                Machine = new Machine
                                {
                                    Name = gamename,
                                },

                                Source = new Source
                                {
                                    Index = indexId,
                                    Name  = filename,
                                },
                            };

                            ParseAddHelper(disk);
                        }

                        // Baddump ROMs have 6 pieces (name, size, BAD, crc, sha1, BAD_DUMP)
                        else if (split.Length == 5 && line.EndsWith("BAD_DUMP"))
                        {
                            Rom rom = new Rom()
                            {
                                Name       = romname,
                                Size       = Sanitizer.CleanLong(split[0]),
                                CRC        = Sanitizer.CleanListromHashData(split[2]),
                                SHA1       = Sanitizer.CleanListromHashData(split[3]),
                                ItemStatus = ItemStatus.BadDump,

                                Machine = new Machine
                                {
                                    Name = gamename,
                                },

                                Source = new Source
                                {
                                    Index = indexId,
                                    Name  = filename,
                                },
                            };

                            ParseAddHelper(rom);
                        }

                        // Nodump ROMs have 6 pieces (name, size, NO, GOOD, DUMP, KNOWN)
                        else if (split.Length == 5 && line.EndsWith("NO GOOD DUMP KNOWN"))
                        {
                            Rom rom = new Rom()
                            {
                                Name       = romname,
                                Size       = Sanitizer.CleanLong(split[0]),
                                ItemStatus = ItemStatus.Nodump,

                                Machine = new Machine
                                {
                                    Name = gamename,
                                },

                                Source = new Source
                                {
                                    Index = indexId,
                                    Name  = filename,
                                },
                            };

                            ParseAddHelper(rom);
                        }

                        // If we have something else, it's invalid
                        else
                        {
                            logger.Warning($"Invalid line detected: '{romname} {line}'");
                        }
                    }
                }
                catch (Exception ex)
                {
                    string message = $"'{filename}' - There was an error parsing at position {sr.BaseStream.Position}";
                    logger.Error(ex, message);
                    if (throwOnError)
                    {
                        sr.Dispose();
                        throw new Exception(message, ex);
                    }
                }
            }
        }
示例#11
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="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,

            // 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.SetFields(new Dictionary <Field, string> {
                                [Field.DatItem_Name] = attrVal
                            });
                            break;

                        case "size":
                            if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).Size = Sanitizer.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;

#if NET_FRAMEWORK
                        case "ripemd160":
                            if (item.ItemType == ItemType.Rom)
                            {
                                (item as Rom).RIPEMD160 = attrVal;
                            }

                            break;
#endif
                        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);
                }
            }

            // 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);
            }
        }
示例#12
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Control-specific fields
            if (mappings.Keys.Contains(Field.DatItem_Control_Type))
            {
                ControlType = mappings[Field.DatItem_Control_Type].AsControlType();
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Player))
            {
                Player = Sanitizer.CleanLong(mappings[Field.DatItem_Control_Player]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Buttons))
            {
                Buttons = Sanitizer.CleanLong(mappings[Field.DatItem_Control_Buttons]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_RequiredButtons))
            {
                RequiredButtons = Sanitizer.CleanLong(mappings[Field.DatItem_Control_RequiredButtons]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Minimum))
            {
                Minimum = Sanitizer.CleanLong(mappings[Field.DatItem_Control_Minimum]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Maximum))
            {
                Maximum = Sanitizer.CleanLong(mappings[Field.DatItem_Control_Maximum]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Sensitivity))
            {
                Sensitivity = Sanitizer.CleanLong(mappings[Field.DatItem_Control_Sensitivity]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_KeyDelta))
            {
                KeyDelta = Sanitizer.CleanLong(mappings[Field.DatItem_Control_KeyDelta]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Reverse))
            {
                Reverse = mappings[Field.DatItem_Control_Reverse].AsYesNo();
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Ways))
            {
                Ways = mappings[Field.DatItem_Control_Ways];
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Ways2))
            {
                Ways2 = mappings[Field.DatItem_Control_Ways2];
            }

            if (mappings.Keys.Contains(Field.DatItem_Control_Ways3))
            {
                Ways3 = mappings[Field.DatItem_Control_Ways3];
            }
        }
示例#13
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Display-specific fields
            if (mappings.Keys.Contains(Field.DatItem_Tag))
            {
                Tag = mappings[Field.DatItem_Tag];
            }

            if (mappings.Keys.Contains(Field.DatItem_DisplayType))
            {
                DisplayType = mappings[Field.DatItem_DisplayType].AsDisplayType();
            }

            if (mappings.Keys.Contains(Field.DatItem_Rotate))
            {
                Rotate = Sanitizer.CleanLong(mappings[Field.DatItem_Rotate]);
            }

            if (mappings.Keys.Contains(Field.DatItem_FlipX))
            {
                FlipX = mappings[Field.DatItem_FlipX].AsYesNo();
            }

            if (mappings.Keys.Contains(Field.DatItem_Width))
            {
                Width = Sanitizer.CleanLong(mappings[Field.DatItem_Width]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Height))
            {
                Height = Sanitizer.CleanLong(mappings[Field.DatItem_Height]);
            }

            if (mappings.Keys.Contains(Field.DatItem_Refresh))
            {
                if (Double.TryParse(mappings[Field.DatItem_Refresh], out double refresh))
                {
                    Refresh = refresh;
                }
            }

            if (mappings.Keys.Contains(Field.DatItem_PixClock))
            {
                PixClock = Sanitizer.CleanLong(mappings[Field.DatItem_PixClock]);
            }

            if (mappings.Keys.Contains(Field.DatItem_HTotal))
            {
                HTotal = Sanitizer.CleanLong(mappings[Field.DatItem_HTotal]);
            }

            if (mappings.Keys.Contains(Field.DatItem_HBEnd))
            {
                HBEnd = Sanitizer.CleanLong(mappings[Field.DatItem_HBEnd]);
            }

            if (mappings.Keys.Contains(Field.DatItem_HBStart))
            {
                HBStart = Sanitizer.CleanLong(mappings[Field.DatItem_HBStart]);
            }

            if (mappings.Keys.Contains(Field.DatItem_VTotal))
            {
                VTotal = Sanitizer.CleanLong(mappings[Field.DatItem_VTotal]);
            }

            if (mappings.Keys.Contains(Field.DatItem_VBEnd))
            {
                VBEnd = Sanitizer.CleanLong(mappings[Field.DatItem_VBEnd]);
            }

            if (mappings.Keys.Contains(Field.DatItem_VBStart))
            {
                VBStart = Sanitizer.CleanLong(mappings[Field.DatItem_VBStart]);
            }
        }
示例#14
0
        /// <summary>
        /// Set fields with given values
        /// </summary>
        /// <param name="mappings">Mappings dictionary</param>
        public override void SetFields(Dictionary <Field, string> mappings)
        {
            // Set base fields
            base.SetFields(mappings);

            // Handle Rom-specific fields

            #region Common

            if (mappings.Keys.Contains(Field.DatItem_Name))
            {
                Name = mappings[Field.DatItem_Name];
            }

            if (mappings.Keys.Contains(Field.DatItem_Bios))
            {
                Bios = mappings[Field.DatItem_Bios];
            }

            if (mappings.Keys.Contains(Field.DatItem_Size))
            {
                Size = Sanitizer.CleanLong(mappings[Field.DatItem_Size]);
            }

            if (mappings.Keys.Contains(Field.DatItem_CRC))
            {
                CRC = mappings[Field.DatItem_CRC];
            }

            if (mappings.Keys.Contains(Field.DatItem_MD5))
            {
                MD5 = mappings[Field.DatItem_MD5];
            }

#if NET_FRAMEWORK
            if (mappings.Keys.Contains(Field.DatItem_RIPEMD160))
            {
                RIPEMD160 = mappings[Field.DatItem_RIPEMD160];
            }
#endif

            if (mappings.Keys.Contains(Field.DatItem_SHA1))
            {
                SHA1 = mappings[Field.DatItem_SHA1];
            }

            if (mappings.Keys.Contains(Field.DatItem_SHA256))
            {
                SHA256 = mappings[Field.DatItem_SHA256];
            }

            if (mappings.Keys.Contains(Field.DatItem_SHA384))
            {
                SHA384 = mappings[Field.DatItem_SHA384];
            }

            if (mappings.Keys.Contains(Field.DatItem_SHA512))
            {
                SHA512 = mappings[Field.DatItem_SHA512];
            }

            if (mappings.Keys.Contains(Field.DatItem_SpamSum))
            {
                SpamSum = mappings[Field.DatItem_SpamSum];
            }

            if (mappings.Keys.Contains(Field.DatItem_Merge))
            {
                MergeTag = mappings[Field.DatItem_Merge];
            }

            if (mappings.Keys.Contains(Field.DatItem_Region))
            {
                Region = mappings[Field.DatItem_Region];
            }

            if (mappings.Keys.Contains(Field.DatItem_Offset))
            {
                Offset = mappings[Field.DatItem_Offset];
            }

            if (mappings.Keys.Contains(Field.DatItem_Date))
            {
                Date = mappings[Field.DatItem_Date];
            }

            if (mappings.Keys.Contains(Field.DatItem_Status))
            {
                ItemStatus = mappings[Field.DatItem_Status].AsItemStatus();
            }

            if (mappings.Keys.Contains(Field.DatItem_Optional))
            {
                Optional = mappings[Field.DatItem_Optional].AsYesNo();
            }

            if (mappings.Keys.Contains(Field.DatItem_Inverted))
            {
                Inverted = mappings[Field.DatItem_Optional].AsYesNo();
            }

            #endregion

            #region AttractMode

            if (mappings.Keys.Contains(Field.DatItem_AltName))
            {
                AltName = mappings[Field.DatItem_AltName];
            }

            if (mappings.Keys.Contains(Field.DatItem_AltTitle))
            {
                AltTitle = mappings[Field.DatItem_AltTitle];
            }

            #endregion

            #region OpenMSX

            if (mappings.Keys.Contains(Field.DatItem_Original))
            {
                Original = new Original()
                {
                    Content = mappings[Field.DatItem_Original]
                }
            }
            ;

            if (mappings.Keys.Contains(Field.DatItem_OpenMSXSubType))
            {
                OpenMSXSubType = mappings[Field.DatItem_OpenMSXSubType].AsOpenMSXSubType();
            }

            if (mappings.Keys.Contains(Field.DatItem_OpenMSXType))
            {
                OpenMSXType = mappings[Field.DatItem_OpenMSXType];
            }

            if (mappings.Keys.Contains(Field.DatItem_Remark))
            {
                Remark = mappings[Field.DatItem_Remark];
            }

            if (mappings.Keys.Contains(Field.DatItem_Boot))
            {
                Boot = mappings[Field.DatItem_Boot];
            }

            #endregion

            #region SoftwareList

            if (mappings.Keys.Contains(Field.DatItem_LoadFlag))
            {
                LoadFlag = mappings[Field.DatItem_LoadFlag].AsLoadFlag();
            }

            if (mappings.Keys.Contains(Field.DatItem_Value))
            {
                Value = mappings[Field.DatItem_Value];
            }

            // Handle DataArea-specific fields
            if (DataArea == null)
            {
                DataArea = new DataArea();
            }

            DataArea.SetFields(mappings);

            // Handle Part-specific fields
            if (Part == null)
            {
                Part = new Part();
            }

            Part.SetFields(mappings);

            #endregion
        }
示例#15
0
        /// <summary>
        /// Read game information
        /// </summary>
        /// <param name="reader">XmlReader 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(XmlReader reader, string filename, int indexId)
        {
            // Prepare all internal variables
            string     releaseNumber = string.Empty, duplicateid;
            long?      size     = null;
            List <Rom> datItems = new List <Rom>();
            Machine    machine  = new Machine();

            // If there's no subtree to the configuration, skip it
            if (reader == null)
            {
                return;
            }

            // Otherwise, add what is possible
            reader.MoveToContent();

            // Otherwise, read what we can from the header
            while (!reader.EOF)
            {
                // We only want elements
                if (reader.NodeType != XmlNodeType.Element)
                {
                    reader.Read();
                    continue;
                }

                // Get all games items
                switch (reader.Name.ToLowerInvariant())
                {
                case "imagenumber":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "releasenumber":
                    // TODO: Read this into a field
                    releaseNumber = reader.ReadElementContentAsString();
                    break;

                case "title":
                    machine.Name = reader.ReadElementContentAsString();
                    break;

                case "savetype":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "romsize":
                    size = Sanitizer.CleanLong(reader.ReadElementContentAsString());
                    break;

                case "publisher":
                    machine.Publisher = reader.ReadElementContentAsString();
                    break;

                case "location":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "sourcerom":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "language":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "files":
                    datItems = ReadFiles(reader.ReadSubtree(), releaseNumber, machine.Name, filename, indexId);

                    // Skip the files node now that we've processed it
                    reader.Skip();
                    break;

                case "im1crc":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "im2crc":
                    // TODO: Read this into a field
                    reader.ReadElementContentAsString();
                    break;

                case "comment":
                    machine.Comment = reader.ReadElementContentAsString();
                    break;

                case "duplicateid":
                    duplicateid = reader.ReadElementContentAsString();
                    if (duplicateid != "0")
                    {
                        machine.CloneOf = duplicateid;
                    }

                    break;

                default:
                    reader.Read();
                    break;
                }
            }

            // Add information accordingly for each rom
            for (int i = 0; i < datItems.Count; i++)
            {
                datItems[i].Size = size;
                datItems[i].CopyMachineInformation(machine);

                // Now process and add the rom
                ParseAddHelper(datItems[i]);
            }
        }
示例#16
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);
            }
        }
示例#17
0
        /// <summary>
        /// Read game/machine information
        /// </summary>
        /// <param name="reader">XmlReader to use to parse the machine</param>
        /// <param name="dirs">List of dirs to prepend to the game name</param>
        /// <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>
        private void ReadMachine(
            XmlReader reader,
            List <string> dirs,

            // Standard Dat parsing
            string filename,
            int indexId,

            // Miscellaneous
            bool keep)
        {
            // If we have an empty machine, skip it
            if (reader == null)
            {
                return;
            }

            // Otherwise, add what is possible
            reader.MoveToContent();

            string key           = string.Empty;
            string temptype      = reader.Name;
            bool   containsItems = false;

            // Create a new machine
            MachineType machineType = 0x0;

            if (reader.GetAttribute("isbios").AsYesNo() == true)
            {
                machineType |= MachineType.Bios;
            }

            if (reader.GetAttribute("isdevice").AsYesNo() == true) // Listxml-specific, used by older DATs
            {
                machineType |= MachineType.Device;
            }

            if (reader.GetAttribute("ismechanical").AsYesNo() == true) // Listxml-specific, used by older DATs
            {
                machineType |= MachineType.Mechanical;
            }

            string  dirsString = (dirs != null && dirs.Count() > 0 ? string.Join("/", dirs) + "/" : string.Empty);
            Machine machine    = new Machine
            {
                Name        = dirsString + reader.GetAttribute("name"),
                Description = dirsString + reader.GetAttribute("name"),
                SourceFile  = reader.GetAttribute("sourcefile"),
                Board       = reader.GetAttribute("board"),
                RebuildTo   = reader.GetAttribute("rebuildto"),
                Runnable    = reader.GetAttribute("runnable").AsRunnable(), // Used by older DATs

                CloneOf  = reader.GetAttribute("cloneof"),
                RomOf    = reader.GetAttribute("romof"),
                SampleOf = reader.GetAttribute("sampleof"),

                MachineType = (machineType == 0x0 ? MachineType.NULL : machineType),
            };

            if (Header.Type == "SuperDAT" && !keep)
            {
                string tempout = Regex.Match(machine.Name, @".*?\\(.*)").Groups[1].Value;
                if (!string.IsNullOrWhiteSpace(tempout))
                {
                    machine.Name = tempout;
                }
            }

            while (!reader.EOF)
            {
                // We only want elements
                if (reader.NodeType != XmlNodeType.Element)
                {
                    reader.Read();
                    continue;
                }

                // Get the roms from the machine
                switch (reader.Name)
                {
                case "comment":     // There can be multiple comments by spec
                    machine.Comment += reader.ReadElementContentAsString();
                    break;

                case "description":
                    machine.Description = reader.ReadElementContentAsString();
                    break;

                case "year":
                    machine.Year = reader.ReadElementContentAsString();
                    break;

                case "manufacturer":
                    machine.Manufacturer = reader.ReadElementContentAsString();
                    break;

                case "publisher":     // Not technically supported but used by some legacy DATs
                    machine.Publisher = reader.ReadElementContentAsString();
                    break;

                case "category":     // Not technically supported but used by some legacy DATs
                    machine.Category = reader.ReadElementContentAsString();
                    break;

                case "trurip":     // This is special metadata unique to EmuArc
                    ReadTruRip(reader.ReadSubtree(), machine);

                    // Skip the trurip node now that we've processed it
                    reader.Skip();
                    break;

                case "archive":
                    containsItems = true;

                    DatItem archive = new Archive
                    {
                        Name = reader.GetAttribute("name"),

                        Source = new Source
                        {
                            Index = indexId,
                            Name  = filename,
                        },
                    };

                    archive.CopyMachineInformation(machine);

                    // Now process and add the archive
                    key = ParseAddHelper(archive);

                    reader.Read();
                    break;

                case "biosset":
                    containsItems = true;

                    DatItem biosSet = new BiosSet
                    {
                        Name        = reader.GetAttribute("name"),
                        Description = reader.GetAttribute("description"),
                        Default     = reader.GetAttribute("default").AsYesNo(),

                        Source = new Source
                        {
                            Index = indexId,
                            Name  = filename,
                        },
                    };

                    biosSet.CopyMachineInformation(machine);

                    // Now process and add the biosSet
                    key = ParseAddHelper(biosSet);

                    reader.Read();
                    break;

                case "disk":
                    containsItems = true;

                    DatItem disk = new Disk
                    {
                        Name       = reader.GetAttribute("name"),
                        MD5        = reader.GetAttribute("md5"),
                        SHA1       = reader.GetAttribute("sha1"),
                        MergeTag   = reader.GetAttribute("merge"),
                        ItemStatus = reader.GetAttribute("status").AsItemStatus(),

                        Source = new Source
                        {
                            Index = indexId,
                            Name  = filename,
                        },
                    };

                    disk.CopyMachineInformation(machine);

                    // Now process and add the disk
                    key = ParseAddHelper(disk);

                    reader.Read();
                    break;

                case "media":
                    containsItems = true;

                    DatItem media = new Media
                    {
                        Name    = reader.GetAttribute("name"),
                        MD5     = reader.GetAttribute("md5"),
                        SHA1    = reader.GetAttribute("sha1"),
                        SHA256  = reader.GetAttribute("sha256"),
                        SpamSum = reader.GetAttribute("spamsum"),

                        Source = new Source
                        {
                            Index = indexId,
                            Name  = filename,
                        },
                    };

                    media.CopyMachineInformation(machine);

                    // Now process and add the media
                    key = ParseAddHelper(media);

                    reader.Read();
                    break;

                case "release":
                    containsItems = true;

                    DatItem release = new Release
                    {
                        Name     = reader.GetAttribute("name"),
                        Region   = reader.GetAttribute("region"),
                        Language = reader.GetAttribute("language"),
                        Date     = reader.GetAttribute("date"),
                        Default  = reader.GetAttribute("default").AsYesNo(),
                    };

                    release.CopyMachineInformation(machine);

                    // Now process and add the release
                    key = ParseAddHelper(release);

                    reader.Read();
                    break;

                case "rom":
                    containsItems = true;

                    DatItem rom = new Rom
                    {
                        Name = reader.GetAttribute("name"),
                        Size = Sanitizer.CleanLong(reader.GetAttribute("size")),
                        CRC  = reader.GetAttribute("crc"),
                        MD5  = reader.GetAttribute("md5"),
#if NET_FRAMEWORK
                        RIPEMD160 = reader.GetAttribute("ripemd160"),
#endif
                        SHA1       = reader.GetAttribute("sha1"),
                        SHA256     = reader.GetAttribute("sha256"),
                        SHA384     = reader.GetAttribute("sha384"),
                        SHA512     = reader.GetAttribute("sha512"),
                        SpamSum    = reader.GetAttribute("spamsum"),
                        MergeTag   = reader.GetAttribute("merge"),
                        ItemStatus = reader.GetAttribute("status").AsItemStatus(),
                        Date       = Sanitizer.CleanDate(reader.GetAttribute("date")),
                        Inverted   = reader.GetAttribute("inverted").AsYesNo(),

                        Source = new Source
                        {
                            Index = indexId,
                            Name  = filename,
                        },
                    };

                    rom.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(rom);

                    reader.Read();
                    break;

                case "sample":
                    containsItems = true;

                    DatItem sample = new Sample
                    {
                        Name = reader.GetAttribute("name"),

                        Source = new Source
                        {
                            Index = indexId,
                            Name  = filename,
                        },
                    };

                    sample.CopyMachineInformation(machine);

                    // Now process and add the sample
                    key = ParseAddHelper(sample);

                    reader.Read();
                    break;

                default:
                    reader.Read();
                    break;
                }
            }

            // 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);
            }
        }