builder.h

Go to the documentation of this file.
00001 ///
00002 /// \file       builder.h
00003 ///             Virtual protocol packet builder 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_BUILDER_H__
00023 #define __BARRY_BUILDER_H__
00024 
00025 #include "dll.h"
00026 
00027 namespace Barry {
00028 
00029 // forward declarations
00030 class IConverter;
00031 
00032 //
00033 // Builder class
00034 //
00035 /// Base class for the builder functor hierarchy.
00036 ///
00037 /// This defines the API used by the Controller and Packet classes
00038 /// for building a raw device record to write to the device.
00039 ///
00040 class BXEXPORT Builder
00041 {
00042 public:
00043         Builder() {}
00044         virtual ~Builder() {}
00045 
00046         /// Called first in the sequence, to allow the application to
00047         /// load the needed data from memory, disk, etc.  If successful,
00048         /// return true.  If at the end of the series, return false.
00049         virtual bool Retrieve(unsigned int databaseId) = 0;
00050 
00051         /// Called to retrive the unique ID for this record.
00052         virtual uint8_t GetRecType() const = 0;
00053         virtual uint32_t GetUniqueId() const = 0;
00054 
00055         /// Called before BuildFields() in order to build the header
00056         /// for this record.  Store the raw data in data, at the
00057         /// offset given in offset.  When finished, update offset to
00058         /// point to the next spot to put new data.
00059         virtual void BuildHeader(Data &data, size_t &offset) = 0;
00060 
00061         /// Called to build the record field data.  Store the raw data
00062         /// in data, using offset to know where to write.  Be sure to
00063         /// update offset, and be sure to adjust the size of the data
00064         /// packet (possibly with Data::ReleaseBuffer()).
00065         virtual void BuildFields(Data &data, size_t &offset,
00066                 const IConverter *ic) = 0;
00067 };
00068 
00069 
00070 //
00071 // RecordBuilder template class
00072 //
00073 /// Template class for easy creation of specific protocol packet builder
00074 /// objects.  This template takes the following template arguments:
00075 ///
00076 ///     - RecordT: One of the record classes in record.h
00077 ///     - StorageT: A custom storage functor class.  An object of this type
00078 ///             will be called as a function with empty Record as an
00079 ///             argument.  The storage class is expected to fill the
00080 ///             record object in preparation for building the packet
00081 ///             out of that data.  These calls happen on the fly as the data
00082 ///             is sent to the device over USB, so it should not block forever.
00083 ///
00084 /// Example SaveDatabase() call:
00085 ///
00086 /// <pre>
00087 /// FIXME
00088 /// </pre>
00089 ///
00090 template <class RecordT, class StorageT>
00091 class RecordBuilder : public Builder
00092 {
00093         StorageT *m_storage;
00094         bool m_owned;
00095         RecordT m_rec;
00096 
00097 public:
00098         /// Constructor that references an externally managed storage object.
00099         RecordBuilder(StorageT &storage)
00100                 : m_storage(&storage), m_owned(false) {}
00101 
00102         /// Constructor that references a locally managed storage object.
00103         /// The pointer passed in will be stored, and freed when this class
00104         /// is destroyed.  It is safe to call this constructor with
00105         /// a 'new'ly created storage object.
00106         RecordBuilder(StorageT *storage)
00107                 : m_storage(storage), m_owned(true) {}
00108 
00109         ~RecordBuilder()
00110         {
00111                 if( this->m_owned )
00112                         delete m_storage;
00113         }
00114 
00115         virtual bool Retrieve(unsigned int databaseId)
00116         {
00117                 return (*m_storage)(m_rec, databaseId);
00118         }
00119 
00120         virtual uint8_t GetRecType() const
00121         {
00122                 return m_rec.GetRecType();
00123         }
00124 
00125         virtual uint32_t GetUniqueId() const
00126         {
00127                 return m_rec.GetUniqueId();
00128         }
00129 
00130         /// Functor member called by Controller::SaveDatabase() during
00131         /// processing.
00132         virtual void BuildHeader(Data &data, size_t &offset)
00133         {
00134                 m_rec.BuildHeader(data, offset);
00135         }
00136 
00137         virtual void BuildFields(Data &data, size_t &offset, const IConverter *ic)
00138         {
00139                 m_rec.BuildFields(data, offset, ic);
00140         }
00141 };
00142 
00143 
00144 //
00145 // RecordFetch template class
00146 //
00147 /// Generic record fetch class, to help with using records without
00148 /// builder classes.
00149 ///
00150 template <class RecordT>
00151 class RecordFetch
00152 {
00153         const RecordT &m_rec;
00154         mutable bool m_done;
00155 
00156 public:
00157         RecordFetch(const RecordT &rec) : m_rec(rec), m_done(false) {}
00158         bool operator()(RecordT &rec, unsigned int dbId) const
00159         {
00160                 if( m_done )
00161                         return false;
00162                 rec = m_rec;
00163                 m_done = true;
00164                 return true;
00165         }
00166 };
00167 
00168 
00169 } // namespace Barry
00170 
00171 #endif
00172 

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