0.6.1-1 release
[manu/suphp.git] / src / IniFile.cpp
1 /*
2     suPHP - (c)2002-2005 Sebastian Marsching <sebastian@marsching.com>
3
4     This file is part of suPHP.
5
6     suPHP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     suPHP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with suPHP; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include <string>
22 #include <fstream>
23 #include <sstream>
24
25 #include "KeyNotFoundException.hpp"
26
27 #include "IniFile.hpp"
28
29 using namespace suPHP;
30
31 IniSection& suPHP::IniFile::getSection(std::string name)
32     throw (KeyNotFoundException) {
33     if (this->sections.find(name) != this->sections.end()) {
34         return this->sections.find(name)->second;
35     } else {
36         throw KeyNotFoundException("Section " + name + " not found", 
37                                    __FILE__, __LINE__);
38     }
39 }
40
41 bool suPHP::IniFile::hasSection(std::string name) {
42     if (this->sections.find(name) != this->sections.end()) {
43         return true;
44     } else {
45         return false;
46     }
47     
48 }
49
50 IniSection& suPHP::IniFile::operator[](std::string name) 
51     throw (KeyNotFoundException) {
52     return this->getSection(name);
53 }
54
55
56 void suPHP::IniFile::parse(File file) throw (IOException, ParsingException) {
57     SmartPtr<std::ifstream> is = file.getInputStream();
58     IniSection *current_section = NULL;
59     while (!is->eof() && !is->bad() && !is->fail()) {
60         std::string line;
61         std::string tstr;
62         char dummy;
63         int startpos = 0;
64         int endpos = 0;
65         
66         // Read line from file
67         getline(*is, line);
68         
69         tstr = line;
70         
71         // Find first char not being space or tab
72         startpos = tstr.find_first_not_of(" \t");
73         // Find last char not being space or tab
74         endpos = tstr.find_last_not_of(" \t");
75
76         // Skip empty line, only containing whitespace
77         if (startpos == std::string::npos)
78             continue;
79         
80         // Get trimmed string
81         tstr = tstr.substr(startpos, endpos - startpos + 1);
82
83         // Is line a comment (starting with ";")?
84         if (tstr[0] == ';') {
85             // Comments are not interessting => skip
86             continue;
87        
88         // Is line a section mark ("[section]")?
89         } else if (tstr[0] == '[' && tstr[tstr.size()-1] == ']') {
90             // Extract name of section
91             std::string name = tstr.substr(1, tstr.size() - 2);
92             // If section is not yet existing, create it
93             if (!this->hasSection(name)) {
94                 std::pair<std::string, IniSection> p;
95                 IniSection sect;
96                 p.first = name;
97                 p.second = sect;
98                 this->sections.insert(p);
99             }
100             // Set current section
101             current_section = &(this->getSection(name));
102             
103         // Is the line a key-value pair?
104         } else if (tstr.find_first_of('=') != std::string::npos) {
105             std::string name;
106             std::string value;
107             int eqpos = 0;
108             
109             // Check wheter we already have a section
110             if (current_section == NULL) {
111                 throw ParsingException("Option line \"" + tstr +
112                                        "\" before first section", 
113                                        __FILE__, __LINE__);
114             }
115             
116             // Extract name
117             eqpos = tstr.find_first_of('=');
118             name = tstr.substr(0, eqpos);
119             value = tstr.substr(eqpos + 1, tstr.size() - eqpos + 1);
120             name = name.substr(0, name.find_last_not_of(" \t") + 1);
121             value = value.substr(value.find_first_not_of(" \t"));
122             if (value[0] == '"')
123                 value = value.substr(1);
124             if (value[value.size()-1] == '"')
125                 value = value.substr(0, value.size()-1);
126             current_section->putValue(name, value);
127         // Line is something we do not know
128         } else {
129             throw ParsingException("Illegal line \"" + tstr + "\"", 
130                                    __FILE__, __LINE__);
131         }
132     }
133     is->close();
134 }