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-2011, 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 
00038 #include <iostream>
00039 #include <memory>
00040 
00041 using namespace std;
00042 
00043 namespace Barry {
00044 
00045 //////////////////////////////////////////////////////////////////////////////
00046 // HexDumpParser class
00047 
00048 HexDumpParser::HexDumpParser(std::ostream &os)
00049         : m_os(os)
00050 {
00051 }
00052 
00053 void HexDumpParser::ParseRecord(const Barry::DBData &data,
00054                                 const IConverter *ic)
00055 {
00056         if( m_last_dbname != data.GetDBName() ) {
00057                 m_os << "Records for database: " << data.GetDBName() << endl;
00058                 m_last_dbname = data.GetDBName();
00059         }
00060 
00061         m_os << "Raw record dump for record: 0x"
00062                 << hex << data.GetUniqueId()
00063                 << ", type: 0x" << hex << (unsigned int) data.GetRecType()
00064                 << ", offset: 0x" << hex << data.GetOffset()
00065                 << endl;
00066         m_os << data.GetData() << endl;
00067 }
00068 
00069 
00070 //////////////////////////////////////////////////////////////////////////////
00071 // MultiRecordParser class
00072 
00073 // takes ownership of default_parser!
00074 MultiRecordParser::MultiRecordParser(Parser *default_parser)
00075         : m_default(default_parser)
00076 {
00077 }
00078 
00079 MultiRecordParser::~MultiRecordParser()
00080 {
00081         map_type::iterator i = m_parsers.begin();
00082         for( ; i != m_parsers.end(); ++i ) {
00083                 delete i->second;
00084         }
00085 
00086         // and the default parser
00087         delete m_default;
00088 }
00089 
00090 void MultiRecordParser::Add(const std::string &dbname, Parser *parser)
00091 {
00092         std::auto_ptr<Parser> p(parser);
00093 
00094         map_type::iterator i = m_parsers.find(dbname);
00095         if( i != m_parsers.end() ) {
00096                 // found existing parser, so delete it first
00097                 delete i->second;
00098 
00099                 // assign it
00100                 i->second = p.release();
00101         }
00102         else {
00103                 m_parsers[dbname] = p.get();
00104                 p.release();
00105         }
00106 }
00107 
00108 // takes ownership of parser!
00109 void MultiRecordParser::Add(RecordParserBase *parser)
00110 {
00111         std::auto_ptr<Parser> p(parser);
00112         std::string name = parser->GetDBName();
00113         Add(name, p.release());
00114 }
00115 
00116 bool MultiRecordParser::Add(const std::string &dbname,
00117                                 std::ostream &os)
00118 {
00119         std::auto_ptr<Parser> p;
00120 
00121 #undef HANDLE_PARSER
00122 #define HANDLE_PARSER(tname) if( dbname == tname::GetDBName() ) { p.reset( new RecordParser<tname, DumpStore<tname> > (new DumpStore<tname>(os)) ); }
00123 
00124         // check for recognized database names
00125         ALL_KNOWN_PARSER_TYPES
00126 
00127         if( !p.get() ) {
00128                 // name not known
00129                 return false;
00130         }
00131 
00132         Add(dbname, p.release());
00133         return true;
00134 }
00135 
00136 bool MultiRecordParser::Add(const std::string &dbname, AllRecordStore &store)
00137 {
00138 #undef HANDLE_PARSER
00139 #define HANDLE_PARSER(tname) \
00140         if( dbname == tname::GetDBName() ) { \
00141                 Add(dbname, new RecordParser<tname, AllRecordStore>(store)); \
00142                 return true; \
00143         }
00144 
00145         // check for recognized database names
00146         ALL_KNOWN_PARSER_TYPES
00147 
00148         // if we get here, record was not found
00149         return false;
00150 }
00151 
00152 // Parser overrides
00153 void MultiRecordParser::ParseRecord(const DBData &data, const IConverter *ic)
00154 {
00155         // search for a named parser
00156         map_type::iterator i = m_parsers.find(data.GetDBName());
00157         if( i != m_parsers.end() ) {
00158                 // found one, use it
00159                 i->second->ParseRecord(data, ic);
00160         }
00161         else if( m_default ) {
00162                 // use default parser
00163                 m_default->ParseRecord(data, ic);
00164         }
00165 }
00166 
00167 
00168 //////////////////////////////////////////////////////////////////////////////
00169 // AllRecordDumpStore class
00170 
00171 // Use the macro here to implement the overrides, so that
00172 // the compiler will catch if we are missing any.
00173 #undef HANDLE_PARSER
00174 #define HANDLE_PARSER(tname) \
00175         void AllRecordDumpStore::operator() (const Barry::tname &r) \
00176         { \
00177                 m_os << r << std::endl; \
00178         }
00179 
00180 ALL_KNOWN_PARSER_TYPES
00181 
00182 
00183 //////////////////////////////////////////////////////////////////////////////
00184 // AllRecordDumpParser class
00185 
00186 AllRecordParser::AllRecordParser(std::ostream &os,
00187                                 Parser *default_parser,
00188                                 AllRecordStore *store)
00189         : MultiRecordParser(default_parser)
00190         , m_store(store)
00191 {
00192 #undef HANDLE_PARSER
00193 #define HANDLE_PARSER(tname) if( m_store ) { Add( new RecordParser<tname, AllRecordStore>(*m_store)); } else { Add(tname::GetDBName(), os); }
00194 
00195         ALL_KNOWN_PARSER_TYPES;
00196 }
00197 
00198 AllRecordParser::~AllRecordParser()
00199 {
00200         delete m_store;
00201 }
00202 
00203 
00204 //////////////////////////////////////////////////////////////////////////////
00205 // TeeParser class
00206 
00207 TeeParser::TeeParser()
00208 {
00209 }
00210 
00211 TeeParser::~TeeParser()
00212 {
00213         // free all the owned parser pointers
00214         for( parser_list_type::iterator i = m_owned_parsers.begin();
00215                 i != m_owned_parsers.end();
00216                 ++i )
00217         {
00218                 delete *i;
00219         }
00220 }
00221 
00222 // takes ownership of the pointer!
00223 void TeeParser::Add(Parser *p)
00224 {
00225         std::auto_ptr<Parser> ap(p);
00226         m_owned_parsers.push_back(ap.get());
00227         ap.release();
00228 }
00229 
00230 // does NOT take ownership
00231 void TeeParser::Add(Parser &p)
00232 {
00233         m_external_parsers.push_back(&p);
00234 }
00235 
00236 void TeeParser::ParseRecord(const DBData &data, const IConverter *ic)
00237 {
00238         // call all owned parsers
00239         for( parser_list_type::iterator i = m_owned_parsers.begin();
00240                 i != m_owned_parsers.end();
00241                 ++i )
00242         {
00243                 (*i)->ParseRecord(data, ic);
00244         }
00245 
00246         // call all external parsers
00247         for( parser_list_type::iterator i = m_external_parsers.begin();
00248                 i != m_external_parsers.end();
00249                 ++i )
00250         {
00251                 (*i)->ParseRecord(data, ic);
00252         }
00253 }
00254 
00255 } // namespace Barry
00256