Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Ini file parser and writer (See related posts)

This file provides a read-wite handling for ini files. The data of a ini file is represented by a object which is populated with strings.

   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.


Click here to browse all 5350 code snippets

Related Posts