示例#1
0
        /// <summary>
        /// Remove fields with given values
        /// </summary>
        /// <param name="biosSet">BiosSet to remove fields from</param>
        private void RemoveFields(BiosSet biosSet)
        {
            if (DatItemFields.Contains(DatItemField.Description))
            {
                biosSet.Description = null;
            }

            if (DatItemFields.Contains(DatItemField.Default))
            {
                biosSet.Default = null;
            }
        }
        /// <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="sysid">System ID for the DAT</param>
        /// <param name="srcid">Source ID for the DAT</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        /// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
        /// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
        private void ReadMachine(
            XmlReader reader,
            List <string> dirs,

            // Standard Dat parsing
            string filename,
            int sysid,
            int srcid,

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

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

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

            // Create a new machine
            MachineType machineType = MachineType.NULL;

            if (Utilities.GetYesNo(reader.GetAttribute("isbios")) == true)
            {
                machineType |= MachineType.Bios;
            }
            if (Utilities.GetYesNo(reader.GetAttribute("isdevice")) == true) // Listxml-specific, used by older DATs
            {
                machineType |= MachineType.Device;
            }
            if (Utilities.GetYesNo(reader.GetAttribute("ismechanical")) == true) // Listxml-specific, used by older DATs
            {
                machineType |= MachineType.Mechanical;
            }

            string  dirsString = (dirs != null && dirs.Count() > 0 ? string.Join("/", dirs) + "/" : "");
            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    = Utilities.GetYesNo(reader.GetAttribute("runnable")), // Listxml-specific, used by older DATs

                Comment = "",

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

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

            if (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 "trurip":     // This is special metadata unique to TruRip
                    ReadTruRip(reader.ReadSubtree(), machine);

                    // Skip the trurip node now that we've processed it
                    reader.Skip();
                    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  = Utilities.GetYesNo(reader.GetAttribute("default")),
                    };

                    release.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(release, clean, remUnicode);

                    reader.Read();
                    break;

                case "biosset":
                    containsItems = true;

                    DatItem biosset = new BiosSet
                    {
                        Name        = reader.GetAttribute("name"),
                        Description = reader.GetAttribute("description"),
                        Default     = Utilities.GetYesNo(reader.GetAttribute("default")),

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    biosset.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(biosset, clean, remUnicode);

                    reader.Read();
                    break;

                case "rom":
                    containsItems = true;

                    DatItem rom = new Rom
                    {
                        Name       = reader.GetAttribute("name"),
                        Size       = Utilities.GetSize(reader.GetAttribute("size")),
                        CRC        = Utilities.CleanHashData(reader.GetAttribute("crc"), Constants.CRCLength),
                        MD5        = Utilities.CleanHashData(reader.GetAttribute("md5"), Constants.MD5Length),
                        SHA1       = Utilities.CleanHashData(reader.GetAttribute("sha1"), Constants.SHA1Length),
                        SHA256     = Utilities.CleanHashData(reader.GetAttribute("sha256"), Constants.SHA256Length),
                        SHA384     = Utilities.CleanHashData(reader.GetAttribute("sha384"), Constants.SHA384Length),
                        SHA512     = Utilities.CleanHashData(reader.GetAttribute("sha512"), Constants.SHA512Length),
                        MergeTag   = reader.GetAttribute("merge"),
                        ItemStatus = Utilities.GetItemStatus(reader.GetAttribute("status")),
                        Date       = Utilities.GetDate(reader.GetAttribute("date")),

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    rom.CopyMachineInformation(machine);

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

                    reader.Read();
                    break;

                case "disk":
                    containsItems = true;

                    DatItem disk = new Disk
                    {
                        Name       = reader.GetAttribute("name"),
                        MD5        = Utilities.CleanHashData(reader.GetAttribute("md5"), Constants.MD5Length),
                        SHA1       = Utilities.CleanHashData(reader.GetAttribute("sha1"), Constants.SHA1Length),
                        SHA256     = Utilities.CleanHashData(reader.GetAttribute("sha256"), Constants.SHA256Length),
                        SHA384     = Utilities.CleanHashData(reader.GetAttribute("sha384"), Constants.SHA384Length),
                        SHA512     = Utilities.CleanHashData(reader.GetAttribute("sha512"), Constants.SHA512Length),
                        MergeTag   = reader.GetAttribute("merge"),
                        ItemStatus = Utilities.GetItemStatus(reader.GetAttribute("status")),

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    disk.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(disk, clean, remUnicode);

                    reader.Read();
                    break;

                case "sample":
                    containsItems = true;

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

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    samplerom.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(samplerom, clean, remUnicode);

                    reader.Read();
                    break;

                case "archive":
                    containsItems = true;

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

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    archiverom.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(archiverom, clean, remUnicode);

                    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()
                {
                    SystemID = sysid,
                    System   = filename,
                    SourceID = srcid,
                };
                blank.CopyMachineInformation(machine);

                // Now process and add the rom
                ParseAddHelper(blank, clean, remUnicode);
            }
        }
示例#3
0
        /// <summary>
        /// Read directory 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="sysid">System ID for the DAT</param>
        /// <param name="srcid">Source ID for the DAT</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        /// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
        /// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
        private bool ReadDirectory(XmlReader reader,
                                   List <string> parent,

                                   // Standard Dat parsing
                                   string filename,
                                   int sysid,
                                   int srcid,

                                   // Miscellaneous
                                   bool keep,
                                   bool clean,
                                   bool remUnicode)
        {
            // Prepare all internal variables
            XmlReader  flagreader;
            bool       empty = true;
            string     key = "", date = "";
            long       size = -1;
            ItemStatus its  = ItemStatus.None;

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

            string foldername = (reader.GetAttribute("name") ?? "");

            if (!String.IsNullOrWhiteSpace(foldername))
            {
                parent.Add(foldername);
            }

            // Otherwise, read what we can from the directory
            while (!reader.EOF)
            {
                // If we're ending a folder or game, take care of possibly empty games and removing from the parent
                if (reader.NodeType == XmlNodeType.EndElement && (reader.Name == "directory" || reader.Name == "dir"))
                {
                    // If we didn't find any items in the folder, make sure to add the blank rom
                    if (empty)
                    {
                        string tempgame = String.Join("\\", parent);
                        Rom    rom      = new Rom("null", tempgame, omitFromScan: Hash.DeepHashes);                 // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually

                        // Now process and add the rom
                        key = ParseAddHelper(rom, clean, remUnicode);
                    }

                    // Regardless, end the current folder
                    int parentcount = parent.Count;
                    if (parentcount == 0)
                    {
                        Globals.Logger.Verbose("Empty parent '{0}' found in '{1}'", String.Join("\\", parent), filename);
                        empty = true;
                    }

                    // If we have an end folder element, remove one item from the parent, if possible
                    if (parentcount > 0)
                    {
                        parent.RemoveAt(parent.Count - 1);
                        if (keep && parentcount > 1)
                        {
                            Type = (String.IsNullOrWhiteSpace(Type) ? "SuperDAT" : Type);
                        }
                    }
                }

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

                // Get all directory items
                string content = "";
                switch (reader.Name)
                {
                // Directories can contain directories
                case "dir":
                case "directory":
                    ReadDirectory(reader.ReadSubtree(), parent, filename, sysid, srcid, keep, clean, remUnicode);

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

                case "file":
                    empty = false;

                    // If the rom is itemStatus, flag it
                    its        = ItemStatus.None;
                    flagreader = reader.ReadSubtree();

                    // If the subtree is empty, skip it
                    if (flagreader == null)
                    {
                        reader.Skip();
                        continue;
                    }

                    while (!flagreader.EOF)
                    {
                        // We only want elements
                        if (flagreader.NodeType != XmlNodeType.Element || flagreader.Name == "flags")
                        {
                            flagreader.Read();
                            continue;
                        }

                        switch (flagreader.Name)
                        {
                        case "flag":
                            if (flagreader.GetAttribute("name") != null && flagreader.GetAttribute("value") != null)
                            {
                                content = flagreader.GetAttribute("value");
                                its     = Utilities.GetItemStatus(flagreader.GetAttribute("name"));
                            }
                            break;
                        }

                        flagreader.Read();
                    }

                    // If the rom has a Date attached, read it in and then sanitize it
                    date = Utilities.GetDate(reader.GetAttribute("date"));

                    // Take care of hex-sized files
                    size = Utilities.GetSize(reader.GetAttribute("size"));

                    Machine dir = new Machine();

                    // Get the name of the game from the parent
                    dir.Name        = String.Join("\\", parent);
                    dir.Description = dir.Name;

                    DatItem datItem;
                    switch (reader.GetAttribute("type").ToLowerInvariant())
                    {
                    case "archive":
                        datItem = new Archive
                        {
                            Name = reader.GetAttribute("name"),

                            SystemID = sysid,
                            System   = filename,
                            SourceID = srcid,
                        };
                        break;

                    case "biosset":
                        datItem = new BiosSet
                        {
                            Name        = reader.GetAttribute("name"),
                            Description = reader.GetAttribute("description"),
                            Default     = Utilities.GetYesNo(reader.GetAttribute("default")),

                            SystemID = sysid,
                            System   = filename,
                            SourceID = srcid,
                        };
                        break;

                    case "disk":
                        datItem = new Disk
                        {
                            Name       = reader.GetAttribute("name"),
                            MD5        = Utilities.CleanHashData(reader.GetAttribute("md5"), Constants.MD5Length),
                            SHA1       = Utilities.CleanHashData(reader.GetAttribute("sha1"), Constants.SHA1Length),
                            SHA256     = Utilities.CleanHashData(reader.GetAttribute("sha256"), Constants.SHA256Length),
                            SHA384     = Utilities.CleanHashData(reader.GetAttribute("sha384"), Constants.SHA384Length),
                            SHA512     = Utilities.CleanHashData(reader.GetAttribute("sha512"), Constants.SHA512Length),
                            ItemStatus = its,

                            SystemID = sysid,
                            System   = filename,
                            SourceID = srcid,
                        };
                        break;

                    case "release":
                        datItem = new Release
                        {
                            Name     = reader.GetAttribute("name"),
                            Region   = reader.GetAttribute("region"),
                            Language = reader.GetAttribute("language"),
                            Date     = reader.GetAttribute("date"),
                            Default  = Utilities.GetYesNo(reader.GetAttribute("default")),

                            SystemID = sysid,
                            System   = filename,
                            SourceID = srcid,
                        };
                        break;

                    case "rom":
                        datItem = new Rom
                        {
                            Name       = reader.GetAttribute("name"),
                            Size       = size,
                            CRC        = Utilities.CleanHashData(reader.GetAttribute("crc"), Constants.CRCLength),
                            MD5        = Utilities.CleanHashData(reader.GetAttribute("md5"), Constants.MD5Length),
                            SHA1       = Utilities.CleanHashData(reader.GetAttribute("sha1"), Constants.SHA1Length),
                            SHA256     = Utilities.CleanHashData(reader.GetAttribute("sha256"), Constants.SHA256Length),
                            SHA384     = Utilities.CleanHashData(reader.GetAttribute("sha384"), Constants.SHA384Length),
                            SHA512     = Utilities.CleanHashData(reader.GetAttribute("sha512"), Constants.SHA512Length),
                            ItemStatus = its,
                            Date       = date,

                            SystemID = sysid,
                            System   = filename,
                            SourceID = srcid,
                        };
                        break;

                    case "sample":
                        datItem = new Sample
                        {
                            Name = reader.GetAttribute("name"),

                            SystemID = sysid,
                            System   = filename,
                            SourceID = srcid,
                        };
                        break;

                    default:
                        // By default, create a new Blank, just in case
                        datItem = new Blank();
                        break;
                    }

                    datItem?.CopyMachineInformation(dir);

                    // Now process and add the rom
                    key = ParseAddHelper(datItem, clean, remUnicode);

                    reader.Read();
                    break;
                }
            }

            return(empty);
        }
示例#4
0
        /// <summary>
        /// Read machine information
        /// </summary>
        /// <param name="reader">XmlReader representing a machine block</param>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="sysid">System ID for the DAT</param>
        /// <param name="srcid">Source ID for the DAT</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        /// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
        /// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
        private void ReadMachine(
            XmlReader reader,

            // Standard Dat parsing
            string filename,
            int sysid,
            int srcid,

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

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

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

            // Create a new machine
            MachineType machineType = MachineType.NULL;

            if (Utilities.GetYesNo(reader.GetAttribute("isbios")) == true)
            {
                machineType |= MachineType.Bios;
            }
            if (Utilities.GetYesNo(reader.GetAttribute("isdevice")) == true)
            {
                machineType |= MachineType.Device;
            }
            if (Utilities.GetYesNo(reader.GetAttribute("ismechanical")) == true)
            {
                machineType |= MachineType.Mechanical;
            }

            Machine machine = new Machine
            {
                Name        = reader.GetAttribute("name"),
                Description = reader.GetAttribute("name"),
                SourceFile  = reader.GetAttribute("sourcefile"),
                Runnable    = Utilities.GetYesNo(reader.GetAttribute("runnable")),

                Comment = "",

                CloneOf     = reader.GetAttribute("cloneof") ?? "",
                RomOf       = reader.GetAttribute("romof") ?? "",
                SampleOf    = reader.GetAttribute("sampleof") ?? "",
                Devices     = new List <string>(),
                SlotOptions = new List <string>(),

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

            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 "description":
                    machine.Description = reader.ReadElementContentAsString();
                    break;

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

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

                case "biosset":
                    containsItems = true;

                    DatItem biosset = new BiosSet
                    {
                        Name        = reader.GetAttribute("name"),
                        Description = reader.GetAttribute("description"),
                        Default     = Utilities.GetYesNo(reader.GetAttribute("default")),

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    biosset.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(biosset, clean, remUnicode);

                    reader.Read();
                    break;

                case "rom":
                    containsItems = true;

                    DatItem rom = new Rom
                    {
                        Name       = reader.GetAttribute("name"),
                        Bios       = reader.GetAttribute("bios"),
                        Size       = Utilities.GetSize(reader.GetAttribute("size")),
                        CRC        = Utilities.CleanHashData(reader.GetAttribute("crc"), Constants.CRCLength),
                        MD5        = Utilities.CleanHashData(reader.GetAttribute("md5"), Constants.MD5Length),
                        SHA1       = Utilities.CleanHashData(reader.GetAttribute("sha1"), Constants.SHA1Length),
                        SHA256     = Utilities.CleanHashData(reader.GetAttribute("sha256"), Constants.SHA256Length),
                        SHA384     = Utilities.CleanHashData(reader.GetAttribute("sha384"), Constants.SHA384Length),
                        SHA512     = Utilities.CleanHashData(reader.GetAttribute("sha512"), Constants.SHA512Length),
                        MergeTag   = reader.GetAttribute("merge"),
                        Region     = reader.GetAttribute("region"),
                        Offset     = reader.GetAttribute("offset"),
                        ItemStatus = Utilities.GetItemStatus(reader.GetAttribute("status")),
                        Optional   = Utilities.GetYesNo(reader.GetAttribute("optional")),

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    rom.CopyMachineInformation(machine);

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

                    reader.Read();
                    break;

                case "disk":
                    containsItems = true;

                    DatItem disk = new Disk
                    {
                        Name       = reader.GetAttribute("name"),
                        MD5        = Utilities.CleanHashData(reader.GetAttribute("md5"), Constants.MD5Length),
                        SHA1       = Utilities.CleanHashData(reader.GetAttribute("sha1"), Constants.SHA1Length),
                        SHA256     = Utilities.CleanHashData(reader.GetAttribute("sha256"), Constants.SHA256Length),
                        SHA384     = Utilities.CleanHashData(reader.GetAttribute("sha384"), Constants.SHA384Length),
                        SHA512     = Utilities.CleanHashData(reader.GetAttribute("sha512"), Constants.SHA512Length),
                        MergeTag   = reader.GetAttribute("merge"),
                        Region     = reader.GetAttribute("region"),
                        Index      = reader.GetAttribute("index"),
                        Writable   = Utilities.GetYesNo(reader.GetAttribute("writable")),
                        ItemStatus = Utilities.GetItemStatus(reader.GetAttribute("status")),
                        Optional   = Utilities.GetYesNo(reader.GetAttribute("optional")),

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    disk.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(disk, clean, remUnicode);

                    reader.Read();
                    break;

                case "device_ref":
                    string device_ref_name = reader.GetAttribute("name");
                    if (!machine.Devices.Contains(device_ref_name))
                    {
                        machine.Devices.Add(device_ref_name);
                    }

                    reader.Read();
                    break;

                case "sample":
                    containsItems = true;

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

                        SystemID = sysid,
                        System   = filename,
                        SourceID = srcid,
                    };

                    samplerom.CopyMachineInformation(machine);

                    // Now process and add the rom
                    key = ParseAddHelper(samplerom, clean, remUnicode);

                    reader.Read();
                    break;

                case "chip":
                    // string chip_name = reader.GetAttribute("name");
                    // string chip_tag = reader.GetAttribute("tag");
                    // string chip_type = reader.GetAttribute("type"); // (cpu|audio)
                    // string chip_clock = reader.GetAttribute("clock");

                    reader.Read();
                    break;

                case "display":
                    // string display_tag = reader.GetAttribute("tag");
                    // string display_type = reader.GetAttribute("type"); // (raster|vector|lcd|svg|unknown)
                    // string display_rotate = reader.GetAttribute("rotate"); // (0|90|180|270)
                    // bool? display_flipx = Utilities.GetYesNo(reader.GetAttribute("flipx"));
                    // string display_width = reader.GetAttribute("width");
                    // string display_height = reader.GetAttribute("height");
                    // string display_refresh = reader.GetAttribute("refresh");
                    // string display_pixclock = reader.GetAttribute("pixclock");
                    // string display_htotal = reader.GetAttribute("htotal");
                    // string display_hbend = reader.GetAttribute("hbend");
                    // string display_hbstart = reader.GetAttribute("hbstart");
                    // string display_vtotal = reader.GetAttribute("vtotal");
                    // string display_vbend = reader.GetAttribute("vbend");
                    // string display_vbstart = reader.GetAttribute("vbstart");

                    reader.Read();
                    break;

                case "sound":
                    // string sound_channels = reader.GetAttribute("channels");

                    reader.Read();
                    break;

                case "condition":
                    // string condition_tag = reader.GetAttribute("tag");
                    // string condition_mask = reader.GetAttribute("mask");
                    // string condition_relation = reader.GetAttribute("relation"); // (eq|ne|gt|le|lt|ge)
                    // string condition_value = reader.GetAttribute("value");

                    reader.Read();
                    break;

                case "input":
                    // bool? input_service = Utilities.GetYesNo(reader.GetAttribute("service"));
                    // bool? input_tilt = Utilities.GetYesNo(reader.GetAttribute("tilt"));
                    // string input_players = reader.GetAttribute("players");
                    // string input_coins = reader.GetAttribute("coins");

                    // // While the subtree contains <control> elements...
                    // string control_type = reader.GetAttribute("type");
                    // string control_player = reader.GetAttribute("player");
                    // string control_buttons = reader.GetAttribute("buttons");
                    // string control_regbuttons = reader.GetAttribute("regbuttons");
                    // string control_minimum = reader.GetAttribute("minimum");
                    // string control_maximum = reader.GetAttribute("maximum");
                    // string control_sensitivity = reader.GetAttribute("sensitivity");
                    // string control_keydelta = reader.GetAttribute("keydelta");
                    // bool? control_reverse = Utilities.GetYesNo(reader.GetAttribute("reverse"));
                    // string control_ways = reader.GetAttribute("ways");
                    // string control_ways2 = reader.GetAttribute("ways2");
                    // string control_ways3 = reader.GetAttribute("ways3");

                    reader.Skip();
                    break;

                case "dipswitch":
                    // string dipswitch_name = reader.GetAttribute("name");
                    // string dipswitch_tag = reader.GetAttribute("tag");
                    // string dipswitch_mask = reader.GetAttribute("mask");

                    // // While the subtree contains <diplocation> elements...
                    // string diplocation_name = reader.GetAttribute("name");
                    // string diplocation_number = reader.GetAttribute("number");
                    // bool? diplocation_inverted = Utilities.GetYesNo(reader.GetAttribute("inverted"));

                    // // While the subtree contains <dipvalue> elements...
                    // string dipvalue_name = reader.GetAttribute("name");
                    // string dipvalue_value = reader.GetAttribute("value");
                    // bool? dipvalue_default = Utilities.GetYesNo(reader.GetAttribute("default"));

                    reader.Skip();
                    break;

                case "configuration":
                    // string configuration_name = reader.GetAttribute("name");
                    // string configuration_tag = reader.GetAttribute("tag");
                    // string configuration_mask = reader.GetAttribute("mask");

                    // // While the subtree contains <conflocation> elements...
                    // string conflocation_name = reader.GetAttribute("name");
                    // string conflocation_number = reader.GetAttribute("number");
                    // bool? conflocation_inverted = Utilities.GetYesNo(reader.GetAttribute("inverted"));

                    // // While the subtree contains <confsetting> elements...
                    // string confsetting_name = reader.GetAttribute("name");
                    // string confsetting_value = reader.GetAttribute("value");
                    // bool? confsetting_default = Utilities.GetYesNo(reader.GetAttribute("default"));

                    reader.Skip();
                    break;

                case "port":
                    // string port_tag = reader.GetAttribute("tag");

                    // // While the subtree contains <analog> elements...
                    // string analog_mask = reader.GetAttribute("mask");

                    reader.Skip();
                    break;

                case "adjuster":
                    // string adjuster_name = reader.GetAttribute("name");
                    // bool? adjuster_default = Utilities.GetYesNo(reader.GetAttribute("default"));

                    // // For the one possible <condition> element...
                    // string condition_tag = reader.GetAttribute("tag");
                    // string condition_mask = reader.GetAttribute("mask");
                    // string condition_relation = reader.GetAttribute("relation"); // (eq|ne|gt|le|lt|ge)
                    // string condition_value = reader.GetAttribute("value");

                    reader.Skip();
                    break;

                case "driver":
                    // string driver_status = reader.GetAttribute("status"); // (good|imperfect|preliminary)
                    // string driver_emulation = reader.GetAttribute("emulation"); // (good|imperfect|preliminary)
                    // string driver_cocktail = reader.GetAttribute("cocktail"); // (good|imperfect|preliminary)
                    // string driver_savestate = reader.GetAttribute("savestate"); // (supported|unsupported)

                    reader.Read();
                    break;

                case "feature":
                    // string feature_type = reader.GetAttribute("type"); // (protection|palette|graphics|sound|controls|keyboard|mouse|microphone|camera|disk|printer|lan|wan|timing)
                    // string feature_status = reader.GetAttribute("status"); // (unemulated|imperfect)
                    // string feature_overall = reader.GetAttribute("overall"); // (unemulated|imperfect)

                    reader.Read();
                    break;

                case "device":
                    // string device_type = reader.GetAttribute("type");
                    // string device_tag = reader.GetAttribute("tag");
                    // string device_fixed_image = reader.GetAttribute("fixed_image");
                    // string device_mandatory = reader.GetAttribute("mandatory");
                    // string device_interface = reader.GetAttribute("interface");

                    // // For the one possible <instance> element...
                    // string instance_name = reader.GetAttribute("name");
                    // string instance_briefname = reader.GetAttribute("briefname");

                    // // While the subtree contains <extension> elements...
                    // string extension_name = reader.GetAttribute("name");

                    reader.Skip();
                    break;

                case "slot":
                    // string slot_name = reader.GetAttribute("name");
                    ReadSlot(reader.ReadSubtree(), machine);

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

                case "softwarelist":
                    // string softwarelist_name = reader.GetAttribute("name");
                    // string softwarelist_status = reader.GetAttribute("status"); // (original|compatible)
                    // string softwarelist_filter = reader.GetAttribute("filter");

                    reader.Read();
                    break;

                case "ramoption":
                    // string ramoption_default = reader.GetAttribute("default");

                    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()
                {
                    SystemID = sysid,
                    System   = filename,
                    SourceID = srcid,
                };
                blank.CopyMachineInformation(machine);

                // Now process and add the rom
                ParseAddHelper(blank, clean, remUnicode);
            }
        }
示例#5
0
        /// <summary>
        /// Parse a character-separated value DAT and return all found games and roms within
        /// </summary>
        /// <param name="filename">Name of the file to be parsed</param>
        /// <param name="sysid">System ID for the DAT</param>
        /// <param name="srcid">Source ID for the DAT</param>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        /// <param name="clean">True if game names are sanitized, false otherwise (default)</param>
        /// <param name="remUnicode">True if we should remove non-ASCII characters from output, false otherwise (default)</param>
        public override void ParseFile(
            // Standard Dat parsing
            string filename,
            int sysid,
            int srcid,

            // Miscellaneous
            bool keep,
            bool clean,
            bool remUnicode)
        {
            // Open a file reader
            Encoding     enc = Utilities.GetEncoding(filename);
            StreamReader sr  = new StreamReader(Utilities.TryOpenRead(filename), enc);

            // Create an empty list of columns to parse though
            List <string> columns = new List <string>();

            long linenum = -1;

            while (!sr.EndOfStream)
            {
                string line = sr.ReadLine();
                linenum++;

                // Parse the first line, getting types from the column names
                if (linenum == 0)
                {
                    string[] parsedColumns = line.Split(_delim);
                    foreach (string parsed in parsedColumns)
                    {
                        switch (parsed.ToLowerInvariant().Trim('"'))
                        {
                        case "file":
                        case "filename":
                        case "file name":
                            columns.Add("DatFile.FileName");
                            break;

                        case "internal name":
                            columns.Add("DatFile.Name");
                            break;

                        case "description":
                        case "dat description":
                            columns.Add("DatFile.Description");
                            break;

                        case "game name":
                        case "game":
                        case "machine":
                            columns.Add("Machine.Name");
                            break;

                        case "game description":
                            columns.Add("Description");
                            break;

                        case "type":
                            columns.Add("DatItem.Type");
                            break;

                        case "rom":
                        case "romname":
                        case "rom name":
                        case "name":
                            columns.Add("Rom.Name");
                            break;

                        case "disk":
                        case "diskname":
                        case "disk name":
                            columns.Add("Disk.Name");
                            break;

                        case "size":
                            columns.Add("DatItem.Size");
                            break;

                        case "crc":
                        case "crc hash":
                            columns.Add("DatItem.CRC");
                            break;

                        case "md5":
                        case "md5 hash":
                            columns.Add("DatItem.MD5");
                            break;

                        case "sha1":
                        case "sha-1":
                        case "sha1 hash":
                        case "sha-1 hash":
                            columns.Add("DatItem.SHA1");
                            break;

                        case "sha256":
                        case "sha-256":
                        case "sha256 hash":
                        case "sha-256 hash":
                            columns.Add("DatItem.SHA256");
                            break;

                        case "sha384":
                        case "sha-384":
                        case "sha384 hash":
                        case "sha-384 hash":
                            columns.Add("DatItem.SHA384");
                            break;

                        case "sha512":
                        case "sha-512":
                        case "sha512 hash":
                        case "sha-512 hash":
                            columns.Add("DatItem.SHA512");
                            break;

                        case "nodump":
                        case "no dump":
                        case "status":
                        case "item status":
                            columns.Add("DatItem.Nodump");
                            break;

                        case "date":
                            columns.Add("DatItem.Date");
                            break;

                        default:
                            columns.Add("INVALID");
                            break;
                        }
                    }

                    continue;
                }

                // Otherwise, we want to split the line and parse
                string[] parsedLine = line.Split(_delim);

                // If the line doesn't have the correct number of columns, we log and skip
                if (parsedLine.Length != columns.Count)
                {
                    Globals.Logger.Warning("Malformed line found in '{0}' at line {1}", filename, linenum);
                    continue;
                }

                // Set the output item information
                string machineName = null, machineDesc = null, name = null, crc = null, md5 = null, sha1 = null,
                       sha256 = null, sha384 = null, sha512 = null, date = null;
                long       size     = -1;
                ItemType   itemType = ItemType.Rom;
                ItemStatus status   = ItemStatus.None;

                // Now we loop through and get values for everything
                for (int i = 0; i < columns.Count; i++)
                {
                    string value = parsedLine[i].Trim('"');
                    switch (columns[i])
                    {
                    case "DatFile.FileName":
                        FileName = (String.IsNullOrWhiteSpace(FileName) ? value : FileName);
                        break;

                    case "DatFile.Name":
                        Name = (String.IsNullOrWhiteSpace(Name) ? value : Name);
                        break;

                    case "DatFile.Description":
                        Description = (String.IsNullOrWhiteSpace(Description) ? value : Description);
                        break;

                    case "Machine.Name":
                        machineName = value;
                        break;

                    case "Description":
                        machineDesc = value;
                        break;

                    case "DatItem.Type":
                        itemType = Utilities.GetItemType(value) ?? ItemType.Rom;
                        break;

                    case "Rom.Name":
                    case "Disk.Name":
                        name = String.IsNullOrWhiteSpace(value) ? name : value;
                        break;

                    case "DatItem.Size":
                        if (!Int64.TryParse(value, out size))
                        {
                            size = -1;
                        }
                        break;

                    case "DatItem.CRC":
                        crc = Utilities.CleanHashData(value, Constants.CRCLength);
                        break;

                    case "DatItem.MD5":
                        md5 = Utilities.CleanHashData(value, Constants.MD5Length);
                        break;

                    case "DatItem.SHA1":
                        sha1 = Utilities.CleanHashData(value, Constants.SHA1Length);
                        break;

                    case "DatItem.SHA256":
                        sha256 = Utilities.CleanHashData(value, Constants.SHA256Length);
                        break;

                    case "DatItem.SHA384":
                        sha384 = Utilities.CleanHashData(value, Constants.SHA384Length);
                        break;

                    case "DatItem.SHA512":
                        sha512 = Utilities.CleanHashData(value, Constants.SHA512Length);
                        break;

                    case "DatItem.Nodump":
                        status = Utilities.GetItemStatus(value);
                        break;

                    case "DatItem.Date":
                        date = value;
                        break;
                    }
                }

                // And now we populate and add the new item
                switch (itemType)
                {
                case ItemType.Archive:
                    Archive archive = new Archive()
                    {
                        Name = name,

                        MachineName        = machineName,
                        MachineDescription = machineDesc,
                    };

                    ParseAddHelper(archive, clean, remUnicode);
                    break;

                case ItemType.BiosSet:
                    BiosSet biosset = new BiosSet()
                    {
                        Name = name,

                        MachineName = machineName,
                        Description = machineDesc,
                    };

                    ParseAddHelper(biosset, clean, remUnicode);
                    break;

                case ItemType.Disk:
                    Disk disk = new Disk()
                    {
                        Name   = name,
                        MD5    = md5,
                        SHA1   = sha1,
                        SHA256 = sha256,
                        SHA384 = sha384,
                        SHA512 = sha512,

                        MachineName        = machineName,
                        MachineDescription = machineDesc,

                        ItemStatus = status,
                    };

                    ParseAddHelper(disk, clean, remUnicode);
                    break;

                case ItemType.Release:
                    Release release = new Release()
                    {
                        Name = name,

                        MachineName        = machineName,
                        MachineDescription = machineDesc,
                    };

                    ParseAddHelper(release, clean, remUnicode);
                    break;

                case ItemType.Rom:
                    Rom rom = new Rom()
                    {
                        Name   = name,
                        Size   = size,
                        CRC    = crc,
                        MD5    = md5,
                        SHA1   = sha1,
                        SHA256 = sha256,
                        SHA384 = sha384,
                        SHA512 = sha512,
                        Date   = date,

                        MachineName        = machineName,
                        MachineDescription = machineDesc,

                        ItemStatus = status,
                    };

                    ParseAddHelper(rom, clean, remUnicode);
                    break;

                case ItemType.Sample:
                    Sample sample = new Sample()
                    {
                        Name = name,

                        MachineName        = machineName,
                        MachineDescription = machineDesc,
                    };

                    ParseAddHelper(sample, clean, remUnicode);
                    break;
                }
            }
        }
示例#6
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="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>
        /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param>
        private void ReadMachine(
            XmlReader reader,
            List <string> dirs,
            bool statsOnly,

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

            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
                    ParseAddHelper(archive, statsOnly);

                    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
                    ParseAddHelper(biosSet, statsOnly);

                    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
                    ParseAddHelper(disk, statsOnly);

                    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
                    ParseAddHelper(media, statsOnly);

                    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
                    ParseAddHelper(release, statsOnly);

                    reader.Read();
                    break;

                case "rom":
                    containsItems = true;

                    DatItem rom = new Rom
                    {
                        Name       = reader.GetAttribute("name"),
                        Size       = Utilities.CleanLong(reader.GetAttribute("size")),
                        CRC        = reader.GetAttribute("crc"),
                        MD5        = reader.GetAttribute("md5"),
                        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       = 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
                    ParseAddHelper(rom, statsOnly);

                    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
                    ParseAddHelper(sample, statsOnly);

                    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, statsOnly);
            }
        }