1 /**
2  *  Field proxy. Returned by the table. Can be casted to the
3  *  relevant native type (std::string or numeric)
4  *
5  *  @copyright 2014 Copernica BV
6  */
7 
8 /**
9  *  Include guard
10  */
11 #pragma once
12 
13 /**
14  *  Dependencies
15  */
16 #include <cstdint>
17 #include <string>
18 #include "stringfield.h"
19 #include "booleanset.h"
20 #include "decimalfield.h"
21 #include "numericfield.h"
22 
23 /**
24  *  Set up namespace
25  */
26 namespace AMQP {
27 
28 /**
29  *  Forward declarations
30  */
31 class Table;
32 class Array;
33 class Field;
34 
35 /**
36  *  Class implementation
37  */
38 template <typename T, typename I>
39 class FieldProxy
40 {
41 private:
42     /**
43      *  The table or array possibly holding the requested field
44      */
45     T *_source;
46 
47     /**
48      *  The key in the table
49      */
50     I _index;
51 
52 public:
53     /**
54      *  Construct the field proxy
55      *
56      *  @param  table   the table possibly holding the field
57      *  @oaram  index   key in table map
58      */
FieldProxy(T * source,I index)59     FieldProxy(T *source, I index) :
60         _source(source),
61         _index(index)
62     {}
63 
64     /**
65      *  Assign a boolean value
66      *
67      *  @param  value
68      */
69     FieldProxy& operator=(bool value)
70     {
71         // assign value and allow chaining
72         _source->set(_index, BooleanSet(value));
73         return *this;
74     }
75 
76     /**
77      *  Assign a numeric value
78      *
79      *  @param  value
80      *  @return FieldProxy
81      */
82     FieldProxy& operator=(uint8_t value)
83     {
84         // assign value and allow chaining
85         _source->set(_index, UOctet(value));
86         return *this;
87     }
88 
89     /**
90      *  Assign a numeric value
91      *
92      *  @param  value
93      *  @return FieldProxy
94      */
95     FieldProxy& operator=(int8_t value)
96     {
97         // assign value and allow chaining
98         _source->set(_index, Octet(value));
99         return *this;
100     }
101 
102     /**
103      *  Assign a numeric value
104      *
105      *  @param  value
106      *  @return FieldProxy
107      */
108     FieldProxy& operator=(uint16_t value)
109     {
110         // assign value and allow chaining
111         _source->set(_index, UShort(value));
112         return *this;
113     }
114 
115     /**
116      *  Assign a numeric value
117      *
118      *  @param  value
119      *  @return FieldProxy
120      */
121     FieldProxy& operator=(int16_t value)
122     {
123         // assign value and allow chaining
124         _source->set(_index, Short(value));
125         return *this;
126     }
127 
128     /**
129      *  Assign a numeric value
130      *
131      *  @param  value
132      *  @return FieldProxy
133      */
134     FieldProxy& operator=(uint32_t value)
135     {
136         // assign value and allow chaining
137         _source->set(_index, ULong(value));
138         return *this;
139     }
140 
141     /**
142      *  Assign a numeric value
143      *
144      *  @param  value
145      *  @return FieldProxy
146      */
147     FieldProxy& operator=(int32_t value)
148     {
149         // assign value and allow chaining
150         _source->set(_index, Long(value));
151         return *this;
152     }
153 
154     /**
155      *  Assign a numeric value
156      *
157      *  @param  value
158      *  @return FieldProxy
159      */
160     FieldProxy& operator=(uint64_t value)
161     {
162         // assign value and allow chaining
163         _source->set(_index, ULongLong(value));
164         return *this;
165     }
166 
167     /**
168      *  Assign a numeric value
169      *
170      *  @param  value
171      *  @return FieldProxy
172      */
173     FieldProxy& operator=(int64_t value)
174     {
175         // assign value and allow chaining
176         _source->set(_index, LongLong(value));
177         return *this;
178     }
179 
180     /**
181      *  Assign a decimal value
182      *
183      *  @param  value
184      *  @return FieldProxy
185      */
186     FieldProxy& operator=(const DecimalField &value)
187     {
188         // assign value and allow chaining
189         _source->set(_index, DecimalField(value));
190         return *this;
191     }
192 
193     /**
194      *  Assign a string value
195      *
196      *  @param  value
197      *  @return FieldProxy
198      */
199     FieldProxy &operator=(const std::string &value)
200     {
201         // in theory we should make a distinction between short and long string,
202         // but in practive only long strings are accepted
203         _source->set(_index, LongString(value));
204 
205         // allow chaining
206         return *this;
207     }
208 
209     /**
210      *  Assign a string value
211      *
212      *  @param  value
213      *  @return FieldProxy
214      */
215     FieldProxy &operator=(const char *value)
216     {
217         // cast to a string
218         return operator=(std::string(value));
219     }
220 
221     /**
222      *  Assign an array value
223      *  @param  value
224      *  @return FieldProxy
225      */
226     FieldProxy &operator=(const Array &value)
227     {
228         // assign value and allow chaining
229         _source->set(_index, value);
230         return *this;
231     }
232 
233     /**
234      *  Assign a table value
235      *  @param  value
236      *  @return FieldProxy
237      */
238     FieldProxy &operator=(const Table &value)
239     {
240         // assign value and allow chaining
241         _source->set(_index, value);
242         return *this;
243     }
244 
245     /**
246      *  Get the underlying field
247      *  @return Field
248      */
get()249     const Field &get() const
250     {
251         return _source->get(_index);
252     }
253 
254     /**
255      *  Get a boolean
256      *  @return bool
257      */
258     template <typename TARGET>
TARGET()259     operator TARGET () const
260     {
261         // retrieve the value
262         return _source->get(_index);
263     }
264 };
265 
266 // define types for array- and table-based field proxy
267 using AssociativeFieldProxy = FieldProxy<Table, std::string>;
268 using ArrayFieldProxy       = FieldProxy<Array, uint8_t>;
269 
270 /**
271  *  end namespace
272  */
273 }
274 
275