root/branches/libffado-2.0/src/libutil/Configuration.cpp

Revision 1303, 11.7 kB (checked in by ppalmers, 14 years ago)

add missing files

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "Configuration.h"
25
26 #include <stdlib.h>
27
28 using namespace libconfig;
29 namespace Util {
30
31 IMPL_DEBUG_MODULE( Configuration, Configuration, DEBUG_LEVEL_VERBOSE );
32
33 Configuration::Configuration()
34 {
35
36 }
37
38 Configuration::~Configuration()
39 {
40     while(m_ConfigFiles.size()) {
41         delete m_ConfigFiles.back();
42         m_ConfigFiles.pop_back();
43     }
44 }
45
46 bool
47 Configuration::openFile(std::string filename, enum eFileMode mode)
48 {
49     // check if not already open
50     if(findFileName(filename) >= 0) {
51         debugError("file already open\n");
52         return false;
53     }
54
55     ConfigFile *c = new ConfigFile(*this, filename, mode);
56     switch(mode) {
57         case eFM_ReadOnly:
58         case eFM_ReadWrite:
59             try {
60                 c->readFile();
61             } catch (FileIOException& e) {
62                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not open file: %s\n", filename.c_str());
63                 delete c;
64                 return false;
65             } catch (ParseException& e) {
66                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not parse file: %s\n", filename.c_str());
67                 delete c;
68                 return false;
69             } catch (...) {
70                 debugOutput(DEBUG_LEVEL_VERBOSE, "Unknown exception when opening file: %s\n", filename.c_str());
71                 delete c;
72                 return false;
73             }
74             break;
75         default:
76             break;
77     }
78     m_ConfigFiles.push_back(c);
79     return true;
80 }
81
82 bool
83 Configuration::closeFile(std::string filename)
84 {
85     int idx = findFileName(filename);
86     if(idx >= 0) {
87         debugOutput(DEBUG_LEVEL_VERBOSE, "Closing config file: %s\n", filename.c_str());
88         ConfigFile *c = m_ConfigFiles.at(idx);
89         m_ConfigFiles.erase(m_ConfigFiles.begin()+idx);
90         delete c;
91         return true;
92     } else {
93         debugError("file not open\n");
94         return false;
95     }
96 }
97
98 bool
99 Configuration::saveFile(std::string name)
100 {
101     int idx = findFileName(name);
102     if(idx >= 0) {
103         ConfigFile *c = m_ConfigFiles.at(idx);
104         switch(c->getMode()) {
105         case eFM_ReadOnly:
106             debugOutput(DEBUG_LEVEL_VERBOSE, "Not saving readonly config file: %s\n", c->getName().c_str());
107             break;
108         case eFM_Temporary:
109             debugOutput(DEBUG_LEVEL_VERBOSE, "Not saving temporary config file: %s\n", c->getName().c_str());
110             break;
111         case eFM_ReadWrite:
112             debugOutput(DEBUG_LEVEL_VERBOSE, "Saving config file: %s\n", c->getName().c_str());
113             try {
114                 c->writeFile();
115             } catch (...) {
116                 debugError("Could not write file: %s\n", c->getName().c_str());
117                 return false;
118             }
119         default:
120             debugOutput(DEBUG_LEVEL_VERBOSE, "bad mode for file: %s\n", c->getName().c_str());
121         }
122     }
123     return true;
124 }
125
126 bool
127 Configuration::save()
128 {
129     bool retval = true;
130     for (unsigned int idx = 0; idx < m_ConfigFiles.size(); idx++) {
131         ConfigFile *c = m_ConfigFiles.at(idx);
132         switch(c->getMode()) {
133         case eFM_ReadOnly:
134             debugOutput(DEBUG_LEVEL_VERBOSE, "Not saving readonly config file: %s\n", c->getName().c_str());
135             break;
136         case eFM_Temporary:
137             debugOutput(DEBUG_LEVEL_VERBOSE, "Not saving temporary config file: %s\n", c->getName().c_str());
138             break;
139         case eFM_ReadWrite:
140             debugOutput(DEBUG_LEVEL_VERBOSE, "Saving config file: %s\n", c->getName().c_str());
141             try {
142                 c->writeFile();
143             } catch (...) {
144                 debugError("Could not write file: %s\n", c->getName().c_str());
145                 retval = false;
146             }
147         default:
148             debugOutput(DEBUG_LEVEL_VERBOSE, "bad mode for file: %s\n", c->getName().c_str());
149         }
150     }
151     return retval;
152 }
153
154 void
155 Configuration::ConfigFile::showSetting(libconfig::Setting &s, std::string prefix)
156 {
157     unsigned int children = s.getLength();
158     Setting::Type t = s.getType();
159
160     switch(t) {
161     case Setting::TypeGroup:
162         debugOutput(DEBUG_LEVEL_NORMAL, "  %sGroup: %s\n", prefix.c_str(), s.getName());
163         for(unsigned int i = 0; i < children; i++) {
164             showSetting(s[i], prefix + "  ");
165         }
166         break;
167     case Setting::TypeList:
168         debugOutput(DEBUG_LEVEL_NORMAL, "  %sList: %s\n", prefix.c_str(), s.getName());
169         for(unsigned int i = 0; i < children; i++) {
170             showSetting(s[i], prefix + "  ");
171         }
172         break;
173     case Setting::TypeArray:
174         debugOutput(DEBUG_LEVEL_NORMAL, "  %sArray: %s\n", prefix.c_str(), s.getName());
175         for(unsigned int i = 0; i < children; i++) {
176             showSetting(s[i], prefix + "  ");
177         }
178         break;
179     case Setting::TypeInt:
180         {
181             int32_t i = s;
182             debugOutput(DEBUG_LEVEL_NORMAL,
183                         "  %s%s = %ld (0x%08lX)\n",
184                         prefix.c_str(), s.getName(), i, i);
185         }
186         break;
187     case Setting::TypeInt64:
188         {
189             int64_t i = s;
190             debugOutput(DEBUG_LEVEL_NORMAL,
191                         "  %s%s = %lld (0x%016llX)\n",
192                         prefix.c_str(), s.getName(), i, i);
193         }
194         break;
195     case Setting::TypeFloat:
196         {
197             float f = s;
198             debugOutput(DEBUG_LEVEL_NORMAL,
199                         "  %s%s = %f\n",
200                         prefix.c_str(), s.getName(), f);
201         }
202         break;
203     case Setting::TypeString:
204         {
205             std::string str = s;
206             debugOutput(DEBUG_LEVEL_NORMAL,
207                         "  %s%s = %s\n",
208                         prefix.c_str(), s.getName(), str.c_str());
209         }
210         break;
211     case Setting::TypeBoolean:
212         {
213             bool b = s;
214             std::string str = (b?"true":"false");
215             debugOutput(DEBUG_LEVEL_NORMAL,
216                         "  %s%s = %s\n",
217                         prefix.c_str(), s.getName(), str.c_str());
218         }
219         break;
220     default:
221         {
222             debugOutput(DEBUG_LEVEL_NORMAL,
223                         "  %s%s = Unsupported Type\n",
224                         prefix.c_str(), s.getName());
225         }
226         break;
227     }
228 }
229
230
231 Configuration::VendorModelEntry
232 Configuration::findDeviceVME( unsigned int vendor_id, unsigned model_id )
233 {
234     for ( std::vector<ConfigFile *>::iterator it = m_ConfigFiles.begin();
235       it != m_ConfigFiles.end();
236       ++it )
237     {
238         ConfigFile *c = *it;
239         try {
240             Setting &list = c->lookup("device_definitions");
241             unsigned int children = list.getLength();
242             for(unsigned int i = 0; i < children; i++) {
243                 Setting &s = list[i];
244                 try {
245                     Setting &vendorid = s["vendorid"];
246                     Setting &modelid = s["modelid"];
247                     uint32_t vid = vendorid;
248                     uint32_t mid = modelid;
249                     if (vendor_id == vid && model_id == mid) {
250                         struct VendorModelEntry vme;
251                         vme.vendor_id = vendorid;
252                         vme.model_id = modelid;
253
254                         const char *tmp = s["vendorname"];
255                         vme.vendor_name = tmp;
256                         tmp = s["modelname"];
257                         vme.model_name = tmp;
258                         vme.driver = s["driver"];
259                         debugOutput(DEBUG_LEVEL_VERBOSE,
260                                     "  device VME for %X:%x found in %s\n",
261                                     vendor_id, model_id, c->getName().c_str());
262                         c->showSetting(s);
263                         return vme;
264                     }
265                 } catch (...) {
266                     debugWarning("Bogus format\n");
267                 }
268             }
269         } catch (...) {
270             debugOutput(DEBUG_LEVEL_VERBOSE, "  %s has no device definitions\n", c->getName().c_str());
271         }
272     }
273     struct VendorModelEntry invalid;
274     return invalid;
275 }
276
277 bool
278 Configuration::isDeviceVMEPresent( unsigned int vendor_id, unsigned model_id )
279 {
280     return isValid(findDeviceVME( vendor_id, model_id ));
281 }
282
283 bool
284 Configuration::isValid( const Configuration::VendorModelEntry& vme )
285 {
286     struct VendorModelEntry invalid;
287     return !(vme==invalid);
288 }
289
290 void
291 Configuration::ConfigFile::show()
292 {
293     debugOutput(DEBUG_LEVEL_NORMAL, " config file: %s\n", getName().c_str());
294     Setting &root = getRoot();
295     if(root.getLength()) {
296         showSetting(root, "");
297     } else {
298         debugOutput(DEBUG_LEVEL_NORMAL, "  Empty\n");
299     }
300 }
301
302 void
303 Configuration::show()
304 {
305     debugOutput(DEBUG_LEVEL_NORMAL, "Configuration:\n");
306     for (unsigned int idx = 0; idx < m_ConfigFiles.size(); idx++) {
307         ConfigFile *c = m_ConfigFiles.at(idx);
308         c->show();
309     }
310 }
311
312 int
313 Configuration::findFileName(std::string s) {
314     int i=0;
315     for ( std::vector<ConfigFile *>::iterator it = m_ConfigFiles.begin();
316       it != m_ConfigFiles.end();
317       ++it )
318     {
319         if((*it)->getName() == s) {
320             return i;
321         }
322         i++;
323     }
324     return -1;
325 }
326
327 void
328 Configuration::ConfigFile::readFile()
329 {
330     std::string filename = m_name;
331     // fix up the '~' as homedir
332     std::string::size_type pos = filename.find_first_of("~");
333     if(pos != std::string::npos) {
334         char *homedir = getenv("HOME");
335         if(homedir) {
336             std::string home = homedir;
337             filename.replace( pos, 1, home, 0, home.length());
338         }
339     }
340     Config::readFile(filename.c_str());
341 }
342
343 void
344 Configuration::ConfigFile::writeFile()
345 {
346     std::string filename = m_name;
347     // fix up the '~' as homedir
348     std::string::size_type pos = filename.find_first_of("~");
349     if(pos != std::string::npos) {
350         char *homedir = getenv("HOME");
351         if(homedir) {
352             std::string home = homedir;
353             filename.replace( pos, 1, home, 0, home.length());
354         }
355     }
356     Config::writeFile(filename.c_str());
357 }
358
359 Configuration::VendorModelEntry::VendorModelEntry()
360     : vendor_id( 0 )
361     , model_id( 0 )
362     , driver( 0 )
363 {
364 }
365
366 Configuration::VendorModelEntry::VendorModelEntry( const VendorModelEntry& rhs )
367     : vendor_id( rhs.vendor_id )
368     , model_id( rhs.model_id )
369     , vendor_name( rhs.vendor_name )
370     , model_name( rhs.model_name )
371     , driver( rhs.driver )
372 {
373 }
374
375 Configuration::VendorModelEntry&
376 Configuration::VendorModelEntry::operator = ( const VendorModelEntry& rhs )
377 {
378     // check for assignment to self
379     if ( this == &rhs ) return *this;
380
381     vendor_id   = rhs.vendor_id;
382     model_id    = rhs.model_id;
383     vendor_name = rhs.vendor_name;
384     model_name  = rhs.model_name;
385     driver      = rhs.driver;
386
387     return *this;
388 }
389
390 bool
391 Configuration::VendorModelEntry::operator == ( const VendorModelEntry& rhs ) const
392 {
393     bool equal=true;
394
395     equal &= (vendor_id   == rhs.vendor_id);
396     equal &= (model_id    == rhs.model_id);
397     equal &= (vendor_name == rhs.vendor_name);
398     equal &= (model_name  == rhs.model_name);
399     equal &= (driver      == rhs.driver);
400
401     return equal;
402 }
403
404 Configuration::VendorModelEntry::~VendorModelEntry()
405 {
406 }
407
408 } // namespace Util
Note: See TracBrowser for help on using the browser.