root/trunk/libffado/src/DeviceStringParser.cpp

Revision 1147, 10.4 kB (checked in by ppalmers, 16 years ago)

fix namespace issue

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 "DeviceStringParser.h"
25
26 #include <stdlib.h>
27 #include <errno.h>
28
29 #include <iostream>
30 #include <sstream>
31
32 #include "libieee1394/configrom.h"
33 #include "libieee1394/ieee1394service.h"
34
35 IMPL_DEBUG_MODULE( DeviceStringParser, DeviceStringParser, DEBUG_LEVEL_NORMAL );
36
37 DeviceStringParser::DeviceString::DeviceString(DeviceStringParser& parent)
38     : m_Parent(parent)
39     , m_node( -1 )
40     , m_port( -1 )
41     , m_guid( 0 )
42     , m_String("")
43     , m_Type(eInvalid)
44     , m_debugModule( parent.m_debugModule )
45 {
46 }
47
48 DeviceStringParser::DeviceString::~DeviceString()
49 {
50 }
51
52 bool
53 DeviceStringParser::DeviceString::parse(std::string s)
54 {
55     m_String = s;
56     debugOutput(DEBUG_LEVEL_VERBOSE, "parse: %s\n", s.c_str());
57     std::string prefix = s.substr(0,3);
58    
59     if(s.compare(0,3,"hw:")==0) {
60         m_Type = eBusNode;
61         std::string detail = s.substr(3);
62         std::string::size_type comma_pos = detail.find_first_of(",");
63         if(comma_pos == std::string::npos) {
64             // node is unspecified
65             m_node = -1;
66             std::string port = detail;
67             errno = 0;
68             m_port = strtol(port.c_str(), NULL, 0);
69             if(errno) {
70                 m_Type = eInvalid;
71                 m_port = -1;
72                 m_node = -1;
73                 debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse port\n");
74                 return false;
75             }
76         } else {
77             std::string port = detail.substr(0, comma_pos);
78             std::string node = detail.substr(comma_pos+1);
79             errno = 0;
80             m_port = strtol(port.c_str(), NULL, 0);
81             if(errno) {
82                 m_Type = eInvalid;
83                 m_port = -1;
84                 m_node = -1;
85                 debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse port\n");
86                 return false;
87             }
88             errno = 0;
89             m_node = strtol(node.c_str(), NULL, 0);
90             if(errno) {
91                 m_Type = eInvalid;
92                 m_port = -1;
93                 m_node = -1;
94                 debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse node\n");
95                 return false;
96             }
97         }
98     } else if (s.compare(0,5,"guid:")==0) {
99         std::string detail = s.substr(5);
100         m_Type = eGUID;
101         errno = 0;
102         m_guid = strtoll(detail.c_str(), NULL, 0);
103         if(errno) {
104             m_Type = eInvalid;
105             m_guid = 0;
106             debugOutput(DEBUG_LEVEL_VERBOSE, "failed to parse guid\n");
107             return false;
108         }
109     } else {
110         m_Type = eInvalid;
111         debugOutput(DEBUG_LEVEL_VERBOSE, "invalid\n");
112         return false;
113     }
114     return true;
115 }
116
117 bool
118 DeviceStringParser::DeviceString::isValidString(std::string s)
119 {
120     std::string prefix = s.substr(0,3);
121     uint64_t tmp;
122     if(s.compare(0,3,"hw:")==0) {
123         std::string detail = s.substr(3);
124         std::string::size_type comma_pos = detail.find_first_of(",");
125         if(comma_pos == std::string::npos) {
126             std::string port = detail;
127             errno = 0;
128             tmp = strtol(port.c_str(), NULL, 0);
129             if(errno) {
130                 return false;
131             }
132         } else {
133             std::string port = detail.substr(0, comma_pos);
134             std::string node = detail.substr(comma_pos+1);
135             errno = 0;
136             tmp = strtol(port.c_str(), NULL, 0);
137             if(errno) {
138                 return false;
139             }
140             errno = 0;
141             tmp = strtol(node.c_str(), NULL, 0);
142             if(errno) {
143                 return false;
144             }
145         }
146     } else if (s.compare(0,5,"guid:")==0) {
147         std::string detail = s.substr(5);
148         errno = 0;
149         tmp = strtoll(detail.c_str(), NULL, 0);
150         if(errno) {
151             return false;
152         }
153     } else {
154         return false;
155     }
156     return true;
157 }
158
159 bool
160 DeviceStringParser::DeviceString::match(ConfigRom& configRom)
161 {
162     debugOutput(DEBUG_LEVEL_VERBOSE, "match %p\n", &configRom);
163     bool match;
164     switch(m_Type) {
165         case eBusNode:
166             if(m_port < 0) {
167                 debugWarning("Need at least a port spec\n");
168                 return false;
169             }
170             match = configRom.get1394Service().getPort() == m_port;
171             if(m_node >= 0) {
172                 match &= ((configRom.getNodeId() & 0x3F) == m_node);
173             }
174             return match;
175         case eGUID:
176             //GUID should not be 0
177             return m_guid && (m_guid == configRom.getGuid());
178         case eInvalid:
179         default:
180             debugOutput(DEBUG_LEVEL_VERBOSE, "no match %p\n", &configRom);
181             return false;
182     }
183     return false;
184 }
185
186 bool
187 DeviceStringParser::DeviceString::operator==(const DeviceString& x)
188 {
189     bool retval;
190     switch(m_Type) {
191         case eBusNode:
192             retval = (m_port == x.m_port) && (m_node == x.m_node);
193             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "eBusNode %d,%d == %d,%d? %d\n",
194                         m_port, m_node, x.m_port, x.m_node, retval);
195             return retval;
196         case eGUID:
197             retval = m_guid && (m_guid == x.m_guid);
198             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "eGUID 0x%016X == 0x%016X? %d\n",
199                         m_guid, x.m_guid, retval);
200             return retval;
201         case eInvalid:
202             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "eInvalid \n");
203         default:
204             return false;
205     }
206 }
207
208 void
209 DeviceStringParser::DeviceString::show()
210 {
211     debugOutput(DEBUG_LEVEL_INFO, "string: %s\n", m_String.c_str());
212     switch(m_Type) {
213         case eBusNode:
214             debugOutput(DEBUG_LEVEL_INFO, "type: eBusNode\n");
215             debugOutput(DEBUG_LEVEL_INFO, " Port: %d, Node: %d\n",
216                         m_port, m_node);
217             break;
218         case eGUID:
219             debugOutput(DEBUG_LEVEL_INFO, "type: eGUID\n");
220             debugOutput(DEBUG_LEVEL_INFO, " GUID: %016LLX\n", m_guid);
221             break;
222         case eInvalid:
223         default:
224             debugOutput(DEBUG_LEVEL_INFO, "type: eInvalid\n");
225             break;
226     }
227 }
228
229 // ------------------------
230 DeviceStringParser::DeviceStringParser()
231 {}
232
233 DeviceStringParser::~DeviceStringParser()
234 {
235     while(m_DeviceStrings.size()) {
236         DeviceString *tmp = m_DeviceStrings.at(0);
237         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "removing device string: %p\n", tmp);
238         m_DeviceStrings.erase(m_DeviceStrings.begin());
239         delete tmp;
240     }
241 }
242
243 bool
244 DeviceStringParser::parseString(std::string s)
245 {
246     debugOutput(DEBUG_LEVEL_VERBOSE, "parse: %s\n", s.c_str());
247
248     std::string::size_type next_sep;
249     std::string tmp = s;
250     do {
251         debugOutput(DEBUG_LEVEL_VERBOSE, " left: %s\n", tmp.c_str());
252         next_sep = tmp.find_first_of(";");
253         std::string to_parse = tmp.substr(0, next_sep);
254         DeviceString *d = new DeviceString(*this);
255         if(d == NULL) {
256             debugError("failed to allocate memory for device string\n");
257             continue;
258         }
259         if(d->parse(to_parse)) {
260             addDeviceString(d);
261         } else {
262             debugWarning("Failed to parse device substring: \"%s\"\n",
263                          to_parse.c_str());
264             delete d;
265         }
266         tmp = tmp.substr(next_sep+1);
267     } while(tmp.size() && next_sep != std::string::npos);
268
269     pruneDuplicates();
270
271     return true;
272 }
273
274 bool
275 DeviceStringParser::isValidString(std::string s)
276 {
277     debugOutput(DEBUG_LEVEL_VERBOSE, "isvalid? %s\n", s.c_str());
278     return DeviceString::isValidString(s);
279 }
280
281 bool
282 DeviceStringParser::match(ConfigRom& c)
283 {
284     for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
285       it != m_DeviceStrings.end();
286       ++it )
287     {
288         if((*it)->match(c)) {
289             return true;
290         }
291     }
292     return false;
293 }
294 bool
295 DeviceStringParser::addDeviceString(DeviceString *o)
296 {
297     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "adding device string: %p\n", o);
298     if (hasDeviceString(o)){
299         return false;
300     }
301     m_DeviceStrings.push_back(o);
302     return true;
303 }
304
305 bool
306 DeviceStringParser::removeDeviceString(DeviceString *o)
307 {
308     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "removing device string: %p\n", o);
309     int i=findDeviceString(o);
310     if (i<0) {
311         debugOutput(DEBUG_LEVEL_VERBOSE, "not found\n");
312         return false;
313     } else {
314         DeviceString *tmp = m_DeviceStrings.at(i);
315         m_DeviceStrings.erase(m_DeviceStrings.begin()+i);
316         delete tmp;
317         return true;
318     }
319 }
320
321 bool
322 DeviceStringParser::hasDeviceString(DeviceString *o)
323 {
324     return (findDeviceString(o) >= 0);
325 }
326
327 int
328 DeviceStringParser::findDeviceString(DeviceString *o)
329 {
330     int i=0;
331     for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
332       it != m_DeviceStrings.end();
333       ++it )
334     {
335         if(*it == o) {
336             return i;
337         }
338         i++;
339     }
340     return -1;
341 }
342
343 void
344 DeviceStringParser::pruneDuplicates()
345 {
346     DeviceStringVector duplicates;
347     // find duplicates
348     for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
349       it != m_DeviceStrings.end();
350       ++it )
351     {
352         for ( DeviceStringVectorIterator it2 = it+1;
353           it2 != m_DeviceStrings.end();
354           ++it2 )
355         {
356
357             if(**it == **it2) {
358                 duplicates.push_back(*it2);
359             }
360         }
361     }
362
363     // remove duplicates
364     for ( DeviceStringVectorIterator it = duplicates.begin();
365       it != duplicates.end();
366       ++it )
367     {
368         removeDeviceString(*it);
369     }
370 }
371
372
373 void
374 DeviceStringParser::show()
375 {
376     debugOutput(DEBUG_LEVEL_INFO, "DeviceStringParser: %p\n", this);
377     for ( DeviceStringVectorIterator it = m_DeviceStrings.begin();
378       it != m_DeviceStrings.end();
379       ++it )
380     {
381         (*it)->show();
382     }
383 }
384
385 void
386 DeviceStringParser::setVerboseLevel(int i)
387 {
388     setDebugLevel(i);
389 }
Note: See TracBrowser for help on using the browser.