/// <summary> /// Populate the dictionary from an INI file /// </summary> /// <param name="ini">Path to INI file to populate from</param> /// <remarks> /// The INI file format that is supported here is not exactly the same /// as a traditional one. This expects a MAME extras format, which usually /// doesn't contain key value pairs and always at least contains one section /// called `ROOT_FOLDER`. If that's the name of a section, then we assume /// the value is boolean. If there's another section name, then that is set /// as the value instead. /// </remarks> public bool PopulateFromFile(string ini) { // Prepare all intenral variables IniReader ir = new IniReader(ini) { ValidateRows = false }; bool foundRootFolder = false; // If we got a null reader, just return if (ir == null) { return(false); } // Otherwise, read the file to the end try { while (!ir.EndOfStream) { // Read in the next line and process ir.ReadNextLine(); // We don't care about whitespace or comments if (ir.RowType == IniRowType.None || ir.RowType == IniRowType.Comment) { continue; } // If we have a section, just read it in if (ir.RowType == IniRowType.SectionHeader) { // If we've found the start of the extras, set the flag if (string.Equals(ir.Section, "ROOT_FOLDER", StringComparison.OrdinalIgnoreCase)) { foundRootFolder = true; } continue; } // If we have a value, then we start populating the dictionary else if (foundRootFolder) { // Get the value and machine name string value = ir.Section; string machineName = ir.CurrentLine.Trim(); // If the section is "ROOT_FOLDER", then we use the value "true" instead. // This is done because some INI files use the name of the file as the // category to be assigned to the items included. if (value == "ROOT_FOLDER") { value = "true"; } // Add the new mapping Mappings[machineName] = value; } } } catch (Exception ex) { LoggerImpl.Warning(ex, $"Exception found while parsing '{ini}'"); return(false); } ir.Dispose(); return(true); }
/// <summary> /// Parse a RomCenter 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) { // Prepare all intenral variables IniReader ir = filename.GetIniReader(false); // If we got a null reader, just return if (ir == null) { return; } // Otherwise, read the file to the end try { ir.ReadNextLine(); while (!ir.EndOfStream) { // We don't care about whitespace or comments if (ir.RowType == IniRowType.None || ir.RowType == IniRowType.Comment) { ir.ReadNextLine(); continue; } // If we have a section if (ir.RowType == IniRowType.SectionHeader) { switch (ir.Section.ToLowerInvariant()) { case "credits": ReadCreditsSection(ir); break; case "dat": ReadDatSection(ir); break; case "emulator": ReadEmulatorSection(ir); break; case "games": ReadGamesSection(ir, filename, indexId); break; // Unknown section so we ignore it default: ir.ReadNextLine(); break; } } } } catch (Exception ex) { string message = $"'{filename}' - There was an error parsing line {ir.LineNumber} '{ir.CurrentLine}'"; logger.Error(ex, message); if (throwOnError) { ir.Dispose(); throw new Exception(message, ex); } } ir.Dispose(); }