moved qdb here because matt is lazy
[public/www-new.git] / pub / qdb / src / modules / Chirpy / Util / IniFile.pm
1 ###############################################################################\r
2 # Chirpy! 0.3, a quote management system                                      #\r
3 # Copyright (C) 2005-2007 Tim De Pauw <ceetee@users.sourceforge.net>          #\r
4 ###############################################################################\r
5 # This program is free software; you can redistribute it and/or modify it     #\r
6 # under the terms of the GNU General Public License as published by the Free  #\r
7 # Software Foundation; either version 2 of the License, or (at your option)   #\r
8 # any later version.                                                          #\r
9 #                                                                             #\r
10 # This program is distributed in the hope that it will be useful, but WITHOUT #\r
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #\r
12 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   #\r
13 # more details.                                                               #\r
14 #                                                                             #\r
15 # You should have received a copy of the GNU General Public License along     #\r
16 # with this program; if not, write to the Free Software Foundation, Inc., 51  #\r
17 # Franklin St, Fifth Floor, Boston, MA  02110-1301  USA                       #\r
18 ###############################################################################\r
19 \r
20 ###############################################################################\r
21 # $Id:: IniFile.pm 291 2007-02-05 21:24:46Z ceetee                          $ #\r
22 ###############################################################################\r
23 \r
24 =head1 NAME\r
25 \r
26 Chirpy::Util::IniFile - Load from and save to an INI file\r
27 \r
28 =head1 SYNOPSIS\r
29 \r
30  $inifile = new Chirpy::Util::IniFile('/path/to/inifile.ini');\r
31 \r
32  $value = $inifile->get($section, $name);\r
33 \r
34  $inifile->set($section, $name, $value);\r
35  \r
36  undef $inifile;\r
37 \r
38 =head1 NOTE\r
39 \r
40 The C<undef $inifile;> in the above example is not necessary to trigger an\r
41 update of the file's contents. The file is updated as soon as the object goes\r
42 out of scope (but only if the C<set()> function has been called).\r
43 \r
44 =head1 AUTHOR\r
45 \r
46 Tim De Pauw E<lt>ceetee@users.sourceforge.netE<gt>\r
47 \r
48 =head1 SEE ALSO\r
49 \r
50 L<Chirpy::Configuration>, L<Chirpy::Locale>, L<Chirpy>,\r
51 L<http://chirpy.sourceforge.net/>\r
52 \r
53 =head1 COPYRIGHT\r
54 \r
55 Copyright 2005-2007 Tim De Pauw. All rights reserved.\r
56 \r
57 This program is free software; you can redistribute it and/or modify it under\r
58 the terms of the GNU General Public License as published by the Free Software\r
59 Foundation; either version 2 of the License, or (at your option) any later\r
60 version.\r
61 \r
62 This program is distributed in the hope that it will be useful, but WITHOUT ANY\r
63 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\r
64 PARTICULAR PURPOSE.  See the GNU General Public License for more details.\r
65 \r
66 =cut\r
67 \r
68 package Chirpy::Util::IniFile;\r
69 \r
70 use strict;\r
71 use warnings;\r
72 \r
73 use vars qw($VERSION);\r
74 \r
75 $VERSION = '0.3';\r
76 \r
77 use Chirpy 0.3;\r
78 \r
79 sub new {\r
80         my ($class, $file, $create) = @_;\r
81         my $self = {\r
82                 'contents' => {},\r
83                 'filename' => $file\r
84         };\r
85         if (!defined $file) {\r
86                 Chirpy::die('No filename specified');\r
87         }\r
88         if ($create) {\r
89                 $self->{'modified'} = 1;\r
90         }\r
91         elsif (!-f $file) {\r
92                 Chirpy::die('File "' . $file . '" does not exist');\r
93         }\r
94         local *FILE;\r
95         open(FILE, '<:utf8', $file)\r
96                 or Chirpy::die('Failed to read from ' . $file . ': ' . $!);\r
97         my $section;\r
98         while (<FILE>) {\r
99                 chomp;\r
100                 next if (/^;/);\r
101                 if (/^\s*\[([^\]]+)\]\s*$/) {\r
102                         $section = $1;\r
103                 }\r
104                 elsif (defined($section) && /^([^=]+)=(.*)/) {\r
105                         $self->{'contents'}{$section}{$1} = $2;\r
106                 }\r
107         }\r
108         close FILE;\r
109         return bless($self, $class);\r
110 }\r
111 \r
112 sub DESTROY {\r
113         my $self = shift;\r
114         return unless ($self->{'modified'});\r
115         local *FILE;\r
116         open(FILE, '>:utf8', $self->{'filename'})\r
117                 or Chirpy::die('Failed to write to ' . $self->{'filename'}\r
118                         . ': ' . $!);\r
119         print FILE '; Automatically generated by ', __PACKAGE__, $/,\r
120                 '; ', (my $str = gmtime()), $/;\r
121         foreach my $section (sort { lc($a) cmp lc($b) }\r
122                 keys %{$self->{'contents'}}) {\r
123                         print FILE $/, '[', $section, ']', $/;\r
124                         foreach my $name (sort { lc($a) cmp lc($b) }\r
125                                 keys %{$self->{'contents'}{$section}}) {\r
126                                         print FILE $name, '=',\r
127                                                 $self->{'contents'}{$section}{$name}, $/;\r
128                         }\r
129         }\r
130         close FILE;\r
131 }\r
132 \r
133 sub get {\r
134         my ($self, $section, $name) = @_;\r
135         return (defined $name\r
136                 ? $self->{'contents'}{$section}{$name}\r
137                 : $self->{'contents'}{$section});\r
138 }\r
139 \r
140 sub set {\r
141         my ($self, $section, $name, $value) = @_;\r
142         $self->{'contents'}{$section} = {}\r
143                 if (!exists($self->{'contents'}{$section}));\r
144         $self->{'contents'}{$section}{$name} = $value;\r
145         $self->{'modified'} = 1;\r
146 }\r
147 \r
148 1;\r
149 \r
150 ###############################################################################