root/trunk/libffado/src/libutil/serialize_libxml.cpp

Revision 1763, 10.0 kB (checked in by ppalmers, 12 years ago)

Merged revisions 1536,1541,1544-1546,1549,1554-1562,1571,1579-1581,1618,1632,1634-1635,1661,1677-1679,1703-1704,1715,1720-1723,1743-1745,1755 via svnmerge from
svn+ssh://ffadosvn@ffado.org/ffado/branches/libffado-2.0

Also fix remaining format string warnings.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
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 "version.h" // FOR CACHE_VERSION
25
26 #include "serialize.h"
27
28 #include <cstring>
29 #include <cstdio>
30 #include <cstdlib>
31
32 using namespace std;
33
34 IMPL_DEBUG_MODULE( Util::XMLSerialize,   XMLSerialize,   DEBUG_LEVEL_NORMAL );
35 IMPL_DEBUG_MODULE( Util::XMLDeserialize, XMLDeserialize, DEBUG_LEVEL_NORMAL );
36
37 Util::XMLSerialize::XMLSerialize( std::string fileName )
38     : IOSerialize()
39     , m_filepath( fileName )
40     , m_verboseLevel( DEBUG_LEVEL_NORMAL )
41 {
42     setDebugLevel( DEBUG_LEVEL_NORMAL );
43     try {
44         m_doc.create_root_node( "ffado_cache" );
45         writeVersion();
46     } catch ( const exception& ex ) {
47         cout << "Exception caught: " << ex.what();
48     }
49 }
50
51 Util::XMLSerialize::XMLSerialize( std::string fileName, int verboseLevel )
52     : IOSerialize()
53     , m_filepath( fileName )
54     , m_verboseLevel( verboseLevel )
55 {
56     setDebugLevel(verboseLevel);
57     try {
58         m_doc.create_root_node( "ffado_cache" );
59         writeVersion();
60     } catch ( const exception& ex ) {
61         cout << "Exception caught: " << ex.what();
62     }
63 }
64
65 Util::XMLSerialize::~XMLSerialize()
66 {
67     try {
68         m_doc.write_to_file_formatted( m_filepath );
69     } catch ( const exception& ex ) {
70         cout << "Exception caugth: " << ex.what();
71     }
72
73 }
74
75 void
76 Util::XMLSerialize::writeVersion()
77 {
78     xmlpp::Node* pNode = m_doc.get_root_node();
79     xmlpp::Element* pElem = pNode->add_child( "CacheVersion" );
80     char* valstr;
81     asprintf( &valstr, "%s", CACHE_VERSION );
82     pElem->set_child_text( valstr );
83     free( valstr );
84 }
85
86 bool
87 Util::XMLSerialize::write( std::string strMemberName,
88                            long long value )
89
90 {
91     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "write %s = %lld\n",
92                  strMemberName.c_str(), value );
93
94     vector<string> tokens;
95     tokenize( strMemberName, tokens, "/" );
96
97     if ( tokens.size() == 0 ) {
98         debugWarning( "token size is 0\n" );
99         return false;
100     }
101
102     xmlpp::Node* pNode = m_doc.get_root_node();
103     pNode = getNodePath( pNode, tokens );
104
105     // element to be added
106     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
107     char* valstr;
108     asprintf( &valstr, "%lld", value );
109     pElem->set_child_text( valstr );
110     free( valstr );
111
112     return true;
113 }
114
115 bool
116 Util::XMLSerialize::write( std::string strMemberName,
117                            std::string str)
118 {
119     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "write %s = %s\n",
120                  strMemberName.c_str(), str.c_str() );
121
122     vector<string> tokens;
123     tokenize( strMemberName, tokens, "/" );
124
125     if ( tokens.size() == 0 ) {
126         debugWarning( "token size is 0\n" );
127         return false;
128     }
129
130     xmlpp::Node* pNode = m_doc.get_root_node();
131     pNode = getNodePath( pNode, tokens );
132
133     // element to be added
134     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
135     pElem->set_child_text( str );
136
137     return true;
138 }
139
140 xmlpp::Node*
141 Util::XMLSerialize::getNodePath( xmlpp::Node* pRootNode,
142                                  std::vector<string>& tokens )
143 {
144     // returns the correct node on which the new element has to be added.
145     // if the path does not exist, it will be created.
146
147     if ( tokens.size() == 1 ) {
148         return pRootNode;
149     }
150
151     unsigned int iTokenIdx = 0;
152     xmlpp::Node* pCurNode = pRootNode;
153     for (bool bFound = false;
154          ( iTokenIdx < tokens.size() - 1 );
155          bFound = false, iTokenIdx++ )
156     {
157         xmlpp::Node::NodeList nodeList = pCurNode->get_children();
158         for ( xmlpp::Node::NodeList::iterator it = nodeList.begin();
159               it != nodeList.end();
160               ++it )
161         {
162             if ( ( *it )->get_name() == tokens[iTokenIdx] ) {
163                 pCurNode = *it;
164                 bFound = true;
165                 break;
166             }
167         }
168         if ( !bFound ) {
169             break;
170         }
171     }
172
173     for ( unsigned int i = iTokenIdx; i < tokens.size() - 1; i++, iTokenIdx++ ) {
174         pCurNode = pCurNode->add_child( tokens[iTokenIdx] );
175     }
176     return pCurNode;
177
178 }
179
180 /***********************************/
181
182 Util::XMLDeserialize::XMLDeserialize( std::string fileName )
183     : IODeserialize()
184     , m_filepath( fileName )
185     , m_verboseLevel( DEBUG_LEVEL_NORMAL )
186 {
187     setDebugLevel(DEBUG_LEVEL_NORMAL);
188     try {
189         m_parser.set_substitute_entities(); //We just want the text to
190                                             //be resolved/unescaped
191                                             //automatically.
192         m_parser.parse_file( m_filepath );
193     } catch ( const exception& ex ) {
194         cout << "Exception caught: " << ex.what();
195     }
196 }
197
198 Util::XMLDeserialize::XMLDeserialize( std::string fileName, int verboseLevel )
199     : IODeserialize()
200     , m_filepath( fileName )
201     , m_verboseLevel( verboseLevel )
202 {
203     setDebugLevel(verboseLevel);
204     try {
205         m_parser.set_substitute_entities(); //We just want the text to
206                                             //be resolved/unescaped
207                                             //automatically.
208         m_parser.parse_file( m_filepath );
209     } catch ( const exception& ex ) {
210         cout << "Exception caught: " << ex.what();
211     }
212 }
213
214 Util::XMLDeserialize::~XMLDeserialize()
215 {
216 }
217
218 bool
219 Util::XMLDeserialize::isValid()
220 {
221     return checkVersion();
222 }
223
224 bool
225 Util::XMLDeserialize::checkVersion()
226 {
227     std::string savedVersion;
228     if (read( "CacheVersion", savedVersion )) {
229         Glib::ustring expectedVersion = CACHE_VERSION;
230         debugOutput( DEBUG_LEVEL_NORMAL, "Cache version: %s, expected: %s.\n", savedVersion.c_str(), expectedVersion.c_str() );
231         if (expectedVersion == savedVersion) {
232             debugOutput( DEBUG_LEVEL_VERBOSE, "Cache version OK.\n" );
233             return true;
234         } else {
235             debugOutput( DEBUG_LEVEL_VERBOSE, "Cache version not OK.\n" );
236             return false;
237         }
238     } else return false;
239 }
240
241 bool
242 Util::XMLDeserialize::read( std::string strMemberName,
243                             long long& value )
244
245 {
246     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "lookup %s\n", strMemberName.c_str() );
247
248     xmlpp::Document *pDoc=m_parser.get_document();
249     if(!pDoc) {
250         debugWarning( "no document found\n" );
251         return false;
252     }
253     xmlpp::Node* pNode = pDoc->get_root_node();
254
255     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "pNode = %s\n", pNode->get_name().c_str() );
256
257     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
258     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
259           it != nodeSet.end();
260           ++it )
261     {
262         const xmlpp::Element* pElement =
263             dynamic_cast< const xmlpp::Element* >( *it );
264         if ( pElement && pElement->has_child_text() ) {
265             char* tail;
266             value = strtoll( pElement->get_child_text()->get_content().c_str(),
267                              &tail, 0 );
268             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "found %s = %lld\n",
269                          strMemberName.c_str(), value );
270             return true;
271         }
272         debugWarning( "no such a node %s\n", strMemberName.c_str() );
273         return false;
274     }
275
276     debugWarning( "no such a node %s\n", strMemberName.c_str() );
277     return false;
278 }
279
280 bool
281 Util::XMLDeserialize::read( std::string strMemberName,
282                             std::string& str )
283 {
284     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "lookup %s\n", strMemberName.c_str() );
285
286     xmlpp::Document *pDoc=m_parser.get_document();
287     if(!pDoc) {
288         debugWarning( "no document found\n" );
289         return false;
290     }
291     xmlpp::Node* pNode = pDoc->get_root_node();
292
293     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
294     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
295           it != nodeSet.end();
296           ++it )
297     {
298         const xmlpp::Element* pElement = dynamic_cast< const xmlpp::Element* >( *it );
299         if ( pElement ) {
300             if ( pElement->has_child_text() ) {
301                 str = pElement->get_child_text()->get_content();
302             } else {
303                 str = "";
304             }
305             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "found %s = %s\n",
306                          strMemberName.c_str(), str.c_str() );
307             return true;
308         }
309         debugWarning( "no such a node %s\n", strMemberName.c_str() );
310         return false;
311     }
312
313     debugWarning( "no such a node %s\n", strMemberName.c_str() );
314     return false;
315 }
316
317 bool
318 Util::XMLDeserialize::isExisting( std::string strMemberName )
319 {
320     xmlpp::Document *pDoc=m_parser.get_document();
321     if(!pDoc) {
322         return false;
323     }
324     xmlpp::Node* pNode = pDoc->get_root_node();
325     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
326     return nodeSet.size() > 0;
327 }
328
329 void
330 tokenize(const string& str,
331          vector<string>& tokens,
332          const string& delimiters)
333 {
334     // Skip delimiters at beginning.
335     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
336     // Find first "non-delimiter".
337     string::size_type pos     = str.find_first_of(delimiters, lastPos);
338
339     while (string::npos != pos || string::npos != lastPos)
340     {
341         // Found a token, add it to the vector.
342         tokens.push_back(str.substr(lastPos, pos - lastPos));
343         // Skip delimiters.  Note the "not_of"
344         lastPos = str.find_first_not_of(delimiters, pos);
345         // Find next "non-delimiter"
346         pos = str.find_first_of(delimiters, lastPos);
347     }
348 }
Note: See TracBrowser for help on using the browser.