root/branches/streaming-rework/src/libutil/serialize.cpp

Revision 417, 6.5 kB (checked in by pieterpalmers, 17 years ago)

- some small segfault fixes in the serialization

Line 
1 /* serialize.cpp
2  * Copyright (C) 2006,07 by Daniel Wagner
3  *
4  * This file is part of FreeBoB.
5  *
6  * FreeBoB is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * FreeBoB is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with FreeBoB; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA.
19  */
20
21 #include "serialize.h"
22
23 using namespace std;
24
25 void tokenize(const string& str,
26               vector<string>& tokens,
27               const string& delimiters = " ")
28 {
29     // Skip delimiters at beginning.
30     string::size_type lastPos = str.find_first_not_of(delimiters, 0);
31     // Find first "non-delimiter".
32     string::size_type pos     = str.find_first_of(delimiters, lastPos);
33
34     while (string::npos != pos || string::npos != lastPos) {
35         // Found a token, add it to the vector.
36         tokens.push_back(str.substr(lastPos, pos - lastPos));
37         // Skip delimiters.  Note the "not_of"
38         lastPos = str.find_first_not_of(delimiters, pos);
39         // Find next "non-delimiter"
40         pos = str.find_first_of(delimiters, lastPos);
41     }
42 }
43
44 /////////////////////////////////
45
46 Util::XMLSerialize::XMLSerialize( Glib::ustring fileName )
47     : IOSerialize()
48     , m_filepath( fileName )
49 {
50     try {
51         m_doc.create_root_node( "freebob_cache" );
52     } catch ( const exception& ex ) {
53         cout << "Exception caught: " << ex.what();
54     }
55 }
56
57
58 Util::XMLSerialize::~XMLSerialize()
59 {
60     try {
61         m_doc.write_to_file_formatted( m_filepath );
62     } catch ( const exception& ex ) {
63         cout << "Exception caugth: " << ex.what();
64     }
65
66 }
67
68 bool
69 Util::XMLSerialize::write( std::string strMemberName,
70                            long long value )
71
72 {
73     vector<string> tokens;
74     tokenize( strMemberName, tokens, "/" );
75
76     if ( tokens.size() == 0 ) {
77         return false;
78     }
79
80     xmlpp::Node* pNode = m_doc.get_root_node();
81     pNode = getNodePath( pNode, tokens );
82
83     // element to be added
84     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
85     char* valstr;
86     asprintf( &valstr, "%lld", value );
87     pElem->set_child_text( valstr );
88     free( valstr );
89
90     return true;
91 }
92
93 bool
94 Util::XMLSerialize::write( std::string strMemberName,
95                            Glib::ustring str)
96 {
97     vector<string> tokens;
98     tokenize( strMemberName, tokens, "/" );
99
100     if ( tokens.size() == 0 ) {
101         return false;
102     }
103
104     xmlpp::Node* pNode = m_doc.get_root_node();
105     pNode = getNodePath( pNode, tokens );
106
107     // element to be added
108     xmlpp::Element* pElem = pNode->add_child( tokens[tokens.size() - 1] );
109     pElem->set_child_text( str );
110
111     return true;
112 }
113
114 xmlpp::Node*
115 Util::XMLSerialize::getNodePath( xmlpp::Node* pRootNode,
116                                  std::vector<string>& tokens )
117 {
118     // returns the correct node on which the new element has to be added.
119     // if the path does not exist, it will be created.
120
121     if ( tokens.size() == 1 ) {
122         return pRootNode;
123     }
124
125     unsigned int iTokenIdx = 0;
126     xmlpp::Node* pCurNode = pRootNode;
127     for (bool bFound = false;
128          ( iTokenIdx < tokens.size() - 1 );
129          bFound = false, iTokenIdx++ )
130     {
131         xmlpp::Node::NodeList nodeList = pCurNode->get_children();
132         for ( xmlpp::Node::NodeList::iterator it = nodeList.begin();
133               it != nodeList.end();
134               ++it )
135         {
136             if ( ( *it )->get_name() == tokens[iTokenIdx] ) {
137                 pCurNode = *it;
138                 bFound = true;
139                 break;
140             }
141         }
142         if ( !bFound ) {
143             break;
144         }
145     }
146
147     for ( unsigned int i = iTokenIdx; i < tokens.size() - 1; i++, iTokenIdx++ ) {
148         pCurNode = pCurNode->add_child( tokens[iTokenIdx] );
149     }
150     return pCurNode;
151
152 }
153
154 /***********************************/
155
156 Util::XMLDeserialize::XMLDeserialize( Glib::ustring fileName )
157     : IODeserialize()
158     , m_filepath( fileName )
159 {
160     try {
161         m_parser.set_substitute_entities(); //We just want the text to
162                                             //be resolved/unescaped
163                                             //automatically.
164         m_parser.parse_file( m_filepath );
165     } catch ( const exception& ex ) {
166         cout << "Exception caught: " << ex.what();
167     }
168 }
169
170
171 Util::XMLDeserialize::~XMLDeserialize()
172 {
173 }
174
175 bool
176 Util::XMLDeserialize::read( std::string strMemberName,
177                             long long& value )
178
179 {
180     xmlpp::Document *pDoc=m_parser.get_document();
181     if(!pDoc) {
182         return false;
183     }
184     xmlpp::Node* pNode = pDoc->get_root_node();
185
186     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
187     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
188           it != nodeSet.end();
189           ++it )
190     {
191         const xmlpp::Element* pElement =
192             dynamic_cast< const xmlpp::Element* >( *it );
193         if ( pElement && pElement->has_child_text() ) {
194             char* tail;
195             value = strtoll( pElement->get_child_text()->get_content().c_str(),
196                              &tail, 0 );
197             return true;
198         }
199         return false;
200     }
201
202     return false;
203 }
204
205 bool
206 Util::XMLDeserialize::read( std::string strMemberName,
207                             Glib::ustring& str )
208 {
209     xmlpp::Document *pDoc=m_parser.get_document();
210     if(!pDoc) {
211         return false;
212     }
213     xmlpp::Node* pNode = pDoc->get_root_node();
214    
215     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
216     for ( xmlpp::NodeSet::iterator it = nodeSet.begin();
217           it != nodeSet.end();
218           ++it )
219     {
220         const xmlpp::Element* pElement = dynamic_cast< const xmlpp::Element* >( *it );
221         if ( pElement && pElement->has_child_text() ) {
222             str = pElement->get_child_text()->get_content();
223             return true;
224         }
225         return false;
226     }
227
228     return false;
229 }
230
231 bool
232 Util::XMLDeserialize::isExisting( std::string strMemberName )
233 {
234     xmlpp::Document *pDoc=m_parser.get_document();
235     if(!pDoc) {
236         return false;
237     }
238     xmlpp::Node* pNode = pDoc->get_root_node();
239     xmlpp::NodeSet nodeSet = pNode->find( strMemberName );
240     return nodeSet.size() > 0;
241 }
Note: See TracBrowser for help on using the browser.