# 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