Ini file library
Monkey Forums/Monkey Beginners/Ini file library
| ||
Hi ! I'm searching a way to parse an short ini file. (i only want read values) So is there already a monkey code example to do this ? Many Thanks. |
| ||
Hi, I have written a module for this.'-------------------------------------------------------------------------- ' File Format: Custom ini file ' ' [ Section ] ' value = property ' multilineValue = {-- ' 0 1 2 3 4 5 6 7 8 ' 9 10 11 12 13 14 15 ' 16 17 18 19 20 21 ' --} '-------------------------------------------------------------------------- Strict Import mojo.app Class IniFile Method New(path:String) Local text:= LoadString(path) If text InitWithString(text, path) End End Method InitWithString:Void(iniString:String, name:String = "unnamed") Local lines:String[] = iniString.Split("~n") Local currentSection:IniSection Local multilineMode:Bool = False Local multilineData:String Local multilineProp:String sections = New StringMap<IniSection> AddSection(GLOBALS) currentSection = GetGlobals() For Local i:Int = 0 Until lines.Length Local line:String = lines[i].Trim() 'comments If line.Length = 0 Or line.StartsWith("#") 'Do nothing 'read multiple lines ElseIf multilineMode If line = MULTILINE_END multilineMode = False SetProperty(currentSection, multilineProp, multilineData) Else multilineData += line + " " End 'sections ElseIf line.StartsWith("[") If line.EndsWith("]") Local sectionID:String = line[1..-1].Trim() If sections.Contains(sectionID) GenerateError("Section " + sectionID + " has already been declared! (on line " + (i+1) + ")", name) Else AddSection(sectionID) currentSection = GetSection(sectionID) End Else GenerateError("Sections must be closed! (on line " + (i+1) + ")", name) End 'properties Else Local delimiterIndex:Int = line.Find(DELIMITER) If delimiterIndex = -1 GenerateError("Attempting to parse line " + (i+1) + ": " + line + "~nbut could not find the delimiter " + DELIMITER, name) End Local leftSide:String = line[0..delimiterIndex].Trim() Local rightSide:String = line[delimiterIndex+1..].Trim() If rightSide = MULTILINE_START multilineMode = True multilineProp = leftSide Else SetProperty(currentSection, leftSide, rightSide) End End Next If multilineMode GenerateError("You forgot to close a multiline property with ~q" + MULTILINE_START + "~q", name) End End Method Get:String(value:String, fallback:String = "") Local g:= GetGlobals() If g Return g.GetString(value, fallback) End Return fallback End Method GetSection:IniSection(section:String) Return sections.Get(section) End Method GetGlobals:IniSection() Return GetSection(GLOBALS) End Method AddSection:Void(id:String) Local s:= New IniSection s.id = id s.data = New StringMap<String> sections.Add(id, s) End Method SetProperty:Void(section:IniSection, prop:String, value:String) If Not section Then Return If section.data.Contains(prop) section.data.Set(prop, value) Else section.data.Add(prop, value) End End Private Field sections:StringMap<IniSection> = New StringMap<IniSection> Const DELIMITER:String = "=" Const GLOBALS:String = "_GLOBALS_" Const MULTILINE_START:String = "{--" Const MULTILINE_END:String = "--}" Method GenerateError:Void(message:String, name:String) Error("IniFile " + name + "~n" + message) sections = Null End 'could be used for quote parsing Method ParseString:String(rawString:String) Local trimmed:String = rawString.Trim() Local findQuote:Int = trimmed.Find("~q") If findQuote = -1 Then Return trimmed If trimmed[0] = "~q"[0] And trimmed[trimmed.Length-1] = "~q"[0] Return trimmed[1..trimmed.Length-1] End Return "" End End Class IniSection Method ID:String() Property Return id End Method GetString:String(prop:String, fallback:String = "") Local value:= data.Get(prop) If Not value Return fallback End Return value End Method GetInt:Int(prop:String, fallback:Int = 0) If Not data.Contains(prop) Return fallback End Return Int(data.Get(prop)) End Method GetFloat:Float(prop:String, fallback:Float = 0.0) If Not data.Contains(prop) Return fallback End Return Float(data.Get(prop)) End Method GetBool:Bool(prop:String, fallback:Bool = False) If Not data.Contains(prop) Return fallback End Local result:String = data.Get(prop) result = result.ToLower() Select result Case "0", "no", "false", "off" Return False Case "1", "yes", "true", "on" Return True End Return fallback End Private Field data:StringMap<String> Field id:String End Usage is like this Local ini:= New IniFile("path.ini") Local globals:= ini.GetGlobals() Print globals.GetInt("width") 'prints 100 Print globals.GetString("description") 'prints Hello World Local colors:= ini.GetSection("ColorSection") Print colors.GetFloat("red") 'prints 1.0 Print colors.GetFloat("green") 'prints 0.5 Print colors.GetFloat("blue") 'prints 0.2 Print colors.GetFloat("yellow", 0.8) 'prints 0.8 (fallback) because yelllow was not found assuming an ini file like this # This is a comment, values below are in the global section width = 100 description = Hello World [ ColorSection ] red = 1.0 green = 0.5 blue = 0.2 ----- edit: added convinience method Get() which will use the global section automatically. Local ini:= New IniFile("path.ini") Print ini.Get("width") 'prints 100 |
| ||
Many thanks to share this Shinkiro1 |