source: branches/work_320/ConfigFile.cpp @ 679

Revision 58, 4.1 KB checked in by jls17, 10 years ago (diff)

first steps to support multiple platforms:

  • updated includes to case-sensitive filenames;
  • "\" within includes are replaced with "/";
  • all files end with new line;
  • itoa function is not available under linux => use sprintf instead;

CARInside::LoadFromFile?

  • outputs item count loaded from xml file;
Line 
1//Copyright (C) 2009 Stefan Nerlich | stefan.nerlich@hotmail.com
2//
3//This file is part of ARInside.
4//
5//    ARInside is free software: you can redistribute it and/or modify
6//    it under the terms of the GNU General Public License as published by
7//    the Free Software Foundation, version 2 of the License.
8//
9//    ARInside is distributed in the hope that it will be useful,
10//    but WITHOUT ANY WARRANTY; without even the implied warranty of
11//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12//    GNU General Public License for more details.
13//
14//    You should have received a copy of the GNU General Public License
15//    along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
16
17#include "stdafx.h"
18#include "ConfigFile.h"
19
20using std::string;
21
22ConfigFile::ConfigFile( string filename, string delimiter,
23                                           string comment, string sentry )
24                                           : myDelimiter(delimiter), myComment(comment), mySentry(sentry)
25{       
26        std::ifstream in( filename.c_str() );   
27        if( !in ) 
28                throw file_not_found( filename ); 
29
30        in >> (*this);
31}
32
33
34ConfigFile::ConfigFile()
35: myDelimiter( string(1,'=') ), myComment( string(1,'#') )
36{
37        // Construct a ConfigFile without a file; empty
38}
39
40
41void ConfigFile::remove( const string& key )
42{
43        // Remove key and its value
44        myContents.erase( myContents.find( key ) );
45        return;
46}
47
48
49bool ConfigFile::keyExists( const string& key ) const
50{
51        // Indicate whether key is found
52        mapci p = myContents.find( key );
53        return ( p != myContents.end() );
54}
55
56
57/* static */
58void ConfigFile::trim( string& s )
59{
60        // Remove leading and trailing whitespace
61        static const char whitespace[] = " \n\t\v\r\f";
62        s.erase( 0, s.find_first_not_of(whitespace) );
63        s.erase( s.find_last_not_of(whitespace) + 1U );
64}
65
66
67std::ostream& operator<<( std::ostream& os, const ConfigFile& cf )
68{
69        // Save a ConfigFile to os
70        for( ConfigFile::mapci p = cf.myContents.begin();
71                p != cf.myContents.end();
72                ++p )
73        {
74                os << p->first << " " << cf.myDelimiter << " ";
75                os << p->second << std::endl;
76        }
77        return os;
78}
79
80
81std::istream& operator>>( std::istream& is, ConfigFile& cf )
82{
83        // Load a ConfigFile from is
84        // Read in keys and values, keeping internal whitespace
85        typedef string::size_type pos;
86        const string& delim  = cf.myDelimiter;  // separator
87        const string& comm   = cf.myComment;    // comment
88        const string& sentry = cf.mySentry;     // end of file sentry
89        const pos skip = delim.length();        // length of separator
90
91        string nextline = "";  // might need to read ahead to see where value ends
92
93        while( is || nextline.length() > 0 )
94        {
95                // Read an entire line at a time
96                string line;
97                if( nextline.length() > 0 )
98                {
99                        line = nextline;  // we read ahead; use it now
100                        nextline = "";
101                }
102                else
103                {
104                        std::getline( is, line );
105                }
106
107                // Ignore comments
108                line = line.substr( 0, line.find(comm) );
109
110                // Check for end of file sentry
111                if( sentry != "" && line.find(sentry) != string::npos ) return is;
112
113                // Parse the line if it contains a delimiter
114                pos delimPos = line.find( delim );
115                if( delimPos < string::npos )
116                {
117                        // Extract the key
118                        string key = line.substr( 0, delimPos );
119                        line.replace( 0, delimPos+skip, "" );
120
121                        // See if value continues on the next line
122                        // Stop at blank line, next line with a key, end of stream,
123                        // or end of file sentry
124                        bool terminate = false;
125                        while( !terminate && is )
126                        {
127                                std::getline( is, nextline );
128                                terminate = true;
129
130                                string nlcopy = nextline;
131                                ConfigFile::trim(nlcopy);
132                                if( nlcopy == "" ) continue;
133
134                                nextline = nextline.substr( 0, nextline.find(comm) );
135                                if( nextline.find(delim) != string::npos )
136                                        continue;
137                                if( sentry != "" && nextline.find(sentry) != string::npos )
138                                        continue;
139
140                                nlcopy = nextline;
141                                ConfigFile::trim(nlcopy);
142                                if( nlcopy != "" ) line += "\n";
143                                line += nextline;
144                                terminate = false;
145                        }
146
147                        // Store key and value
148                        ConfigFile::trim(key);
149                        ConfigFile::trim(line);
150                        cf.myContents[key] = line;  // overwrites if key is repeated
151                }
152        }
153
154        return is;
155}
Note: See TracBrowser for help on using the repository browser.