1 2 # 3 # ini.rb - read and write ini files 4 # 5 # Copyright (C) 2007 Jeena Paradies 6 # License: GPL 7 # Author: Jeena Paradies (info@jeenaparadies.net) 8 # 9 # == Overview 10 # 11 # This file provides a read-wite handling for ini files. 12 # The data of a ini file is represented by a object which 13 # is populated with strings. 14 15 class Ini 16 17 # Class with methods to read from and write into ini files. 18 # 19 # A ini file is a text file in a specific format, 20 # it may include several fields which are sparated by 21 # field headlines which are enclosured by "[]". 22 # Each field may include several key-value pairs. 23 # 24 # Each key-value pair is represented by one line and 25 # the value is sparated from the key by a "=". 26 # 27 # == Examples 28 # 29 # === Example ini file 30 # 31 # # this is the first comment which will be saved in the comment attribute 32 # mail=info@example.com 33 # domain=example.com # this is a comment which will not be saved 34 # [database] 35 # db=example 36 # user=john 37 # passwd=very-secure 38 # host=localhost 39 # # this is another comment 40 # [filepaths] 41 # tmp=/tmp/example 42 # lib=/home/john/projects/example/lib 43 # htdocs=/home/john/projects/example/htdocs 44 # [ texts ] 45 # wellcome=Wellcome on my new website! 46 # Website description = This is only a example. # and another comment 47 # 48 # === Example object 49 # 50 # A Ini#comment stores: 51 # "this is the first comment which will be saved in the comment attribute" 52 # 53 # A Ini object stores: 54 # 55 # { 56 # "mail" => "info@example.com", 57 # "domain" => "example.com", 58 # "database" => { 59 # "db" => "example", 60 # "user" => "john", 61 # "passwd" => "very-secure", 62 # "host" => "localhost" 63 # }, 64 # "filepaths" => { 65 # "tmp" => "/tmp/example", 66 # "lib" => "/home/john/projects/example/lib", 67 # "htdocs" => "/home/john/projects/example/htdocs" 68 # } 69 # "texts" => { 70 # "wellcome" => "Wellcome on my new website!", 71 # "Website description" => "This is only a example." 72 # } 73 # } 74 # 75 # As you can see this module gets rid of all comments, linebreaks 76 # and unnecessary spaces at the beginning and the end of each 77 # field headline, key or value. 78 # 79 # === Using the object 80 # 81 # Using the object is stright forward: 82 # 83 # ini = Ini.new("path/settings.ini") 84 # ini["mail"] = "info@example.com" 85 # ini["filepaths"] = { "tmp" => "/tmp/example" } 86 # ini.comment = "This is\na comment" 87 # puts ini["filepaths"]["tmp"] 88 # # => /tmp/example 89 # ini.write() 90 # 91 92 # 93 # :inihash is a hash which holds all ini data 94 # :comment is a string which holds the comments on the top of the file 95 # 96 attr_accessor :inihash, :comment 97 98 # 99 # Creating a new Ini object 100 # 101 # +path+ is a path to the ini file 102 # +load+ if nil restores the data if possible 103 # if true restores the data, if not possible raises an error 104 # if false does not resotre the data 105 # 106 def initialize(path, load=nil) 107 @path = path 108 @inihash = {} 109 110 if load or ( load.nil? and FileTest.readable_real? @path ) 111 restore() 112 end 113 end 114 115 # 116 # Retrive the ini data for the key +key+ 117 # 118 def [](key) 119 @inihash[key] 120 end 121 122 # 123 # Set the ini data for the key +key+ 124 # 125 def []=(key, value) 126 raise TypeError, "String expected" unless key.is_a? String 127 raise TypeError, "String or Hash expected" unless value.is_a? String or value.is_a? Hash 128 129 @inihash[key] = value 130 end 131 132 # 133 # Restores the data from file into the object 134 # 135 def restore() 136 @inihash = Ini.read_from_file(@path) 137 @comment = Ini.read_comment_from_file(@path) 138 end 139 140 # 141 # Store data from the object in the file 142 # 143 def update() 144 Ini.write_to_file(@path, @inihash, @comment) 145 end 146 147 # 148 # Reading data from file 149 # 150 # +path+ is a path to the ini file 151 # 152 # returns a hash which represents the data from the file 153 # 154 def Ini.read_from_file(path) 155 156 inihash = {} 157 headline = nil 158 159 IO.foreach(path) do |line| 160 161 line = line.strip.split(/#/)[0] 162 163 # read it only if the line doesn't begin with a "=" and is long enough 164 unless line.length < 2 and line[0,1] == "=" 165 166 # it's a headline if the line begins with a "[" and ends with a "]" 167 if line[0,1] == "[" and line[line.length - 1, line.length] == "]" 168 169 # get rid of the [] and unnecessary spaces 170 headline = line[1, line.length - 2 ].strip 171 inihash[headline] = {} 172 else 173 174 key, value = line.split(/=/, 2) 175 176 key = key.strip unless key.nil? 177 value = value.strip unless value.nil? 178 179 unless headline.nil? 180 inihash[headline][key] = value 181 else 182 inihash[key] = value unless key.nil? 183 end 184 end 185 end 186 end 187 188 inihash 189 end 190 191 # 192 # Reading comments from file 193 # 194 # +path+ is a path to the ini file 195 # 196 # Returns a string with comments from the beginning of the 197 # ini file. 198 # 199 def Ini.read_comment_from_file(path) 200 comment = "" 201 202 IO.foreach(path) do |line| 203 line.strip! 204 break unless line[0,1] == "#" or line == "" 205 206 comment << "#{line[1, line.length ].strip}\n" 207 end 208 209 comment 210 end 211 212 # 213 # Writing a ini hash into a file 214 # 215 # +path+ is a path to the ini file 216 # +inihash+ is a hash representing the ini File. Default is a empty hash. 217 # +comment+ is a string with comments which appear on the 218 # top of the file. Each line will get a "#" before. 219 # Default is no comment. 220 # 221 def Ini.write_to_file(path, inihash={}, comment=nil) 222 raise TypeError, "String expected" unless comment.is_a? String or comment.nil? 223 224 raise TypeError, "Hash expected" unless inihash.is_a? Hash 225 File.open(path, "w") { |file| 226 227 unless comment.nil? 228 comment.each do |line| 229 file << "# #{line}" 230 end 231 end 232 233 file << Ini.to_s(inihash) 234 } 235 end 236 237 # 238 # Turn a hash (up to 2 levels deepness) into a ini string 239 # 240 # +inihash+ is a hash representing the ini File. Default is a empty hash. 241 # 242 # Returns a string in the ini file format. 243 # 244 def Ini.to_s(inihash={}) 245 str = "" 246 247 inihash.each do |key, value| 248 249 if value.is_a? Hash 250 str << "[#{key.to_s}]\n" 251 252 value.each do |under_key, under_value| 253 str << "#{under_key.to_s}=#{under_value.to_s unless under_value.nil?}\n" 254 end 255 256 else 257 str << "#{key.to_s}=#{value.to_s unless value2.nil?}\n" 258 end 259 end 260 261 str 262 end 263 264 end
You need to create an account or log in to post comments to this site.