/// <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="indexId">Index ID for the DAT</param> /// <param name="keep">True if full pathnames are to be kept, false otherwise (default)</param> /// <param name="throwOnError">True if the error that is thrown should be thrown back to the caller, false otherwise</param> protected override void ParseFile(string filename, int indexId, bool keep, bool throwOnError = false) { // Open a file reader Encoding enc = FileExtensions.GetEncoding(filename); SeparatedValueReader svr = new SeparatedValueReader(FileExtensions.TryOpenRead(filename), enc) { Header = true, Quotes = true, Separator = _delim, VerifyFieldCount = true, }; // If we're somehow at the end of the stream already, we can't do anything if (svr.EndOfStream) { return; } // Read in the header svr.ReadHeader(); // Loop through all of the data lines while (!svr.EndOfStream) { try { // Get the current line, split and parse svr.ReadNextLine(); // Create mapping dictionary var mappings = new Dictionary <Field, string>(); // Now we loop through and get values for everything for (int i = 0; i < svr.HeaderValues.Count; i++) { Field key = svr.HeaderValues[i].AsField(); string value = svr.Line[i]; mappings[key] = value; } // Set DatHeader fields DatHeader header = new DatHeader(); header.SetFields(mappings); Header.ConditionalCopy(header); // Set Machine and DatItem fields if (mappings.ContainsKey(Field.DatItem_Type)) { DatItem datItem = DatItem.Create(mappings[Field.DatItem_Type].AsItemType()); datItem.SetFields(mappings); datItem.Source = new Source(indexId, filename); ParseAddHelper(datItem); } } catch (Exception ex) { string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'"; logger.Error(ex, message); if (throwOnError) { svr.Dispose(); throw new Exception(message, ex); } } } svr.Dispose(); }
/// <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); } }