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

Generated on Wed Sep 24 21:27:31 2008 for Barry by  doxygen 1.5.1