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

Revision 864, 9.9 kB (checked in by ppalmers, 16 years ago)

update license to GPLv2 or GPLv3 instead of GPLv2 or any later version. Update copyrights to reflect the new year

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