parser.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       parser.cc
00003 ///             Virtual parser wrapper
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #include "parser.h"
00023 #include "r_calendar.h"
00024 #include "r_calllog.h"
00025 #include "r_bookmark.h"
00026 #include "r_contact.h"
00027 #include "r_memo.h"
00028 #include "r_message.h"
00029 #include "r_servicebook.h"
00030 #include "r_task.h"
00031 #include "r_pin_message.h"
00032 #include "r_saved_message.h"
00033 #include "r_sms.h"
00034 #include "r_folder.h"
00035 #include "r_timezone.h"
00036 #include "r_cstore.h"
00037 #include "r_hhagent.h"
00038 #include "ios_state.h"
00039 
00040 #include <iostream>
00041 #include <memory>
00042 
00043 using namespace std;
00044 
00045 namespace Barry {
00046 
00047 //////////////////////////////////////////////////////////////////////////////
00048 // HexDumpParser class
00049 
00050 HexDumpParser::HexDumpParser(std::ostream &os)
00051         : m_os(os)
00052 {
00053 }
00054 
00055 void HexDumpParser::ParseRecord(const Barry::DBData &data,
00056                                 const IConverter *ic)
00057 {
00058         ios_format_state state(m_os);
00059 
00060         if( m_last_dbname != data.GetDBName() ) {
00061                 m_os << "Records for database: " << data.GetDBName() << endl;
00062                 m_last_dbname = data.GetDBName();
00063         }
00064 
00065         m_os << "Raw record dump for record: 0x"
00066                 << hex << data.GetUniqueId()
00067                 << ", type: 0x" << hex << (unsigned int) data.GetRecType()
00068                 << ", offset: 0x" << hex << data.GetOffset()
00069                 << endl;
00070         m_os << data.GetData() << endl;
00071 }
00072 
00073 
00074 //////////////////////////////////////////////////////////////////////////////
00075 // MultiRecordParser class
00076 
00077 // takes ownership of default_parser!
00078 MultiRecordParser::MultiRecordParser(Parser *default_parser)
00079         : m_delete_default(default_parser) // takes ownership
00080         , m_default(default_parser)
00081 {
00082 }
00083 
00084 // does not take ownership of the default_parser
00085 MultiRecordParser::MultiRecordParser(Parser &default_parser)
00086         : m_delete_default(0)   // no ownership of reference
00087         , m_default(&default_parser)
00088 {
00089 }
00090 
00091 MultiRecordParser::~MultiRecordParser()
00092 {
00093         map_type::iterator i = m_parsers.begin();
00094         for( ; i != m_parsers.end(); ++i ) {
00095                 delete i->second;
00096         }
00097 
00098         // and the default parser
00099         delete m_delete_default;
00100 }
00101 
00102 void MultiRecordParser::Add(const std::string &dbname, Parser *parser)
00103 {
00104         std::auto_ptr<Parser> p(parser);
00105 
00106         map_type::iterator i = m_parsers.find(dbname);
00107         if( i != m_parsers.end() ) {
00108                 // found existing parser, so delete it first
00109                 delete i->second;
00110 
00111                 // assign it
00112                 i->second = p.release();
00113         }
00114         else {
00115                 m_parsers[dbname] = p.get();
00116                 p.release();
00117         }
00118 }
00119 
00120 // takes ownership of parser!
00121 void MultiRecordParser::Add(RecordParserBase *parser)
00122 {
00123         std::auto_ptr<Parser> p(parser);
00124         std::string name = parser->GetDBName();
00125         Add(name, p.release());
00126 }
00127 
00128 bool MultiRecordParser::Add(const std::string &dbname,
00129                                 std::ostream &os)
00130 {
00131         std::auto_ptr<Parser> p;
00132 
00133 #undef HANDLE_PARSER
00134 #define HANDLE_PARSER(tname) if( dbname == tname::GetDBName() ) { p.reset( new RecordParser<tname, DumpStore<tname> > (new DumpStore<tname>(os)) ); }
00135 
00136         // check for recognized database names
00137         ALL_KNOWN_PARSER_TYPES
00138 
00139         if( !p.get() ) {
00140                 // name not known
00141                 return false;
00142         }
00143 
00144         Add(dbname, p.release());
00145         return true;
00146 }
00147 
00148 bool MultiRecordParser::Add(const std::string &dbname, AllRecordStore &store)
00149 {
00150 #undef HANDLE_PARSER
00151 #define HANDLE_PARSER(tname) \
00152         if( dbname == tname::GetDBName() ) { \
00153                 Add(dbname, new RecordParser<tname, AllRecordStore>(store)); \
00154                 return true; \
00155         }
00156 
00157         // check for recognized database names
00158         ALL_KNOWN_PARSER_TYPES
00159 
00160         // if we get here, record was not found
00161         return false;
00162 }
00163 
00164 // Parser overrides
00165 void MultiRecordParser::ParseRecord(const DBData &data, const IConverter *ic)
00166 {
00167         // search for a named parser
00168         map_type::iterator i = m_parsers.find(data.GetDBName());
00169         if( i != m_parsers.end() ) {
00170                 // found one, use it
00171                 i->second->ParseRecord(data, ic);
00172         }
00173         else if( m_default ) {
00174                 // use default parser
00175                 m_default->ParseRecord(data, ic);
00176         }
00177 }
00178 
00179 
00180 //////////////////////////////////////////////////////////////////////////////
00181 // AllRecordDumpStore class
00182 
00183 // Use the macro here to implement the overrides, so that
00184 // the compiler will catch if we are missing any.
00185 #undef HANDLE_PARSER
00186 #define HANDLE_PARSER(tname) \
00187         void AllRecordDumpStore::operator() (const Barry::tname &r) \
00188         { \
00189                 m_os << r << std::endl; \
00190         }
00191 
00192 ALL_KNOWN_PARSER_TYPES
00193 
00194 
00195 //////////////////////////////////////////////////////////////////////////////
00196 // AllRecordDumpParser class
00197 
00198 AllRecordParser::AllRecordParser(std::ostream &os,
00199                                 Parser *default_parser,
00200                                 AllRecordStore *store)
00201         : MultiRecordParser(default_parser)
00202         , m_store(store)        // takes ownership here
00203 {
00204         AddRecords(&os, store);
00205 }
00206 
00207 // does not take ownership of default_parser or store
00208 AllRecordParser::AllRecordParser(Parser &default_parser, AllRecordStore &store)
00209         : MultiRecordParser(default_parser)
00210         , m_store(0)
00211 {
00212         AddRecords(0, &store);
00213 }
00214 
00215 AllRecordParser::~AllRecordParser()
00216 {
00217         delete m_store;
00218 }
00219 
00220 void AllRecordParser::AddRecords(std::ostream *os, AllRecordStore *store)
00221 {
00222         // Does not allow RecordParser<> to own store, since we're using
00223         // it multiple times as the same store for each record type.
00224 #undef HANDLE_PARSER
00225 #define HANDLE_PARSER(tname) \
00226         if( store ) { \
00227                 Add( new RecordParser<tname, AllRecordStore>(*store)); \
00228         } else if( os ) { \
00229                 Add(tname::GetDBName(), *os); \
00230         }
00231 
00232         ALL_KNOWN_PARSER_TYPES;
00233 }
00234 
00235 
00236 //////////////////////////////////////////////////////////////////////////////
00237 // TeeParser class
00238 
00239 TeeParser::TeeParser()
00240 {
00241 }
00242 
00243 TeeParser::~TeeParser()
00244 {
00245         // free all the owned parser pointers
00246         for( parser_list_type::iterator i = m_owned_parsers.begin();
00247                 i != m_owned_parsers.end();
00248                 ++i )
00249         {
00250                 delete *i;
00251         }
00252 }
00253 
00254 // takes ownership of the pointer!
00255 void TeeParser::Add(Parser *p)
00256 {
00257         std::auto_ptr<Parser> ap(p);
00258         m_owned_parsers.push_back(ap.get());
00259         ap.release();
00260 }
00261 
00262 // does NOT take ownership
00263 void TeeParser::Add(Parser &p)
00264 {
00265         m_external_parsers.push_back(&p);
00266 }
00267 
00268 void TeeParser::ParseRecord(const DBData &data, const IConverter *ic)
00269 {
00270         // call all owned parsers
00271         for( parser_list_type::iterator i = m_owned_parsers.begin();
00272                 i != m_owned_parsers.end();
00273                 ++i )
00274         {
00275                 (*i)->ParseRecord(data, ic);
00276         }
00277 
00278         // call all external parsers
00279         for( parser_list_type::iterator i = m_external_parsers.begin();
00280                 i != m_external_parsers.end();
00281                 ++i )
00282         {
00283                 (*i)->ParseRecord(data, ic);
00284         }
00285 }
00286 
00287 } // namespace Barry
00288