00001 /// 00002 /// \file parser.h 00003 /// Virtual parser wrapper 00004 /// 00005 00006 /* 00007 Copyright (C) 2005-2010, 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 #ifndef __BARRY_PARSER_H__ 00023 #define __BARRY_PARSER_H__ 00024 00025 #include "dll.h" 00026 #include "data.h" 00027 #include "protocol.h" 00028 #include <stdint.h> // for uint32_t 00029 00030 // forward declarations 00031 namespace Barry { 00032 class Data; 00033 class IConverter; 00034 } 00035 00036 namespace Barry { 00037 00038 // 00039 // Parser class 00040 // 00041 /// Base class for the parser hierarchy. 00042 /// 00043 /// This class provides the interface that the Controller class uses 00044 /// to pass raw data it reads from the device. The Controller, along 00045 /// with the Packet class, calls each of the virtual functions below 00046 /// in the same order. 00047 /// 00048 /// This class is kept as a pure abstract class, in order to make sure 00049 /// that the compiler will catch any API changes, for code derived 00050 /// from it. 00051 /// 00052 class BXEXPORT Parser 00053 { 00054 public: 00055 Parser() {} 00056 virtual ~Parser() {} 00057 00058 /// Reset and prepare for a new raw data packet 00059 virtual void Clear() = 0; 00060 00061 /// Stores the IDs 00062 virtual void SetIds(uint8_t RecType, uint32_t UniqueId) = 0; 00063 00064 /// Called to parse the header portion of the raw data packet. 00065 /// data contains the entire packet, and offset contains the 00066 /// location at which to start parsing. 00067 virtual void ParseHeader(const Data &data, size_t &offset) = 0; 00068 00069 /// Called to parse sub fields in the raw data packet. 00070 /// The same data is passed as was passed in ParseHeader, 00071 /// only the offset will be updated if it was advanced during 00072 /// the header parsing. 00073 virtual void ParseFields(const Data &data, size_t &offset, 00074 const IConverter *ic) = 0; 00075 00076 /// Called at the very end of record parsing, and used to 00077 /// store the final packet somewhere, either in memory, disk, etc. 00078 virtual void Store() = 0; 00079 }; 00080 00081 00082 // 00083 // NullParser class 00084 // 00085 /// If in debug mode, this class can be used as a null parser. 00086 /// Call Init() and the protocol will be dumped to stdout and 00087 /// no parsing will be done. 00088 /// 00089 /// Do NOT derive your own personal parser classes from this, 00090 /// unless you are perfectly confident that you will catch 00091 /// future API changes on the devel tree without the compiler's 00092 /// help. 00093 /// 00094 class BXEXPORT NullParser : public Parser 00095 { 00096 public: 00097 NullParser() {} 00098 virtual ~NullParser() {} 00099 00100 /// Reset and prepare for a new raw data packet 00101 virtual void Clear() {} 00102 00103 /// Stores the IDs 00104 virtual void SetIds(uint8_t RecType, uint32_t UniqueId) {} 00105 00106 /// Called to parse the header portion of the raw data packet. 00107 /// data contains the entire packet, and offset contains the 00108 /// location at which to start parsing. 00109 virtual void ParseHeader(const Data &data, size_t &offset) {} 00110 00111 /// Called to parse sub fields in the raw data packet. 00112 /// The same data is passed as was passed in ParseHeader, 00113 /// only the offset will be updated if it was advanced during 00114 /// the header parsing. 00115 virtual void ParseFields(const Data &data, size_t &offset, 00116 const IConverter *ic) {} 00117 00118 /// Called at the very end of record parsing, and used to 00119 /// store the final packet somewhere, either in memory, disk, etc. 00120 virtual void Store() {} 00121 }; 00122 00123 00124 // 00125 // RecordParser template class 00126 // 00127 /// Template class for easy creation of specific parser objects. This template 00128 /// takes the following template arguments: 00129 /// 00130 /// - RecordT: One of the record parser classes in record.h 00131 /// - StorageT: A custom storage functor class. An object of this type 00132 /// will be called as a function with parsed Record as an 00133 /// argument. This happens on the fly as the data is retrieved 00134 /// from the device over USB, so it should not block forever. 00135 /// 00136 /// Example LoadDatabase() call: 00137 /// 00138 /// <pre> 00139 /// struct StoreContact 00140 /// { 00141 /// std::vector<Contact> &array; 00142 /// StoreContact(std::vector<Contact> &a) : array(a) {} 00143 /// void operator() (const Contact &c) 00144 /// { 00145 /// array.push_back(c); 00146 /// } 00147 /// }; 00148 /// 00149 /// Controller con(probeResult); 00150 /// con.OpenMode(Controller::Desktop); 00151 /// std::vector<Contact> contactList; 00152 /// StoreContact storage(contactList); 00153 /// RecordParser<Contact, StoreContact> parser(storage); 00154 /// con.LoadDatabase(con.GetDBID("Address Book"), parser); 00155 /// </pre> 00156 /// 00157 template <class RecordT, class StorageT> 00158 class RecordParser : public Parser 00159 { 00160 StorageT *m_store; 00161 bool m_owned; 00162 RecordT m_rec; 00163 00164 public: 00165 /// Constructor that references an externally managed storage object. 00166 RecordParser(StorageT &storage) 00167 : m_store(&storage), m_owned(false) {} 00168 00169 /// Constructor that references a locally managed storage object. 00170 /// The pointer passed in will be stored, and freed when this class 00171 /// is destroyed. It is safe to call this constructor with 00172 /// a 'new'ly created storage object. 00173 RecordParser(StorageT *storage) 00174 : m_store(storage), m_owned(true) {} 00175 00176 ~RecordParser() 00177 { 00178 if( this->m_owned ) 00179 delete m_store; 00180 } 00181 00182 virtual void Clear() 00183 { 00184 m_rec = RecordT(); 00185 } 00186 00187 virtual void SetIds(uint8_t RecType, uint32_t UniqueId) 00188 { 00189 m_rec.SetIds(RecType, UniqueId); 00190 } 00191 00192 virtual void ParseHeader(const Data &data, size_t &offset) 00193 { 00194 m_rec.ParseHeader(data, offset); 00195 } 00196 00197 virtual void ParseFields(const Data &data, size_t &offset, 00198 const IConverter *ic) 00199 { 00200 m_rec.ParseFields(data, offset, ic); 00201 } 00202 00203 virtual void Store() 00204 { 00205 (*m_store)(m_rec); 00206 } 00207 }; 00208 00209 } // namespace Barry 00210 00211 #endif 00212