00001 /// 00002 /// \file parser.h 00003 /// Virtual parser wrapper 00004 /// 00005 00006 /* 00007 Copyright (C) 2005-2008, 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 { class Data; } 00032 00033 namespace Barry { 00034 00035 // also acts as a null parser 00036 // 00037 // Parser class 00038 // 00039 /// Base class for the parser hierarchy. If in debug mode, this 00040 /// class can be used as a null parser. Call Init() and the protocol 00041 /// will be dumped to stdout and no parsing will be done. 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 class BXEXPORT Parser 00049 { 00050 public: 00051 Parser() {} 00052 virtual ~Parser() {} 00053 00054 /// Reset and prepare for a new raw data packet 00055 virtual void Clear() {} 00056 00057 /// Stores the IDs 00058 virtual void SetIds(uint8_t RecType, uint32_t UniqueId) {} 00059 00060 /// Called to parse the header portion of the raw data packet. 00061 /// data contains the entire packet, and offset contains the 00062 /// location at which to start parsing. 00063 virtual void ParseHeader(const Data &data, size_t &offset) {} 00064 00065 /// Called to parse sub fields in the raw data packet. 00066 /// The same data is passed as was passed in ParseHeader, 00067 /// only the offset will be updated if it was advanced during 00068 /// the header parsing. 00069 virtual void ParseFields(const Data &data, size_t &offset) {} 00070 00071 /// Called at the very end of record parsing, and used to 00072 /// store the final packet somewhere, either in memory, disk, etc. 00073 virtual void Store() {} 00074 }; 00075 00076 00077 // 00078 // RecordParser template class 00079 // 00080 /// Template class for easy creation of specific parser objects. This template 00081 /// takes the following template arguments: 00082 /// 00083 /// - RecordT: One of the record parser classes in record.h 00084 /// - StorageT: A custom storage functor class. An object of this type 00085 /// will be called as a function with parsed Record as an 00086 /// argument. This happens on the fly as the data is retrieved 00087 /// from the device over USB, so it should not block forever. 00088 /// 00089 /// Example LoadDatabase() call: 00090 /// 00091 /// <pre> 00092 /// struct StoreContact 00093 /// { 00094 /// std::vector<Contact> &array; 00095 /// StoreContact(std::vector<Contact> &a) : array(a) {} 00096 /// void operator() (const Contact &c) 00097 /// { 00098 /// array.push_back(c); 00099 /// } 00100 /// }; 00101 /// 00102 /// Controller con(probeResult); 00103 /// con.OpenMode(Controller::Desktop); 00104 /// std::vector<Contact> contactList; 00105 /// StoreContact storage(contactList); 00106 /// RecordParser<Contact, StoreContact> parser(storage); 00107 /// con.LoadDatabase(con.GetDBID("Address Book"), parser); 00108 /// </pre> 00109 /// 00110 template <class RecordT, class StorageT> 00111 class RecordParser : public Parser 00112 { 00113 StorageT *m_store; 00114 bool m_owned; 00115 RecordT m_rec; 00116 00117 public: 00118 /// Constructor that references an externally managed storage object. 00119 RecordParser(StorageT &storage) 00120 : m_store(&storage), m_owned(false) {} 00121 00122 /// Constructor that references a locally managed storage object. 00123 /// The pointer passed in will be stored, and freed when this class 00124 /// is destroyed. It is safe to call this constructor with 00125 /// a 'new'ly created storage object. 00126 RecordParser(StorageT *storage) 00127 : m_store(storage), m_owned(true) {} 00128 00129 ~RecordParser() 00130 { 00131 if( this->m_owned ) 00132 delete m_store; 00133 } 00134 00135 virtual void Clear() 00136 { 00137 m_rec = RecordT(); 00138 } 00139 00140 virtual void SetIds(uint8_t RecType, uint32_t UniqueId) 00141 { 00142 m_rec.SetIds(RecType, UniqueId); 00143 } 00144 00145 virtual void ParseHeader(const Data &data, size_t &offset) 00146 { 00147 m_rec.ParseHeader(data, offset); 00148 } 00149 00150 virtual void ParseFields(const Data &data, size_t &offset) 00151 { 00152 m_rec.ParseFields(data, offset); 00153 } 00154 00155 virtual void Store() 00156 { 00157 (*m_store)(m_rec); 00158 } 00159 }; 00160 00161 } // namespace Barry 00162 00163 #endif 00164