root/branches/ppalmers-libutil/serialize.cpp

Revision 620, 8.8 kB (checked in by wagi, 17 years ago)

- one tokenize function is enough. currently in serialize.h defined, this might change
- saveCache code workover. The cache is now created in ~/.ffado/cache. It is actived since it should break
things. Otherwise it needs fixing.

Line 
1 /*
2  * Copyright (C) 2005-2007 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 library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License version 2.1, as published by the Free Software Foundation;
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02110-1301 USA
22  */
23
24 #include "serialize.h"
25
26 using namespace std;
27
28
29 IMPL_DEBUG_MODULE( Util::XMLSerialize,   XMLSerialize,   DEBUG_LEVEL_NORMAL );
30 IMPL_DEBUG_MODULE( Util::XMLDeserialize, XMLDeserialize, DEBUG_LEVEL_NORMAL );
31
32 Util::XMLSerialize::XMLSerialize( Glib::ustring fileName )
33     : IOSerialize()
34     , m_filepath( fileName )
35     , m_verboseLevel( 0 )
36 {
37     try {
38         m_doc.create_root_node( "ffado_cache" );
39     } catch ( const exception& ex ) {
40         cout << "Exception caught: " << ex.what();
41     }
42 }
43
44
45 Util::XMLSerialize::XMLSerialize( Glib::ustring fileName, int verboseLevel )
46     : IOSerialize()
47     , m_filepath( fileName )
48     , m_verboseLevel( verboseLevel )
49 {
50     try {
51         m_doc.create_root_node( "ffado_cache" );
52     } catch ( const exception& ex ) {
53         cout << "Exception caught: " << ex.what();
54     }
55 }
56
57 Util::XMLSerialize::~XMLSerialize()
58 {
59     try {
60         m_doc.write_to_file_formatted( m_filepath );
61     } catch ( const exception& ex ) {
62         cout << "Exception caugth: " << ex.what();
63     }
64
65 }
66
67 bool
68 Util::XMLSerialize::write( std::string strMemberName,
69                            long long value )
70
71 {
72     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "write %s = %d\n",
73                  strMemberName.c_str(), value );
74
75     vector<string> tokens;
76     tokenize( strMemberName, tokens, "/" );
77
78     if ( tokens.size() == 0 ) {
79         debugWarning( "token size is 0\n" );
80         return false;
81     }
82
83     xmlpp::Node* pNode = m_doc.get_root_node();
84     pNode = getNodePath( pNode, tokens );
85
86     // element to be added
87     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
88     char* valstr;
89     asprintf( &valstr, "%lld", value );
90     pElem->set_child_text( valstr );
91     free( valstr );
92
93     return true;
94 }
95
96 bool
97 Util::XMLSerialize::write( std::string strMemberName,
98                            Glib::ustring str)
99 {
100     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "write %s = %s\n",
101                  strMemberName.c_str(), str.c_str() );
102
103     vector<string> tokens;
104     tokenize( strMemberName, tokens, "/" );
105
106     if ( tokens.size() == 0 ) {
107         debugWarning( "token size is 0\n" );
108         return false;
109     }
110
111     xmlpp::Node* pNode = m_doc.get_root_node();
112     pNode = getNodePath( pNode, tokens );
113
114     // element to be added
115     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
116     pElem->set_child_text( str );
117
118     return true;
119 }
120
121 xmlpp::Node*
122 Util::XMLSerialize::getNodePath( xmlpp::Node* pRootNode,
123                                  std::vector<string>& tokens )
124 {
125     // returns the correct node on which the new element has to be added.
126     // if the path does not exist, it will be created.
127
128     if ( tokens.size() == 1 ) {
129         return pRootNode;
130     }
131
132     unsigned int iTokenIdx = 0;
133     xmlpp::Node* pCurNode = pRootNode;
134     for (bool bFound = false;
135          ( iTokenIdx < tokens.size() - 1 );
136          bFound = false, iTokenIdx++ )
137     {
138         xmlpp::Node::NodeList nodeList = pCurNode->get_children();
139         for ( xmlpp::Node::NodeList::iterator it = nodeList.begin();
140               it != nodeList.end();
141               ++it )
142         {
143             if ( ( *it )->get_name() == tokens[iTokenIdx] ) {
144                 pCurNode = *it;
145                 bFound = true;
146                 break;
147             }
148         }
149         if ( !bFound ) {
150             break;
151         }
152     }
153
154     for ( unsigned int i = iTokenIdx; i < tokens.size() - 1; i++, iTokenIdx++ ) {
155         pCurNode = pCurNode->add_child( tokens[iTokenIdx] );
156     }
157     return pCurNode;
158
159 }
160
161 /***********************************/
162
163 Util::XMLDeserialize::XMLDeserialize( Glib::ustring fileName )
164     : IODeserialize()
165     , m_filepath( fileName )
166     , m_verboseLevel( 0 )
167 {
168     try {
169         m_parser.set_substitute_entities(); //We just want the text to
170                                             //be resolved/unescaped
171                                             //automatically.
172         m_parser.parse_file( m_filepath );
173     } catch ( const exception& ex ) {
174         cout << "Exception caught: " << ex.what();
175     }
176 }
177
178 Util::XMLDeserialize::XMLDeserialize( Glib::ustring fileName, int verboseLevel )
179     : IODeserialize()
180     , m_filepath( fileName )
181     , m_verboseLevel( verboseLevel )
182 {
183     try {
184         m_parser.set_substitute_entities(); //We just want the text to
185                                             //be resolved/unescaped
186                                             //automatically.
187         m_parser.parse_file( m_filepath );
188     } catch ( const exception& ex ) {
189         cout << "Exception caught: " << ex.what();
190     }
191 }
192
193 Util::XMLDeserialize::~XMLDeserialize()
194 {
195 }
196
197 bool
198 Util::XMLDeserialize::read( std::string strMemberName,
199                             long long& value )
200
201 {
202     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "lookup %s\n", strMemberName.c_str() );
203
204     xmlpp::Document *pDoc=m_parser.get_document();
205     if(!pDoc) {
206         debugWarning( "no document found\n" );
207         return false;
208     }
209     xmlpp::Node* pNode = pDoc->get_root_node();
210
211     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "pNode = %s\n", pNode->get_name().c_str() );
212
213     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
214     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
215           it != nodeSet.end();
216           ++it )
217     {
218         const xmlpp::Element* pElement =
219             dynamic_cast< const xmlpp::Element* >( *it );
220         if ( pElement && pElement->has_child_text() ) {
221             char* tail;
222             value = strtoll( pElement->get_child_text()->get_content().c_str(),
223                              &tail, 0 );
224             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "found %s = %d\n",
225                          strMemberName.c_str(), value );
226             return true;
227         }
228         debugWarning( "no such a node %s\n", strMemberName.c_str() );
229         return false;
230     }
231
232     debugWarning( "no such a node %s\n", strMemberName.c_str() );
233     return false;
234 }
235
236 bool
237 Util::XMLDeserialize::read( std::string strMemberName,
238                             Glib::ustring& str )
239 {
240     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "lookup %s\n", strMemberName.c_str() );
241
242     xmlpp::Document *pDoc=m_parser.get_document();
243     if(!pDoc) {
244         debugWarning( "no document found\n" );
245         return false;
246     }
247     xmlpp::Node* pNode = pDoc->get_root_node();
248
249     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
250     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
251           it != nodeSet.end();
252           ++it )
253     {
254         const xmlpp::Element* pElement = dynamic_cast< const xmlpp::Element* >( *it );
255         if ( pElement ) {
256             if ( pElement->has_child_text() ) {
257                 str = pElement->get_child_text()->get_content();
258             } else {
259                 str = "";
260             }
261             debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "found %s = %s\n",
262                          strMemberName.c_str(), str.c_str() );
263             return true;
264         }
265         debugWarning( "no such a node %s\n", strMemberName.c_str() );
266         return false;
267     }
268
269     debugWarning( "no such a node %s\n", strMemberName.c_str() );
270     return false;
271 }
272
273 bool
274 Util::XMLDeserialize::isExisting( std::string strMemberName )
275 {
276     xmlpp::Document *pDoc=m_parser.get_document();
277     if(!pDoc) {
278         return false;
279     }
280     xmlpp::Node* pNode = pDoc->get_root_node();
281     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
282     return nodeSet.size() > 0;
283 }
284
285 void
286 tokenize(const string& str,
287          vector<string>& tokens,
288          const string& delimiters)
289 {
290     // Skip delimiters at beginning.
291     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
292     // Find first "non-delimiter".
293     string::size_type pos     = str.find_first_of(delimiters, lastPos);
294
295     while (string::npos != pos || string::npos != lastPos)
296     {
297         // Found a token, add it to the vector.
298         tokens.push_back(str.substr(lastPos, pos - lastPos));
299         // Skip delimiters.  Note the "not_of"
300         lastPos = str.find_first_not_of(delimiters, pos);
301         // Find next "non-delimiter"
302         pos = str.find_first_of(delimiters, lastPos);
303     }
304 }
Note: See TracBrowser for help on using the browser.