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

Revision 2802, 11.5 kB (checked in by jwoithe, 3 years ago)

Cosmetic: "Firewire" becomes "FireWire?".

Officially both the "F" and "W" were capitalised in the FireWire? name, so
reflect this throughout FFADO's source tree. This mostly affects comments.

This patch originated from pander on the ffado-devel mailing list. To
maintain consistency, the committed version has been expanded to include
files not originally included in the original patch.

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 #if LIBXMLXX_MAJOR_VERSION == 3
79     xmlpp::Element* pElem =  m_doc.get_root_node()->add_child_element( "CacheVersion" );
80 #else
81     xmlpp::Node* pNode = m_doc.get_root_node();
82     xmlpp::Element* pElem = pNode->add_child( "CacheVersion" );
83 #endif
84     char* valstr;
85     asprintf( &valstr, "%s", CACHE_VERSION );
86 #if LIBXMLXX_MAJOR_VERSION == 3
87     pElem->set_first_child_text( valstr );
88 #else
89     pElem->set_child_text( valstr );
90 #endif
91     free( valstr );
92 }
93
94 bool
95 Util::XMLSerialize::write( std::string strMemberName,
96                            long long value )
97
98 {
99     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "write %s = %lld\n",
100                  strMemberName.c_str(), value );
101
102     vector<string> tokens;
103     tokenize( strMemberName, tokens, "/" );
104
105     if ( tokens.size() == 0 ) {
106         debugWarning( "token size is 0\n" );
107         return false;
108     }
109
110     xmlpp::Element* pNode = m_doc.get_root_node();
111     pNode = getNodePath( pNode, tokens );
112
113     // element to be added
114 #if LIBXMLXX_MAJOR_VERSION == 3
115     xmlpp::Element* pElem = pNode->add_child_element( tokens[tokens.size() - 1] );
116 #else
117     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
118 #endif
119     char* valstr;
120     asprintf( &valstr, "%lld", value );
121 #if LIBXMLXX_MAJOR_VERSION == 3
122     pElem->set_first_child_text( valstr );
123 #else
124     pElem->set_child_text( valstr );
125 #endif
126     free( valstr );
127
128     return true;
129 }
130
131 bool
132 Util::XMLSerialize::write( std::string strMemberName,
133                            std::string str)
134 {
135     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "write %s = %s\n",
136                  strMemberName.c_str(), str.c_str() );
137
138     vector<string> tokens;
139     tokenize( strMemberName, tokens, "/" );
140
141     if ( tokens.size() == 0 ) {
142         debugWarning( "token size is 0\n" );
143         return false;
144     }
145
146     xmlpp::Element* pNode = m_doc.get_root_node();
147     pNode = getNodePath( pNode, tokens );
148
149     // element to be added
150 #if LIBXMLXX_MAJOR_VERSION == 3
151     xmlpp::Element* pElem = pNode->add_child_element( tokens[tokens.size() - 1] );
152     pElem->set_first_child_text( str );
153 #else
154     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
155     pElem->set_child_text( str );
156 #endif
157
158     return true;
159 }
160
161 xmlpp::Element*
162 Util::XMLSerialize::getNodePath( xmlpp::Element* pRootNode,
163                                  std::vector<string>& tokens )
164 {
165     // returns the correct node on which the new element has to be added.
166     // if the path does not exist, it will be created.
167
168     if ( tokens.size() == 1 ) {
169         return pRootNode;
170     }
171
172     unsigned int iTokenIdx = 0;
173     xmlpp::Element* pCurNode = pRootNode;
174     for (bool bFound = false;
175          ( iTokenIdx < tokens.size() - 1 );
176          bFound = false, iTokenIdx++ )
177     {
178         xmlpp::Node::NodeList nodeList = pCurNode->get_children();
179         for ( xmlpp::Node::NodeList::iterator it = nodeList.begin();
180               it != nodeList.end();
181               ++it )
182         {
183             if ( ( *it )->get_name() == tokens[iTokenIdx] ) {
184                 pCurNode = (xmlpp::Element*) *it;
185                 bFound = true;
186                 break;
187             }
188         }
189         if ( !bFound ) {
190             break;
191         }
192     }
193
194     for ( unsigned int i = iTokenIdx; i < tokens.size() - 1; i++, iTokenIdx++ ) {
195 #if LIBXMLXX_MAJOR_VERSION == 3
196         pCurNode = pCurNode->add_child_element( tokens[iTokenIdx] );
197 #else
198         pCurNode = pCurNode->add_child( tokens[iTokenIdx] );
199 #endif
200     }
201     return pCurNode;
202
203 }
204
205 /***********************************/
206
207 Util::XMLDeserialize::XMLDeserialize( std::string fileName )
208     : IODeserialize()
209     , m_filepath( fileName )
210     , m_verboseLevel( DEBUG_LEVEL_NORMAL )
211 {
212     setDebugLevel(DEBUG_LEVEL_NORMAL);
213     try {
214         m_parser.set_substitute_entities(); //We just want the text to
215                                             //be resolved/unescaped
216                                             //automatically.
217         m_parser.parse_file( m_filepath );
218     } catch ( const exception& ex ) {
219         cout << "Exception caught: " << ex.what();
220     }
221 }
222
223 Util::XMLDeserialize::XMLDeserialize( std::string fileName, int verboseLevel )
224     : IODeserialize()
225     , m_filepath( fileName )
226     , m_verboseLevel( verboseLevel )
227 {
228     setDebugLevel(verboseLevel);
229     try {
230         m_parser.set_substitute_entities(); //We just want the text to
231                                             //be resolved/unescaped
232                                             //automatically.
233         m_parser.parse_file( m_filepath );
234     } catch ( const exception& ex ) {
235         cout << "Exception caught: " << ex.what();
236     }
237 }
238
239 Util::XMLDeserialize::~XMLDeserialize()
240 {
241 }
242
243 bool
244 Util::XMLDeserialize::isValid()
245 {
246     return checkVersion();
247 }
248
249 bool
250 Util::XMLDeserialize::checkVersion()
251 {
252     std::string savedVersion;
253     if (read( "CacheVersion", savedVersion )) {
254         Glib::ustring expectedVersion = CACHE_VERSION;
255         debugOutput( DEBUG_LEVEL_NORMAL, "Cache version: %s, expected: %s.\n", savedVersion.c_str(), expectedVersion.c_str() );
256         if (expectedVersion == savedVersion) {
257             debugOutput( DEBUG_LEVEL_VERBOSE, "Cache version OK.\n" );
258             return true;
259         } else {
260             debugOutput( DEBUG_LEVEL_VERBOSE, "Cache version not OK.\n" );
261             return false;
262         }
263     } else return false;
264 }
265
266 bool
267 Util::XMLDeserialize::read( std::string strMemberName,
268                             long long& value )
269
270 {
271     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "lookup %s\n", strMemberName.c_str() );
272
273     xmlpp::Document *pDoc=m_parser.get_document();
274     if(!pDoc) {
275         debugWarning( "no document found\n" );
276         return false;
277     }
278     xmlpp::Node* pNode = pDoc->get_root_node();
279
280     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "pNode = %s\n", pNode->get_name().c_str() );
281
282 #if LIBXMLXX_MAJOR_VERSION == 3
283     xmlpp::Node::NodeSet nodeSet = pNode->find( strMemberName );
284     for ( xmlpp::Node::NodeSet::iterator it = nodeSet.begin();
285           it != nodeSet.end();
286           ++it )
287 #else
288     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
289     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
290           it != nodeSet.end();
291           ++it )
292 #endif
293     {
294         const xmlpp::Element* pElement =
295             dynamic_cast< const xmlpp::Element* >( *it );
296         if ( pElement && pElement->has_child_text() ) {
297             char* tail;
298 #if LIBXMLXX_MAJOR_VERSION == 3
299             value = strtoll( pElement->get_first_child_text()->get_content().c_str(),
300                              &tail, 0 );
301 #else
302             value = strtoll( pElement->get_child_text()->get_content().c_str(),
303                              &tail, 0 );
304 #endif
305             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "found %s = %lld\n",
306                          strMemberName.c_str(), value );
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::read( std::string strMemberName,
319                             std::string& str )
320 {
321     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "lookup %s\n", strMemberName.c_str() );
322
323     xmlpp::Document *pDoc=m_parser.get_document();
324     if(!pDoc) {
325         debugWarning( "no document found\n" );
326         return false;
327     }
328     xmlpp::Node* pNode = pDoc->get_root_node();
329
330 #if LIBXMLXX_MAJOR_VERSION == 3
331     xmlpp::Node::NodeSet nodeSet = pNode->find( strMemberName );
332     for ( xmlpp::Node::NodeSet::iterator it = nodeSet.begin();
333           it != nodeSet.end();
334           ++it )
335 #else
336     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
337     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
338           it != nodeSet.end();
339           ++it )
340 #endif
341     {
342         const xmlpp::Element* pElement = dynamic_cast< const xmlpp::Element* >( *it );
343         if ( pElement ) {
344             if ( pElement->has_child_text() ) {
345 #if LIBXMLXX_MAJOR_VERSION == 3
346                 str = pElement->get_first_child_text()->get_content();
347 #else
348                 str = pElement->get_child_text()->get_content();
349 #endif
350             } else {
351                 str = "";
352             }
353             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "found %s = %s\n",
354                          strMemberName.c_str(), str.c_str() );
355             return true;
356         }
357         debugWarning( "no such a node %s\n", strMemberName.c_str() );
358         return false;
359     }
360
361     debugWarning( "no such a node %s\n", strMemberName.c_str() );
362     return false;
363 }
364
365 bool
366 Util::XMLDeserialize::isExisting( std::string strMemberName )
367 {
368     xmlpp::Document *pDoc=m_parser.get_document();
369     if(!pDoc) {
370         return false;
371     }
372     xmlpp::Node* pNode = pDoc->get_root_node();
373 #if LIBXMLXX_MAJOR_VERSION == 3
374     xmlpp::Node::NodeSet nodeSet = pNode->find( strMemberName );
375 #else
376     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
377 #endif
378     return nodeSet.size() > 0;
379 }
380
381 void
382 tokenize(const string& str,
383          vector<string>& tokens,
384          const string& delimiters)
385 {
386     // Skip delimiters at beginning.
387     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
388     // Find first "non-delimiter".
389     string::size_type pos     = str.find_first_of(delimiters, lastPos);
390
391     while (string::npos != pos || string::npos != lastPos)
392     {
393         // Found a token, add it to the vector.
394         tokens.push_back(str.substr(lastPos, pos - lastPos));
395         // Skip delimiters.  Note the "not_of"
396         lastPos = str.find_first_not_of(delimiters, pos);
397         // Find next "non-delimiter"
398         pos = str.find_first_of(delimiters, lastPos);
399     }
400 }
Note: See TracBrowser for help on using the browser.