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_delete_default(default_parser) // takes ownership
00076         , m_default(default_parser)
00077 {
00078 }
00079 
00080 // does not take ownership of the default_parser
00081 MultiRecordParser::MultiRecordParser(Parser &default_parser)
00082         : m_delete_default(0)   // no ownership of reference
00083         , m_default(&default_parser)
00084 {
00085 }
00086 
00087 MultiRecordParser::~MultiRecordParser()
00088 {
00089         map_type::iterator i = m_parsers.begin();
00090         for( ; i != m_parsers.end(); ++i ) {
00091                 delete i->second;
00092         }
00093 
00094         // and the default parser
00095         delete m_delete_default;
00096 }
00097 
00098 void MultiRecordParser::Add(const std::string &dbname, Parser *parser)
00099 {
00100         std::auto_ptr<Parser> p(parser);
00101 
00102         map_type::iterator i = m_parsers.find(dbname);
00103         if( i != m_parsers.end() ) {
00104                 // found existing parser, so delete it first
00105                 delete i->second;
00106 
00107                 // assign it
00108                 i->second = p.release();
00109         }
00110         else {
00111                 m_parsers[dbname] = p.get();
00112                 p.release();
00113         }
00114 }
00115 
00116 // takes ownership of parser!
00117 void MultiRecordParser::Add(RecordParserBase *parser)
00118 {
00119         std::auto_ptr<Parser> p(parser);
00120         std::string name = parser->GetDBName();
00121         Add(name, p.release());
00122 }
00123 
00124 bool MultiRecordParser::Add(const std::string &dbname,
00125                                 std::ostream &os)
00126 {
00127         std::auto_ptr<Parser> p;
00128 
00129 #undef HANDLE_PARSER
00130 #define HANDLE_PARSER(tname) if( dbname == tname::GetDBName() ) { p.reset( new RecordParser<tname, DumpStore<tname> > (new DumpStore<tname>(os)) ); }
00131 
00132         // check for recognized database names
00133         ALL_KNOWN_PARSER_TYPES
00134 
00135         if( !p.get() ) {
00136                 // name not known
00137                 return false;
00138         }
00139 
00140         Add(dbname, p.release());
00141         return true;
00142 }
00143 
00144 bool MultiRecordParser::Add(const std::string &dbname, AllRecordStore &store)
00145 {
00146 #undef HANDLE_PARSER
00147 #define HANDLE_PARSER(tname) \
00148         if( dbname == tname::GetDBName() ) { \
00149                 Add(dbname, new RecordParser<tname, AllRecordStore>(store)); \
00150                 return true; \
00151         }
00152 
00153         // check for recognized database names
00154         ALL_KNOWN_PARSER_TYPES
00155 
00156         // if we get here, record was not found
00157         return false;
00158 }
00159 
00160 // Parser overrides
00161 void MultiRecordParser::ParseRecord(const DBData &data, const IConverter *ic)
00162 {
00163         // search for a named parser
00164         map_type::iterator i = m_parsers.find(data.GetDBName());
00165         if( i != m_parsers.end() ) {
00166                 // found one, use it
00167                 i->second->ParseRecord(data, ic);
00168         }
00169         else if( m_default ) {
00170                 // use default parser
00171                 m_default->ParseRecord(data, ic);
00172         }
00173 }
00174 
00175 
00176 //////////////////////////////////////////////////////////////////////////////
00177 // AllRecordDumpStore class
00178 
00179 // Use the macro here to implement the overrides, so that
00180 // the compiler will catch if we are missing any.
00181 #undef HANDLE_PARSER
00182 #define HANDLE_PARSER(tname) \
00183         void AllRecordDumpStore::operator() (const Barry::tname &r) \
00184         { \
00185                 m_os << r << std::endl; \
00186         }
00187 
00188 ALL_KNOWN_PARSER_TYPES
00189 
00190 
00191 //////////////////////////////////////////////////////////////////////////////
00192 // AllRecordDumpParser class
00193 
00194 AllRecordParser::AllRecordParser(std::ostream &os,
00195                                 Parser *default_parser,
00196                                 AllRecordStore *store)
00197         : MultiRecordParser(default_parser)
00198         , m_store(store)        // takes ownership here
00199 {
00200         AddRecords(&os, store);
00201 }
00202 
00203 // does not take ownership of default_parser or store
00204 AllRecordParser::AllRecordParser(Parser &default_parser, AllRecordStore &store)
00205         : MultiRecordParser(default_parser)
00206         , m_store(0)
00207 {
00208         AddRecords(0, &store);
00209 }
00210 
00211 AllRecordParser::~AllRecordParser()
00212 {
00213         delete m_store;
00214 }
00215 
00216 void AllRecordParser::AddRecords(std::ostream *os, AllRecordStore *store)
00217 {
00218         // Does not allow RecordParser<> to own store, since we're using
00219         // it multiple times as the same store for each record type.
00220 #undef HANDLE_PARSER
00221 #define HANDLE_PARSER(tname) \
00222         if( store ) { \
00223                 Add( new RecordParser<tname, AllRecordStore>(*store)); \
00224         } else if( os ) { \
00225                 Add(tname::GetDBName(), *os); \
00226         }
00227 
00228         ALL_KNOWN_PARSER_TYPES;
00229 }
00230 
00231 
00232 //////////////////////////////////////////////////////////////////////////////
00233 // TeeParser class
00234 
00235 TeeParser::TeeParser()
00236 {
00237 }
00238 
00239 TeeParser::~TeeParser()
00240 {
00241         // free all the owned parser pointers
00242         for( parser_list_type::iterator i = m_owned_parsers.begin();
00243                 i != m_owned_parsers.end();
00244                 ++i )
00245         {
00246                 delete *i;
00247         }
00248 }
00249 
00250 // takes ownership of the pointer!
00251 void TeeParser::Add(Parser *p)
00252 {
00253         std::auto_ptr<Parser> ap(p);
00254         m_owned_parsers.push_back(ap.get());
00255         ap.release();
00256 }
00257 
00258 // does NOT take ownership
00259 void TeeParser::Add(Parser &p)
00260 {
00261         m_external_parsers.push_back(&p);
00262 }
00263 
00264 void TeeParser::ParseRecord(const DBData &data, const IConverter *ic)
00265 {
00266         // call all owned parsers
00267         for( parser_list_type::iterator i = m_owned_parsers.begin();
00268                 i != m_owned_parsers.end();
00269                 ++i )
00270         {
00271                 (*i)->ParseRecord(data, ic);
00272         }
00273 
00274         // call all external parsers
00275         for( parser_list_type::iterator i = m_external_parsers.begin();
00276                 i != m_external_parsers.end();
00277                 ++i )
00278         {
00279                 (*i)->ParseRecord(data, ic);
00280         }
00281 }
00282 
00283 } // namespace Barry
00284 

Generated on Tue Mar 1 17:50:15 2011 for Barry by  doxygen 1.5.6