lib: fixed parsing of recurring VEVENTS: DAILY and interval support
[barry/progweb.git] / src / parser.cc
blob29d29d14cd0232de18eb5f4fd1f2d62c4217d781
1 ///
2 /// \file parser.cc
3 /// Virtual parser wrapper
4 ///
6 /*
7 Copyright (C) 2005-2012, 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"
37 #include "r_hhagent.h"
38 #include "ios_state.h"
40 #include <iostream>
41 #include <memory>
43 using namespace std;
45 namespace Barry {
47 //////////////////////////////////////////////////////////////////////////////
48 // HexDumpParser class
50 HexDumpParser::HexDumpParser(std::ostream &os)
51 : m_os(os)
55 void HexDumpParser::ParseRecord(const Barry::DBData &data,
56 const IConverter *ic)
58 ios_format_state state(m_os);
60 if( m_last_dbname != data.GetDBName() ) {
61 m_os << "Records for database: " << data.GetDBName() << endl;
62 m_last_dbname = data.GetDBName();
65 m_os << "Raw record dump for record: 0x"
66 << hex << data.GetUniqueId()
67 << ", type: 0x" << hex << (unsigned int) data.GetRecType()
68 << ", offset: 0x" << hex << data.GetOffset()
69 << endl;
70 m_os << data.GetData() << endl;
74 //////////////////////////////////////////////////////////////////////////////
75 // MultiRecordParser class
77 // takes ownership of default_parser!
78 MultiRecordParser::MultiRecordParser(Parser *default_parser)
79 : m_delete_default(default_parser) // takes ownership
80 , m_default(default_parser)
84 // does not take ownership of the default_parser
85 MultiRecordParser::MultiRecordParser(Parser &default_parser)
86 : m_delete_default(0) // no ownership of reference
87 , m_default(&default_parser)
91 MultiRecordParser::~MultiRecordParser()
93 map_type::iterator i = m_parsers.begin();
94 for( ; i != m_parsers.end(); ++i ) {
95 delete i->second;
98 // and the default parser
99 delete m_delete_default;
102 void MultiRecordParser::Add(const std::string &dbname, Parser *parser)
104 std::auto_ptr<Parser> p(parser);
106 map_type::iterator i = m_parsers.find(dbname);
107 if( i != m_parsers.end() ) {
108 // found existing parser, so delete it first
109 delete i->second;
111 // assign it
112 i->second = p.release();
114 else {
115 m_parsers[dbname] = p.get();
116 p.release();
120 // takes ownership of parser!
121 void MultiRecordParser::Add(RecordParserBase *parser)
123 std::auto_ptr<Parser> p(parser);
124 std::string name = parser->GetDBName();
125 Add(name, p.release());
128 bool MultiRecordParser::Add(const std::string &dbname,
129 std::ostream &os)
131 std::auto_ptr<Parser> p;
133 #undef HANDLE_PARSER
134 #define HANDLE_PARSER(tname) if( dbname == tname::GetDBName() ) { p.reset( new RecordParser<tname, DumpStore<tname> > (new DumpStore<tname>(os)) ); }
136 // check for recognized database names
137 ALL_KNOWN_PARSER_TYPES
139 if( !p.get() ) {
140 // name not known
141 return false;
144 Add(dbname, p.release());
145 return true;
148 bool MultiRecordParser::Add(const std::string &dbname, AllRecordStore &store)
150 #undef HANDLE_PARSER
151 #define HANDLE_PARSER(tname) \
152 if( dbname == tname::GetDBName() ) { \
153 Add(dbname, new RecordParser<tname, AllRecordStore>(store)); \
154 return true; \
157 // check for recognized database names
158 ALL_KNOWN_PARSER_TYPES
160 // if we get here, record was not found
161 return false;
164 // Parser overrides
165 void MultiRecordParser::ParseRecord(const DBData &data, const IConverter *ic)
167 // search for a named parser
168 map_type::iterator i = m_parsers.find(data.GetDBName());
169 if( i != m_parsers.end() ) {
170 // found one, use it
171 i->second->ParseRecord(data, ic);
173 else if( m_default ) {
174 // use default parser
175 m_default->ParseRecord(data, ic);
180 //////////////////////////////////////////////////////////////////////////////
181 // AllRecordDumpStore class
183 // Use the macro here to implement the overrides, so that
184 // the compiler will catch if we are missing any.
185 #undef HANDLE_PARSER
186 #define HANDLE_PARSER(tname) \
187 void AllRecordDumpStore::operator() (const Barry::tname &r) \
189 m_os << r << std::endl; \
192 ALL_KNOWN_PARSER_TYPES
195 //////////////////////////////////////////////////////////////////////////////
196 // AllRecordDumpParser class
198 AllRecordParser::AllRecordParser(std::ostream &os,
199 Parser *default_parser,
200 AllRecordStore *store)
201 : MultiRecordParser(default_parser)
202 , m_store(store) // takes ownership here
204 AddRecords(&os, store);
207 // does not take ownership of default_parser or store
208 AllRecordParser::AllRecordParser(Parser &default_parser, AllRecordStore &store)
209 : MultiRecordParser(default_parser)
210 , m_store(0)
212 AddRecords(0, &store);
215 AllRecordParser::~AllRecordParser()
217 delete m_store;
220 void AllRecordParser::AddRecords(std::ostream *os, AllRecordStore *store)
222 // Does not allow RecordParser<> to own store, since we're using
223 // it multiple times as the same store for each record type.
224 #undef HANDLE_PARSER
225 #define HANDLE_PARSER(tname) \
226 if( store ) { \
227 Add( new RecordParser<tname, AllRecordStore>(*store)); \
228 } else if( os ) { \
229 Add(tname::GetDBName(), *os); \
232 ALL_KNOWN_PARSER_TYPES;
236 //////////////////////////////////////////////////////////////////////////////
237 // TeeParser class
239 TeeParser::TeeParser()
243 TeeParser::~TeeParser()
245 // free all the owned parser pointers
246 for( parser_list_type::iterator i = m_owned_parsers.begin();
247 i != m_owned_parsers.end();
248 ++i )
250 delete *i;
254 // takes ownership of the pointer!
255 void TeeParser::Add(Parser *p)
257 std::auto_ptr<Parser> ap(p);
258 m_owned_parsers.push_back(ap.get());
259 ap.release();
262 // does NOT take ownership
263 void TeeParser::Add(Parser &p)
265 m_external_parsers.push_back(&p);
268 void TeeParser::ParseRecord(const DBData &data, const IConverter *ic)
270 // call all owned parsers
271 for( parser_list_type::iterator i = m_owned_parsers.begin();
272 i != m_owned_parsers.end();
273 ++i )
275 (*i)->ParseRecord(data, ic);
278 // call all external parsers
279 for( parser_list_type::iterator i = m_external_parsers.begin();
280 i != m_external_parsers.end();
281 ++i )
283 (*i)->ParseRecord(data, ic);
287 } // namespace Barry