openETCS
case study for the European Train Control System developed for the authors dissertation
Storage.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010-2012
3  Johannes Feuser <feuser@uni-bremen.de>
4  This file is part of the openETCS library.
5 
6  The openETCS library is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  any later version.
10 
11  The openETCS library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with the openETCS library. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /*!
21  * \author Johannes Feuser <feuser@uni-bremen.de>
22  * \brief storage class
23  */
24 
25 #include "Storage.h"
26 #include "EVCStateMachine.h"
27 
28 
29 
30 
31 namespace oETCS {
32 
33 namespace DF {
34 
35 
36 CStorage::CStorage(oETCS::DF::CEVCStateMachine * const pStateMachine, const bool& bDebug, const std::string& DebugName) throw()
37 :CFunctionBlock(pStateMachine),
38  m_bBoolInput(false),
39  m_dDoubleInput(0.0),
40  m_DoubleArrayInput(::std::vector< double >(0)),
41  m_iIntInput(0),
42  m_StringInput("0"),
43  m_BitValue(0),
44  m_eLastInputType(::oETCS::DF::BOOL),
45  m_bDebug(bDebug),
46  m_DebugName(DebugName)
47 {
48  // Bouml preserved body begin 00061682
49  // empty constructor
50  // Bouml preserved body end 00061682
51 
52 } // CStorage::CStorage() throw()
53 
54 
55 
56 
58 {
59  // Bouml preserved body begin 00061702
60  // empty destructor
61  // Bouml preserved body end 00061702
62 
63 } // CStorage::~CStorage() throw()
64 
65 
66 
67 
68 void CStorage::Calculate() throw(::oETCS::DF::Error::CException)
69 {
70  // Bouml preserved body begin 00061782
71  unsigned int x(0);
72  const unsigned int NUMBER_BOOL_OUTPUT(m_BoolValue.size());
73  const unsigned int NUMBER_DOUBLE_OUTPUT(m_DoubleValue.size());
74  const unsigned int NUMBER_DOUBLE_ARRAY_OUTPUT(m_DoubleArrayValue.size());
75  const unsigned int NUMBER_INT_OUTPUT(m_IntValue.size());
76  const unsigned int NUMBER_STRING_OUTPUT(m_StringValue.size());
77  const unsigned int NUMBER_BIT_OUTPUT(m_BitValue.size());
78  double dConversion(0);
79  float fConversion(0);
80  int iConversion(0);
81  ::std::stringstream ConversionStream;
82 
83 
84  // check, if any input type value was changed
86  {
87  // convert new boolean input to all other data types
88  m_dDoubleInput.m_Value = m_bBoolInput() ? 1.0 : 0.0;
90  m_DoubleArrayInput.m_Value.push_back(m_bBoolInput() ? 1.0 : 0.0);
91  m_iIntInput.m_Value = m_bBoolInput() ? 1 : 0;
92  m_StringInput.m_Value = m_bBoolInput() ? "true" : "false";
93 
94  // set last input type to boolean
96 
97  } // if (m_bBoolInput.IsModified())
98  else if (m_dDoubleInput.IsModified())
99  {
100  // convert new double value to all other data types
102  m_DoubleArrayInput.m_Value.clear();
105  ConversionStream << m_dDoubleInput();
106  m_StringInput.m_Value = ConversionStream.str();
107 
108  // set last input type to double
110 
111  } // else if (m_dDoubleInput.IsModified())
112  else if (m_DoubleArrayInput.IsModified())
113  {
114  // check, if new array is not empty
115  if (!m_DoubleArrayInput.m_Value.empty())
116  {
117  // convert new double array to all other data types
121  ConversionStream << m_DoubleArrayInput()[0];
122  m_StringInput.m_Value = ConversionStream.str();
123 
124  // set last input type to double array
126 
127  } // if (!m_DoubleArrayInput.m_Value.empty())
128 
129  } // else if (m_DoubleArrayInput.IsModified())
130  else if (m_iIntInput.IsModified())
131  {
132  // convert new integer value to all other data types
135  m_DoubleArrayInput.m_Value.clear();
137  ConversionStream << m_iIntInput();
138  m_StringInput.m_Value = ConversionStream.str();
139 
140  // set last input type to integer
142 
143  } // else if (m_iIntInput.IsModified())
144  else if (m_StringInput.IsModified())
145  {
146  // convert new string value to boolean
147  ConversionStream.str(m_StringInput.m_Value);
148  ConversionStream >> m_bBoolInput.m_Value;
149  ConversionStream.clear();
150 
151  // again store string in stream
152  ConversionStream.str(m_StringInput());
153 
154  // check, to which number type string can be converted
155  if (ConversionStream >> dConversion)
156  {
157  // set all number members from double
158  m_dDoubleInput.m_Value = dConversion;
159  m_DoubleArrayInput.m_Value.resize(1);
160  m_DoubleArrayInput.m_Value[0] = dConversion;
161  m_iIntInput.m_Value = dConversion;
162 
163  } // if (ConversionStream >> dConversion)
164  else if (ConversionStream >> fConversion)
165  {
166  // set all number members from float
167  m_dDoubleInput.m_Value = fConversion;
168  m_DoubleArrayInput.m_Value.resize(1);
169  m_DoubleArrayInput.m_Value[0] = fConversion;
170  m_iIntInput.m_Value = fConversion;
171 
172  } // else if (ConversionStream >> fConversion)
173  else if (ConversionStream >> iConversion)
174  {
175  // set all number members from integer
176  m_dDoubleInput.m_Value = iConversion;
177  m_DoubleArrayInput.m_Value.resize(1);
178  m_DoubleArrayInput.m_Value[0] = iConversion;
179  m_iIntInput.m_Value = iConversion;
180 
181  } // else if (ConversionStream >> fConversion)
182  else
183  {
184  // set default value for all numbers
185  m_dDoubleInput.m_Value = 0.0;
186  m_DoubleArrayInput.m_Value.resize(1);
187  m_DoubleArrayInput.m_Value[0] = 0.0;
188  m_iIntInput.m_Value = 0.0;
189 
190  } // else
191 
192  // set last input type to string
194 
195  } // else if (m_StringInput.IsModified())
196 
197 
198  // set all boolean outputs
199  for (x = 0; x < NUMBER_BOOL_OUTPUT; x++)
200  {
201  *(m_BoolValue[x]) = m_bBoolInput();
202 
203  } // for (x = 0; x < NUMBER_BOOL_OUTPUT; x++)
204 
205  // set all double outputs
206  for (x = 0; x < NUMBER_DOUBLE_OUTPUT; x++)
207  {
208  *(m_DoubleValue[x]) = m_dDoubleInput();
209 
210  } // for (x = 0; x < NUMBER_DOUBLE_OUTPUT; x++)
211 
212  // set all double outputs
213  for (x = 0; x < NUMBER_DOUBLE_ARRAY_OUTPUT; x++)
214  {
216 
217  } // for (x = 0; x < NUMBER_DOUBLE_ARRAY_OUTPUT; x++)
218 
219  // set all integer outputs
220  for (x = 0; x < NUMBER_INT_OUTPUT; x++)
221  {
222  *(m_IntValue[x]) = m_iIntInput();
223 
224  } // for (x = 0; x < NUMBER_INT_OUTPUT; x++)
225 
226  // set all string outputs
227  for (x = 0; x < NUMBER_STRING_OUTPUT; x++)
228  {
229  *(m_StringValue[x]) = m_StringInput();
230 
231  } // for (x = 0; x < NUMBER_STRING_OUTPUT; x++)
232 
233  // set all bit outputs
234  for (x = 0; x < NUMBER_BIT_OUTPUT; x++)
235  {
236  // set current bit output as this instance
237  *(m_BitValue[x]) = *this;
238 
239  } // for (x = 0; x < NUMBER_BIT_OUTPUT; x++)
240 
241  // check, if this instance uses debug output
242  if (m_bDebug)
243  {
244 
245  // print prefix of output
246  ::std::cout << "DEBUG: CStrorage \"" << m_DebugName << "\" -> ";
247 
248  // switch the last used input type
249  switch (m_eLastInputType)
250  {
252  // print boolean value
253  ::std::cout << "boolean " << m_bBoolInput();
254 
255  break;
256 
257 
259  // print double value
260  ::std::cout << "double " << m_dDoubleInput();
261 
262  break;
263 
264 
266  // print integer value
267  ::std::cout << "integer " << m_iIntInput();
268 
269  break;
270 
272  // print string value
273  ::std::cout << "string " << m_StringInput();
274 
275  break;
276 
277 
279  // print double array value
280  ::std::cout << "double array " << m_DoubleArrayInput();
281 
282  break;
283 
284  } // switch (m_eLastInputType)
285 
286  // append newline to output
287  ::std::cout << ::std::endl;
288 
289  } // if (m_bDebug)
290 
291  // Bouml preserved body end 00061782
292 
293 } // void CStorage::Calculate() throw(::oETCS::DF::Error::CException)
294 
295 
296 
297 
298 ::std::vector< bool > CStorage::GetBitVector(const unsigned long& lSize) const throw()
299 {
300  // Bouml preserved body begin 000ABC82
301  unsigned int x(0);
302  unsigned int y(0);
303  unsigned int z(0);
304  const unsigned char* pByte(0);
305  unsigned long lIntSize(0);
306  unsigned long lArraySize(0);
307  unsigned long lStringSize(0);
308  int iIntInput(m_iIntInput());
309  ::std::vector< bool > Bits(0);
310 
311 
312  // check, if size is greater than zero, otherwise ignore
313  if (lSize > 0)
314  {
315  // resize bit vector
316  Bits.resize(lSize);
317 
318  // check, which input type was used the last time
319  switch(m_eLastInputType)
320  {
322  // set one and only bit in vector
323  Bits[0] = m_bBoolInput();
324 
325  break;
326 
327 
329  // convert double into integer
330  iIntInput = m_dDoubleInput();
331 
333  // calculate real integer size
334  lIntSize = lSize < sizeof (int) * 8 ? lSize : sizeof (int) * 8;
335 
336  // initialise byte pointer at last byte of integer (little endian)
337  pByte = reinterpret_cast< const unsigned char* >(iIntInput) + lIntSize - 1;
338 
339  // copy bytes of integer into vector
340  for (x = 0; x < lIntSize; x++)
341  {
342  // copy all bits of current byte
343  for (y = 0; y < 8; y++)
344  {
345  // copy current bit
346  Bits[(x * 8) + y] = ((1 << (7 - y)) & (*pByte));
347 
348  } // for (y = 0; y < 8; y++)
349 
350  // decrease byte pointer
351  pByte--;
352 
353  } // for (x = 0; x < lIntSize; x++)
354 
355  break;
356 
357 
359  // calculate real array size
360  lArraySize = lSize < sizeof (int) * 8 * m_DoubleArrayInput().size() ? lSize : sizeof (int) * 8 * m_DoubleArrayInput().size();
361 
362  // re-calculate real integer size
363  lIntSize = lArraySize / m_DoubleArrayInput().size();
364 
365  // process all elements of double array
366  for (z = 0; z < m_DoubleArrayInput().size(); z++)
367  {
368  // convert current double element to integer
369  iIntInput = m_DoubleArrayInput()[z];
370 
371  // initialise byte pointer at last byte of integer (little endian)
372  pByte = reinterpret_cast< const unsigned char* >(iIntInput) + lIntSize - 1;
373 
374  // copy bytes of integer into vector
375  for (x = 0; x < lIntSize; x++)
376  {
377  // copy all bits of current byte
378  for (y = 0; y < 8; y++)
379  {
380  // copy current bit
381  Bits[(x * 8) + y + (z * sizeof(int) * 8)] = ((1 << (7 - y)) & (*pByte));
382 
383  } // for (y = 0; y < 8; y++)
384 
385  // decrease byte pointer
386  pByte--;
387 
388  } // for (x = 0; x < lIntSize; x++)
389 
390  } // for (z = 0; z < m_DoubleArrayInput().size(); z++)
391 
392  break;
393 
394 
396  // calculate real string size
397  lStringSize = lSize < m_StringInput().size() * sizeof (char) * 8 ? lSize / 8 : m_StringInput().size();
398 
399  // process all chars/bytes of string
400  for (x = 0; x < lStringSize; x++)
401  {
402  // copy current byte/char bit-wise
403  for (y = 0; y < 8; y++)
404  {
405  // copy current bit
406  Bits[(x * 8) + y] = ((1 << (7 - y)) & m_StringInput()[x]);
407 
408  } // for (y = 0; y < 8; y++)
409 
410  } // for (x = 0; x < lStringSize; x++)
411 
412  break;
413 
414  } // switch(m_eLastInputType)
415 
416  } // if (lSize > 0)
417 
418 
419  // return bit vector
420  return (Bits);
421  // Bouml preserved body end 000ABC82
422 
423 } // bool CStorage::GetBitVector() const throw()
424 
425 
426 
427 
429 {
430  // Bouml preserved body begin 000CBE82
431  // return member value
432  return (m_eLastInputType);
433  // Bouml preserved body end 000CBE82
434 
435 } // oETCS::DF::DATA_T CStorage::GetLastInputType() const throw()
436 
437 
438 
439 
440 
441 
442 } // namespace oETCS::DF
443 
444 } // namespace oETCS

Copyright (C) 2010-2012 Johannes Feuser (feuser@uni-bremen.de)
The openETCS library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
The openETCS library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the openETCS library. If not, see "http://www.gnu.org/licenses/.