parser.h

Go to the documentation of this file.
00001 ///
00002 /// \file       parser.h
00003 ///             Virtual parser wrapper
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2009, 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> &amp;array;
00142 ///     StoreContact(std::vector<Contact> &amp;a) : array(a) {}
00143 ///     void operator() (const Contact &amp;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 

Generated on Tue Jun 30 16:08:14 2009 for Barry by  doxygen 1.5.8