lib: added record parser for the Content Store database
[barry.git] / src / parser.cc
blobc29b7420bfb80b507d2d20b64845f056b1d1b1d1
1 ///
2 /// \file parser.cc
3 /// Virtual parser wrapper
4 ///
6 /*
7 Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)
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) any later version.
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.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #include "parser.h"
23 #include "r_calendar.h"
24 #include "r_calllog.h"
25 #include "r_bookmark.h"
26 #include "r_contact.h"
27 #include "r_memo.h"
28 #include "r_message.h"
29 #include "r_servicebook.h"
30 #include "r_task.h"
31 #include "r_pin_message.h"
32 #include "r_saved_message.h"
33 #include "r_sms.h"
34 #include "r_folder.h"
35 #include "r_timezone.h"
36 #include "r_cstore.h"
38 #include <iostream>
39 #include <memory>
41 using namespace std;
43 namespace Barry {
45 //////////////////////////////////////////////////////////////////////////////
46 // HexDumpParser class
48 HexDumpParser::HexDumpParser(std::ostream &os)
49 : m_os(os)
53 void HexDumpParser::ParseRecord(const Barry::DBData &data,
54 const IConverter *ic)
56 if( m_last_dbname != data.GetDBName() ) {
57 m_os << "Records for database: " << data.GetDBName() << endl;
58 m_last_dbname = data.GetDBName();
61 m_os << "Raw record dump for record: 0x"
62 << hex << data.GetUniqueId()
63 << ", type: 0x" << hex << (unsigned int) data.GetRecType()
64 << ", offset: 0x" << hex << data.GetOffset()
65 << endl;
66 m_os << data.GetData() << endl;
70 //////////////////////////////////////////////////////////////////////////////
71 // MultiRecordParser class
73 // takes ownership of default_parser!
74 MultiRecordParser::MultiRecordParser(Parser *default_parser)
75 : m_default(default_parser)
79 MultiRecordParser::~MultiRecordParser()
81 map_type::iterator i = m_parsers.begin();
82 for( ; i != m_parsers.end(); ++i ) {
83 delete i->second;
86 // and the default parser
87 delete m_default;
90 void MultiRecordParser::Add(const std::string &dbname, Parser *parser)
92 std::auto_ptr<Parser> p(parser);
94 map_type::iterator i = m_parsers.find(dbname);
95 if( i != m_parsers.end() ) {
96 // found existing parser, so delete it first
97 delete i->second;
99 // assign it
100 i->second = p.release();
102 else {
103 m_parsers[dbname] = p.get();
104 p.release();
108 // takes ownership of parser!
109 void MultiRecordParser::Add(RecordParserBase *parser)
111 std::auto_ptr<Parser> p(parser);
112 std::string name = parser->GetDBName();
113 Add(name, p.release());
116 bool MultiRecordParser::Add(const std::string &dbname,
117 std::ostream &os)
119 std::auto_ptr<Parser> p;
121 #undef HANDLE_PARSER
122 #define HANDLE_PARSER(tname) if( dbname == tname::GetDBName() ) { p.reset( new RecordParser<tname, DumpStore<tname> > (new DumpStore<tname>(os)) ); }
124 // check for recognized database names
125 ALL_KNOWN_PARSER_TYPES
127 if( !p.get() ) {
128 // name not known
129 return false;
132 Add(dbname, p.release());
133 return true;
136 bool MultiRecordParser::Add(const std::string &dbname, AllRecordStore &store)
138 #undef HANDLE_PARSER
139 #define HANDLE_PARSER(tname) \
140 if( dbname == tname::GetDBName() ) { \
141 Add(dbname, new RecordParser<tname, AllRecordStore>(store)); \
142 return true; \
145 // check for recognized database names
146 ALL_KNOWN_PARSER_TYPES
148 // if we get here, record was not found
149 return false;
152 // Parser overrides
153 void MultiRecordParser::ParseRecord(const DBData &data, const IConverter *ic)
155 // search for a named parser
156 map_type::iterator i = m_parsers.find(data.GetDBName());
157 if( i != m_parsers.end() ) {
158 // found one, use it
159 i->second->ParseRecord(data, ic);
161 else if( m_default ) {
162 // use default parser
163 m_default->ParseRecord(data, ic);
168 //////////////////////////////////////////////////////////////////////////////
169 // AllRecordDumpStore class
171 // Use the macro here to implement the overrides, so that
172 // the compiler will catch if we are missing any.
173 #undef HANDLE_PARSER
174 #define HANDLE_PARSER(tname) \
175 void AllRecordDumpStore::operator() (const Barry::tname &r) \
177 m_os << r << std::endl; \
180 ALL_KNOWN_PARSER_TYPES
183 //////////////////////////////////////////////////////////////////////////////
184 // AllRecordDumpParser class
186 AllRecordParser::AllRecordParser(std::ostream &os,
187 Parser *default_parser,
188 AllRecordStore *store)
189 : MultiRecordParser(default_parser)
190 , m_store(store)
192 #undef HANDLE_PARSER
193 #define HANDLE_PARSER(tname) if( m_store ) { Add( new RecordParser<tname, AllRecordStore>(*m_store)); } else { Add(tname::GetDBName(), os); }
195 ALL_KNOWN_PARSER_TYPES;
198 AllRecordParser::~AllRecordParser()
200 delete m_store;
204 //////////////////////////////////////////////////////////////////////////////
205 // TeeParser class
207 TeeParser::TeeParser()
211 TeeParser::~TeeParser()
213 // free all the owned parser pointers
214 for( parser_list_type::iterator i = m_owned_parsers.begin();
215 i != m_owned_parsers.end();
216 ++i )
218 delete *i;
222 // takes ownership of the pointer!
223 void TeeParser::Add(Parser *p)
225 std::auto_ptr<Parser> ap(p);
226 m_owned_parsers.push_back(ap.get());
227 ap.release();
230 // does NOT take ownership
231 void TeeParser::Add(Parser &p)
233 m_external_parsers.push_back(&p);
236 void TeeParser::ParseRecord(const DBData &data, const IConverter *ic)
238 // call all owned parsers
239 for( parser_list_type::iterator i = m_owned_parsers.begin();
240 i != m_owned_parsers.end();
241 ++i )
243 (*i)->ParseRecord(data, ic);
246 // call all external parsers
247 for( parser_list_type::iterator i = m_external_parsers.begin();
248 i != m_external_parsers.end();
249 ++i )
251 (*i)->ParseRecord(data, ic);
255 } // namespace Barry