test: if using -pedantic, also use -ansi, so gettext.h can detect it correctly
[barry.git] / src / builder.h
blob976e405d577f954526da5356db36a6cff149d1b8
1 ///
2 /// \file builder.h
3 /// Virtual protocol packet builder wrapper
4 ///
6 /*
7 Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 See the GNU General Public License in the COPYING file at the
19 root directory of this project for more details.
22 #ifndef __BARRY_BUILDER_H__
23 #define __BARRY_BUILDER_H__
25 #include "dll.h"
26 #include "data.h"
27 #include <stdint.h>
28 #include <string>
30 namespace Barry {
32 // forward declarations
33 class IConverter;
36 // Builder class
38 /// Base class for the builder functor hierarchy.
39 ///
40 /// This defines the API used by the Controller and Packet classes
41 /// for building a raw device record to write to the device.
42 ///
43 class BXEXPORT Builder
45 public:
46 Builder() {}
47 virtual ~Builder() {}
49 /// Called first in the sequence, to allow the application to
50 /// load the needed data from memory, disk, etc. If successful,
51 /// return true. If at the end of the series, return false.
52 virtual bool Retrieve() = 0;
54 /// Called to retrive the unique ID for this record.
55 virtual std::string GetDBName() const = 0;
56 virtual uint8_t GetRecType() const = 0;
57 virtual uint32_t GetUniqueId() const = 0;
59 /// Sometimes a builder can have multiple databases stored
60 /// in it, so when Retrieve() returns false, check if there
61 /// is more data with this function. This function is
62 /// not used by database-oriented functions, but by pipe-
63 /// oriented functions.
64 virtual bool EndOfFile() const = 0;
66 /// Called before BuildFields() in order to build the header
67 /// for this record. Store the raw data in data, at the
68 /// offset given in offset. When finished, update offset to
69 /// point to the next spot to put new data.
70 virtual void BuildHeader(Data &data, size_t &offset) = 0;
72 /// Called to build the record field data. Store the raw data
73 /// in data, using offset to know where to write. Be sure to
74 /// update offset, and be sure to adjust the size of the data
75 /// packet (possibly with Data::ReleaseBuffer()).
76 virtual void BuildFields(Data &data, size_t &offset,
77 const IConverter *ic) = 0;
82 // RecordBuilder template class
84 /// Template class for easy creation of specific protocol packet builder
85 /// objects. This template takes the following template arguments:
86 ///
87 /// - RecordT: One of the record classes in record.h
88 /// - StorageT: A custom storage functor class. An object of this type
89 /// will be called as a function with empty Record as an
90 /// argument. The storage class is expected to fill the
91 /// record object in preparation for building the packet
92 /// out of that data. These calls happen on the fly as the data
93 /// is sent to the device over USB, so it should not block forever.
94 ///
95 /// Example SaveDatabase() call:
96 ///
97 /// <pre>
98 /// FIXME
99 /// </pre>
101 template <class RecordT, class StorageT>
102 class RecordBuilder : public Builder
104 StorageT *m_storage;
105 bool m_owned;
106 bool m_end_of_file;
107 RecordT m_rec;
109 public:
110 /// Constructor that references an externally managed storage object.
111 RecordBuilder(StorageT &storage)
112 : m_storage(&storage)
113 , m_owned(false)
114 , m_end_of_file(false)
118 /// Constructor that references a locally managed storage object.
119 /// The pointer passed in will be stored, and freed when this class
120 /// is destroyed. It is safe to call this constructor with
121 /// a 'new'ly created storage object.
122 RecordBuilder(StorageT *storage)
123 : m_storage(storage)
124 , m_owned(true)
125 , m_end_of_file(false)
129 ~RecordBuilder()
131 if( this->m_owned )
132 delete m_storage;
135 virtual bool Retrieve()
137 bool ret = (*m_storage)(m_rec, *this);
138 if( !ret )
139 m_end_of_file = true;
140 return ret;
143 virtual std::string GetDBName() const
145 return RecordT::GetDBName();
148 virtual uint8_t GetRecType() const
150 return m_rec.GetRecType();
153 virtual uint32_t GetUniqueId() const
155 return m_rec.GetUniqueId();
158 virtual bool EndOfFile() const
160 return m_end_of_file;
163 /// Functor member called by Controller::SaveDatabase() during
164 /// processing.
165 virtual void BuildHeader(Data &data, size_t &offset)
167 m_rec.BuildHeader(data, offset);
170 virtual void BuildFields(Data &data, size_t &offset, const IConverter *ic)
172 m_rec.BuildFields(data, offset, ic);
178 // RecordFetch template class
180 /// Generic record fetch class, to help with using records without
181 /// builder classes.
183 template <class RecordT>
184 class RecordFetch
186 const RecordT &m_rec;
187 mutable bool m_done;
189 public:
190 RecordFetch(const RecordT &rec) : m_rec(rec), m_done(false) {}
191 bool operator()(RecordT &rec, Builder &) const
193 if( m_done )
194 return false;
195 rec = m_rec;
196 m_done = true;
197 return true;
202 } // namespace Barry
204 #endif