1 #ifndef STATEVARIABLE_H
2 #define	STATEVARIABLE_H
3 
4 /*
5  *  Copyright (C) 2007-2010  Anders Gavare.  All rights reserved.
6  *
7  *  Redistribution and use in source and binary forms, with or without
8  *  modification, are permitted provided that the following conditions are met:
9  *
10  *  1. Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  *  2. Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  *  3. The name of the author may not be used to endorse or promote products
16  *     derived from this software without specific prior written permission.
17  *
18  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  *  SUCH DAMAGE.
29  *
30  *
31  *  Note/TODO: This class could perhaps be rewritten in a nicer way by
32  *             using C++ templates.
33  */
34 
35 #include "misc.h"
36 
37 #include "SerializationContext.h"
38 #include "UnitTest.h"
39 
40 
41 class StateVariable;
42 typedef map<string,StateVariable> StateVariableMap;
43 
44 
45 class CustomStateVariableHandler
46 {
47 public:
CustomStateVariableHandler()48 	CustomStateVariableHandler()
49 	{
50 	}
51 
~CustomStateVariableHandler()52 	virtual ~CustomStateVariableHandler()
53 	{
54 	}
55 
56 	virtual void Serialize(ostream& ss) const = 0;
57 	virtual bool Deserialize(const string& value) = 0;
58 	virtual void CopyValueFrom(CustomStateVariableHandler* other) = 0;
59 };
60 
61 
62 /**
63  * \brief StateVariables make up the persistent state of Component objects.
64  *
65  * A %StateVariable has a name, and a value.
66  */
67 class StateVariable
68 	: public UnitTestable
69 {
70 public:
71 	/**
72 	 * \brief An enumeration of the possible types of a %StateVariable.
73 	 */
74 	enum Type {
75 		String = 0,
76 		Bool,
77 		Double,
78 		UInt8,
79 		UInt16,
80 		UInt32,
81 		UInt64,
82 		SInt8,
83 		SInt16,
84 		SInt32,
85 		SInt64,
86 		Custom
87 	};
88 
89 private:
90 	/* Disable construction without name. */
91 	StateVariable();
92 
93 public:
94 	/**
95 	 * \brief Constructor for a String StateVariable.
96 	 *
97 	 * @param name The variable's name.
98 	 * @param ptrToString A pointer to the string which this
99 	 *	variable refers to.
100 	 */
101 	StateVariable(const string& name, string* ptrToString);
102 
103 	/**
104 	 * \brief Constructor for a Bool StateVariable.
105 	 *
106 	 * @param name The variable's name.
107 	 * @param ptrToVar A pointer to the variable.
108 	 */
109 	StateVariable(const string& name, bool* ptrToVar);
110 
111 	/**
112 	 * \brief Constructor for a Double StateVariable.
113 	 *
114 	 * @param name The variable's name.
115 	 * @param ptrToVar A pointer to the variable.
116 	 */
117 	StateVariable(const string& name, double* ptrToVar);
118 
119 	/**
120 	 * \brief Constructor for a UInt8 StateVariable.
121 	 *
122 	 * @param name The variable's name.
123 	 * @param ptrToVar A pointer to the variable.
124 	 */
125 	StateVariable(const string& name, uint8_t* ptrToVar);
126 
127 	/**
128 	 * \brief Constructor for a UInt16 StateVariable.
129 	 *
130 	 * @param name The variable's name.
131 	 * @param ptrToVar A pointer to the variable.
132 	 */
133 	StateVariable(const string& name, uint16_t* ptrToVar);
134 
135 	/**
136 	 * \brief Constructor for a UInt32 StateVariable.
137 	 *
138 	 * @param name The variable's name.
139 	 * @param ptrToVar A pointer to the variable.
140 	 */
141 	StateVariable(const string& name, uint32_t* ptrToVar);
142 
143 	/**
144 	 * \brief Constructor for a UInt64 StateVariable.
145 	 *
146 	 * @param name The variable's name.
147 	 * @param ptrToVar A pointer to the variable.
148 	 */
149 	StateVariable(const string& name, uint64_t* ptrToVar);
150 
151 	/**
152 	 * \brief Constructor for a SInt8 StateVariable.
153 	 *
154 	 * @param name The variable's name.
155 	 * @param ptrToVar A pointer to the variable.
156 	 */
157 	StateVariable(const string& name, int8_t* ptrToVar);
158 
159 	/**
160 	 * \brief Constructor for a SInt16 StateVariable.
161 	 *
162 	 * @param name The variable's name.
163 	 * @param ptrToVar A pointer to the variable.
164 	 */
165 	StateVariable(const string& name, int16_t* ptrToVar);
166 
167 	/**
168 	 * \brief Constructor for a SInt32 StateVariable.
169 	 *
170 	 * @param name The variable's name.
171 	 * @param ptrToVar A pointer to the variable.
172 	 */
173 	StateVariable(const string& name, int32_t* ptrToVar);
174 
175 	/**
176 	 * \brief Constructor for a SInt64 StateVariable.
177 	 *
178 	 * @param name The variable's name.
179 	 * @param ptrToVar A pointer to the variable.
180 	 */
181 	StateVariable(const string& name, int64_t* ptrToVar);
182 
183 	/**
184 	 * \brief Constructor for a custom StateVariable.
185 	 *
186 	 * @param name The variable's name.
187 	 * @param ptrToHandler A pointer to the custom handler.
188 	 */
189 	StateVariable(const string& name, CustomStateVariableHandler* ptrToHandler);
190 
191 	/**
192 	 * \brief Gets the name of the variable.
193 	 *
194 	 * @return The name of the variable.
195 	 */
196 	const string& GetName() const;
197 
198 	/**
199 	 * \brief Gets the type of the variable.
200 	 *
201 	 * @return The type of the variable.
202 	 */
203 	enum Type GetType() const;
204 
205 	/**
206 	 * \brief Serializes the variable value into a string.
207 	 *
208 	 * Strings are serialized as quoted strings; most other types without
209 	 * quoting.
210 	 *
211 	 * @param ss A stream where the variable value will be appended.
212 	 */
213 	void SerializeValue(ostream& ss) const;
214 
215 	/**
216 	 * \brief Serializes the variable into a string.
217 	 *
218 	 * @param ss A stream where the variable (type, name, and value)
219 	 *	will be appended.
220 	 * @param context Serialization context (tab indentation, etc).
221 	 */
222 	void Serialize(ostream& ss, SerializationContext& context) const;
223 
224 	/**
225 	 * \brief Copy the value from another variable into this variable.
226 	 *
227 	 * @param otherVariable The variable to copy from.
228 	 * @return True if the value was copied, false if copying was not
229 	 *	possible (i.e. the types differed).
230 	 */
231 	bool CopyValueFrom(const StateVariable& otherVariable);
232 
233 	/**
234 	 * \brief Returns the variable as a readable string.
235 	 *
236 	 * @return A string, representing the variable's value.
237 	 */
238 	string ToString() const;
239 
240 	/**
241 	 * \brief Returns the variable as an unsignedinteger value.
242 	 *
243 	 * @return A uint64_t, representing the variable's value.
244 	 */
245 	uint64_t ToInteger() const;
246 
247 	/**
248 	 * \brief Returns the variable as a double value.
249 	 *
250 	 * @return A double, representing the variable's value.
251 	 */
252 	double ToDouble() const;
253 
254 	/**
255 	 * \brief Set the variable's value, using a string expression.
256 	 *
257 	 * Note that the expression may be a single value (e.g. <tt>42</tt>),
258 	 * or something more complex (e.g. <tt>123 + cpu0.pc * 4</tt>).
259 	 *
260 	 * When setting string values, the expression should be a C-style
261 	 * escaped string, e.g.: <tt>"This is a string with a \" inside
262 	 * it."</tt>
263 	 *
264 	 * @param expression The new value.
265 	 * @return True if the value was set, false if e.g. there was a
266 	 *	parse error.
267 	 */
268 	bool SetValue(const string& expression);
269 
270 	/**
271 	 * \brief Set the variable's value to an integer.
272 	 *
273 	 * @param value The new value.
274 	 * @return True if the value was set, false if e.g. there was a
275 	 *	type error.
276 	 */
277 	bool SetValue(uint64_t value);
278 
279 
280 	/********************************************************************/
281 
282 	static void RunUnitTests(int& nSucceeded, int& nFailures);
283 
284 private:
285 	/**
286 	 * \brief Evaluates an expression, and returns it as a single value.
287 	 *
288 	 * @param expression The expression to evaluate.
289 	 * @param success Set to true if the expression could be evaluated,
290 	 *	false otherwise.
291 	 * @return A string representation of the evaluated expression.
292 	 *	(Only valid if <tt>success</tt> was set to true.)
293 	 */
294 	string EvaluateExpression(const string& expression,
295 		bool &success) const;
296 
297 	/**
298 	 * \brief Returns the type of the variable, as a string.
299 	 *
300 	 * @return A string representation of the variable's type.
301 	 */
302 	string GetTypeString() const;
303 
304 	/**
305 	 * \brief Returns a string representation of the variable's value.
306 	 *
307 	 * @return A string representation of the variable's value.
308 	 */
309 	string ValueToString() const;
310 
311 private:
312 	string			m_name;
313 	enum Type		m_type;
314 
315 	union {
316 		string*		pstr;
317 		bool*		pbool;
318 		double*		pdouble;
319 		uint8_t*	puint8;
320 		uint16_t*	puint16;
321 		uint32_t*	puint32;
322 		uint64_t*	puint64;
323 		int8_t*		psint8;
324 		int16_t*	psint16;
325 		int32_t*	psint32;
326 		int64_t*	psint64;
327 		CustomStateVariableHandler *phandler;
328 	} m_value;
329 };
330 
331 
332 #endif	// STATEVARIABLE_H
333