openETCS
case study for the European Train Control System developed for the authors dissertation
Language.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 language classes
23  */
24 
25 #include "Language.h"
26 #include "EVCStateMachine.h"
27 
28 
29 
30 
31 namespace oETCS {
32 
33 namespace DF {
34 
35 
36 CLanguage::CLanguage(oETCS::DF::CEVCStateMachine * const pStateMachine) throw()
37 {
38  // Bouml preserved body begin 000A6B82
39  // check, if pointer to state machine is valid
40  if (pStateMachine != 0)
41  {
42  // register this instance with state machine
43  pStateMachine->AddLanguage(this);
44 
45  } // if (pStateMachine != 0)
46  // Bouml preserved body end 000A6B82
47 
48 } // CLanguage::CLanguage() throw()
49 
50 
51 
52 
54 {
55  // Bouml preserved body begin 000A6C02
56  // empty destructor
57  // Bouml preserved body end 000A6C02
58 
59 } // CLanguage::~CLanguage() throw()
60 
61 
62 
63 
64 CVariable::CVariable(oETCS::DF::CEVCStateMachine * const pStateMachine, const unsigned int & iResolution, const oETCS::DF::CVariable::UNIT_T & eUnit, const unsigned long & lSize, const bool& bIsConditional, const long& lConditonalValue, const ::std::map< VARIABLE_VALUE_VECTOR_T, oETCS::DF::CVariable * >& ValueMap) throw()
65 :CLanguage(pStateMachine),
66  m_iResolution(iResolution),
67  m_eUnit(eUnit),
68  m_lSize(lSize),
69  m_Value(lSize),
70  m_iIterated(1),
71  m_dFactor(1.0),
72  m_bConditionalIterator(bIsConditional),
73  m_lConditionalValue(lConditonalValue),
74  m_BitValues(0),
75  m_ScaledVariables(0),
76  m_IteratedVariables(0),
77  m_ValueMap(ValueMap)
78 {
79  // Bouml preserved body begin 0006AB02
80  // empty constructor
81  // Bouml preserved body end 0006AB02
82 
83 } // CVariable::CVariable() throw()
84 
85 
86 
87 
89 {
90  // Bouml preserved body begin 0006AB82
91  // empty destructor
92  // Bouml preserved body end 0006AB82
93 
94 } // CVariable::~CVariable() throw()
95 
96 
97 
98 
99 void CVariable::Calculate() throw(::oETCS::DF::Error::CException)
100 {
101  // Bouml preserved body begin 0006C602
102  char cRawCharacter(0);
103  long lRawInteger(0);
104  unsigned int x(0);
105  unsigned int y(0);
106  unsigned int z(0);
107  double dDoubleOutput(0.0);
108  const unsigned int NUMBER_BITS(m_Value.size());
109  const unsigned int NUMBER_ITERATED(m_IteratedVariables.size());
110  const unsigned int NUMBER_SCALED(m_ScaledVariables.size());
111  decltype (m_BitValues.begin()) Storage;
112  ::std::vector< ::oETCS::DF::VARIABLE_VALUE_VECTOR_T > ArrayValue(m_iIterated);
113  ::std::vector< long > RawIntegers(m_iIterated, 0);
114  ::std::vector< double > DoubleOutputs(m_iIterated, 0.0);
115  ::std::vector< ::std::string > StringOutputs(m_iIterated, "" );
116  ::std::string RawString("");
117  ::oETCS::DF::CStorage LocalStorage(0);
118 
119 
120 
121  // first check, if iteration value is not 0 (do nothing if so)
122  if (m_iIterated != 0)
123  {
124  // check, if iteration value is one (no array value)
125  if (m_iIterated == 1)
126  {
127  // check, if current value exists in map
128  if (m_ValueMap.find(m_Value) != m_ValueMap.end())
129  {
130  // apply value from map to current value
131  m_Value = m_ValueMap.find(m_Value)->second->m_Value;
132 
133  // check, if new value vector has correct size
134  while (m_Value.size() < m_lSize)
135  {
136  // insert a zero to the front of the value vector
137  m_Value.insert(m_Value.begin(), false);
138 
139  } // while (m_Value.size() < m_lSize)
140 
141  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
142  // DEBUG
143  ::std::cout << "CVariable::Calculate<<() bits after value map: ";
144  for (decltype (m_Value.begin()) lb = m_Value.begin(); lb != m_Value.end(); lb++)
145  {
146  ::std::cout << *lb << "," << ::std::flush;
147 
148  } // for (decltype (m_Value.begin()) lb = m_Value.begin(); lb != m_Value.end(); lb++)
149  ::std::cout << ::std::endl;
150  #endif // __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
151 
152  } // if (m_ValueMap.find(m_Value) != m_ValueMap.end())
153 
154  // check, if unit is not string
156  {
157  // check, if size of value stack is bigger than system long long integer
158  if (NUMBER_BITS > (sizeof (long long) * 8))
159  {
160  // print warning to stderr
161  ::std::cerr << "In file " << __FILE__ << " at line " << __LINE__ << ": size of value bit stack is bigger as system long long integer (" << (sizeof (long long) * 8) << "), rest will be ignored " << ::std::endl;
162 
163  } // if (NUMBER_BITS > ( izeof (long long) * 8))
164 
165  // convert bit stack to integer bit-wise
166  for (x = 0; x < NUMBER_BITS && x < (sizeof (long long) * 8); x++)
167  {
168  // add current bit to raw integer
169  lRawInteger += (long long)(m_Value[x] << (NUMBER_BITS - 1 - x));
170 
171  } // for (x = 0; x < NUMBER_BITS && x < (sizeof (long long) * 8); x++)
172 
173  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
174  // DEBUG
175  ::std::cout << "CVariable::Calculate() raw integer value: " << lRawInteger << " number bits: " << NUMBER_BITS << ::std::endl;
176  #endif
177 
178  } // if (m_eUnit != ::oETCS::DF::CVariable::STRING)
179 
180  // check unit of this variable
181  switch (m_eUnit)
182  {
184  case ::oETCS::DF::CVariable::SECONDS:
185  case ::oETCS::DF::CVariable::METERS:
186 
187  // convert integer to double
188  dDoubleOutput = lRawInteger;
189 
190 
191  // check, if a storage is connected
192  if (not m_BitValues.empty())
193  {
194  // copy double output to storages
195  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
196  {
197  // set value in local storage
198  LocalStorage.m_dDoubleInput = dDoubleOutput * m_dFactor * double(m_iResolution);
199  LocalStorage.Calculate();
200 
201  // copy value to current storage
202  (**Storage) = LocalStorage;
203 
204  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
205 
206  } // if (not m_BitValues.empty())
207 
208  // finally break
209  break;
210 
211 
212  case ::oETCS::DF::CVariable::INTEGER:
213 
214  // check, if a storage is connected
215  if (not m_BitValues.empty())
216  {
217  // copy integer output to storage
218  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
219  {
220  // set value in local storage
221  LocalStorage.m_iIntInput = lRawInteger * int(m_dFactor) * m_iResolution;
222  LocalStorage.Calculate();
223 
224  // copy value to current storage
225  (**Storage) = LocalStorage;
226 
227  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
228 
229  } // if (not m_BitValues.empty())
230 
231  // finally break
232  break;
233 
234 
235  case ::oETCS::DF::CVariable::KILO_METERS_PER_HOUR:
236 
237  // convert integer to double
238  dDoubleOutput = lRawInteger;
239 
240 
241  // check, if a storage is connected
242  if (not m_BitValues.empty())
243  {
244  // copy double output normalised to meters to storage
245  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
246  {
247  // set value in local storage
248  LocalStorage.m_dDoubleInput = dDoubleOutput / 3.6 * m_dFactor * double(m_iResolution);
249  LocalStorage.Calculate();
250 
251  // copy value to current storage
252  (**Storage) = LocalStorage;
253 
254  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
255 
256  } // if (not m_BitValues.empty())
257 
258  // finally break
259  break;
260 
261 
262  case ::oETCS::DF::CVariable::CENTI_METERS:
263 
264  // convert integer to double
265  dDoubleOutput = lRawInteger;
266 
267 
268  // check, if a storage is connected
269  if (not m_BitValues.empty())
270  {
271  // copy double output normalised to meters to storage
272  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
273  {
274  // set value in local storage
275  LocalStorage.m_dDoubleInput = dDoubleOutput / 100 * m_dFactor * double(m_iResolution);
276  LocalStorage.Calculate();
277 
278  // copy value to current storage
279  (**Storage) = LocalStorage;
280 
281  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
282 
283  } // if (not m_BitValues.empty())
284 
285  // finally break
286  break;
287 
288 
289  case ::oETCS::DF::CVariable::PER_MILL:
290 
291  // convert integer to double
292  dDoubleOutput = lRawInteger;
293 
294 
295  // check, if a storage is connected
296  if (not m_BitValues.empty())
297  {
298  // copy normalised double output to storage
299  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
300  {
301  // set value in local storage
302  LocalStorage.m_dDoubleInput = dDoubleOutput / 1000 * m_dFactor * double(m_iResolution);
303  LocalStorage.Calculate();
304 
305  // copy value to current storage
306  (**Storage) = LocalStorage;
307 
308  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
309 
310  } // if (not m_BitValues.empty())
311 
312  // finally break
313  break;
314 
315 
317 
318  // check, if a storage is connected
319  if (not m_BitValues.empty())
320  {
321  // compose string byte/character-wise
322  for (x = 0; x < (m_Value.size() / 8); x++)
323  {
324  // compose current character bit-wise
325  for (y = 0; y < 8; y++)
326  {
327  // add current bit to current char
328  cRawCharacter += (m_Value[y + x * 8] << (7 - y));
329 
330  } // for (y = 0; y < 8; y++)
331 
332  // add current char to string
333  RawString += cRawCharacter;
334 
335  // reset character
336  cRawCharacter = 0;
337 
338  } // for (x = 0; x < (m_Value.size() / 8); x++)
339 
340  // copy string to output
341  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
342  {
343  // set value in local storage
344  LocalStorage.m_StringInput = RawString;
345  LocalStorage.Calculate();
346 
347  // copy string to current storage
348  (**Storage) = LocalStorage;
349 
350  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
351 
352  } // if (not m_BitValues.empty())
353 
354  // finally break
355  break;
356 
357  } // switch (m_eUnit)
358 
359  // set iteration in all related variable objects
360  for (x = 0; x < NUMBER_ITERATED; x++)
361  {
362  // check, if this variable is not an conditional iterator or conditional value is met
363  if (not m_bConditionalIterator)
364  {
365  // set iteration value in current variable object
366  m_IteratedVariables[x]->m_iIterated = lRawInteger * int(m_dFactor) * m_iResolution;
367 
368  } // if (not m_bConditionalIterator || m_lConditionalValue == lRawInteger)
369  else if (m_bConditionalIterator && m_lConditionalValue == lRawInteger )
370  {
371  // set iteration value in current variable object to one (multiplied with resolution and factor)
372  m_IteratedVariables[x]->m_iIterated = int(m_dFactor) * m_iResolution;
373 
374  } // else if (m_bConditionalIterator && m_lConditionalValue == lRawInteger )
375  else
376  {
377  // set iteration value in current variable object to zero
378  m_IteratedVariables[x]->m_iIterated = 0;
379 
380  } // else
381 
382  // resize value bit vector due to new iteration in current variable object
384 
385  } // for (x = 0; x < NUMBER_ITERATED; x++)
386 
387  // set scaling factor in all related variable objects
388  for (x = 0; x < NUMBER_SCALED; x++)
389  {
390  // set iteration value in current variable object
391  m_ScaledVariables[x]->m_dFactor = lRawInteger * m_dFactor * double(m_iResolution);
392 
393  } // for (x = 0; x < NUMBER_SCALED; x++)
394 
395  } // if (m_iIterated == 1)
396  else
397  {
398  // split bit stack in array
399  for (x = 0; x < m_iIterated; x++)
400  {
401  // copy bits for current array element
402  for (y = 0; y < m_lSize; y++)
403  {
404  // copy current bits
405  ArrayValue[x].push_back(m_Value[y + x * m_lSize]);
406 
407  } // for (y = 0; y < m_lSize; y++)
408 
409  // check, if current value exists in map
410  if (m_ValueMap.find(ArrayValue[x]) != m_ValueMap.end())
411  {
412  // apply value from map to current value
413  ArrayValue[x] = m_ValueMap.find(ArrayValue[x])->second->m_Value;
414 
415  } // if (m_ValueMap.find(ArrayValue[x]) != m_ValueMap.end())
416 
417  } // for (x = 0; x < m_iIterated; x++)
418 
419  // check, if unit is not string
421  {
422  // check, if size of value stack is bigger than system integer
423  if (m_lSize > (sizeof(long) * 8))
424  {
425  // print warning to stderr
426  ::std::cerr << "In file " << __FILE__ << " at line " << __LINE__ << ": size of value stack is bigger as system integer, rest will be ignored " << ::std::endl;
427 
428  } // if (m_lSize > (sizeof(int) * 8))
429 
430  // convert all array elements
431  for (x = 0; x < m_iIterated; x++)
432  {
433  // convert bit stack to integer bit-wise
434  for (y = 0; y < m_lSize && y < (sizeof(long) * 8); y++)
435  {
436  // add current byte to current raw integer
437  RawIntegers[x] += long(ArrayValue[x][y] << (m_lSize - 1 - y));
438 
439  } // for (y = 0; y < m_lSize && y < (sizeof(int) * 8); y++)
440 
441  } // for (x = 0; x < m_iIterated; x++)
442 
443  } // if (m_eUnit != ::oETCS::DF::CVariable::STRING)
444 
445 
446  // check unit of this variable
447  switch (m_eUnit)
448  {
450  case ::oETCS::DF::CVariable::SECONDS:
451  case ::oETCS::DF::CVariable::METERS:
452 
453  // convert raw integer array in double array
454  for (x = 0; x < m_iIterated; x++)
455  {
456  // convert current element
457  DoubleOutputs[x] = double(RawIntegers[x]) * m_dFactor * double(m_iResolution);
458 
459  } // for (x = 0; x < m_iIterated; x++)
460 
461  // check, if a storage is connected
462  if (not m_BitValues.empty())
463  {
464  // copy array double output to storage
465  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
466  {
467  // set value in local storage
468  LocalStorage.m_DoubleArrayInput = DoubleOutputs;
469  LocalStorage.Calculate();
470 
471  // copy array to current storage
472  (**Storage) = LocalStorage;
473 
474  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
475 
476  } // if (not m_BitValues.empty())
477 
478  // finally break
479  break;
480 
481 
482  case ::oETCS::DF::CVariable::INTEGER:
483 
484  // convert raw integer array in double array
485  for (x = 0; x < m_iIterated; x++)
486  {
487  // convert current element
488  DoubleOutputs[x] = RawIntegers[x] * int(m_dFactor) * m_iResolution;
489 
490  } // for (x = 0; x < m_iIterated; x++)
491 
492  // check, if a storage is connected
493  if (not m_BitValues.empty())
494  {
495  // print warning to stderr
496  ::std::cerr << "In file " << __FILE__ << " at line " << __LINE__ << ": integer array input type not (yet) defined " << ::std::endl;
497 
498  } // if (not m_BitValues.empty())
499 
500  // finally break
501  break;
502 
503 
504  case ::oETCS::DF::CVariable::KILO_METERS_PER_HOUR:
505 
506  // convert raw integer array in double array
507  for (x = 0; x < m_iIterated; x++)
508  {
509  // convert current element
510  DoubleOutputs[x] = double(RawIntegers[x]) / 3.6 * m_dFactor * double(m_iResolution);
511 
512  } // for (x = 0; x < m_iIterated; x++)
513 
514  // check, if a storage is connected
515  if (not m_BitValues.empty())
516  {
517  // copy double array output to storage
518  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
519  {
520  // set value in local storage
521  LocalStorage.m_DoubleArrayInput = DoubleOutputs;
522  LocalStorage.Calculate();
523 
524  // copy array to current storage
525  (**Storage) = LocalStorage;
526 
527  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
528 
529  } // if (not m_BitValues.empty())
530 
531  // finally break
532  break;
533 
534 
535  case ::oETCS::DF::CVariable::CENTI_METERS:
536 
537  // convert raw integer array in double array
538  for (x = 0; x < m_iIterated; x++)
539  {
540  // convert current element
541  DoubleOutputs[x] = double(RawIntegers[x]) / 100 * m_dFactor * double(m_iResolution);
542 
543  } // for (x = 0; x < m_iIterated; x++)
544 
545  // check, if a storage is connected
546  if (not m_BitValues.empty())
547  {
548  // copy double array output to storage
549  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
550  {
551  // set value in local storage
552  LocalStorage.m_DoubleArrayInput = DoubleOutputs;
553  LocalStorage.Calculate();
554 
555  // copy array to current storage
556  (**Storage) = LocalStorage;
557 
558  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
559 
560  } // if (not m_BitValues.empty())
561 
562  // finally break
563  break;
564 
565 
566  case ::oETCS::DF::CVariable::PER_MILL:
567 
568  // convert raw integer array in double array
569  for (x = 0; x < m_iIterated; x++)
570  {
571  // convert current element
572  DoubleOutputs[x] = double(RawIntegers[x]) / 1000 * m_dFactor * double(m_iResolution);
573 
574  } // for (x = 0; x < m_iIterated; x++)
575 
576  // check, if a storage is connected
577  if (not m_BitValues.empty())
578  {
579  // copy double array output to storage
580  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
581  {
582  // set value in local storage
583  LocalStorage.m_DoubleArrayInput = DoubleOutputs;
584  LocalStorage.Calculate();
585 
586  // copy array to current storage
587  (**Storage) = LocalStorage;
588 
589  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
590 
591  } // if (not m_BitValues.empty())
592 
593  // finally break
594  break;
595 
596 
598 
599  // convert value array in string array
600  for (x = 0; x < m_iIterated; x++)
601  {
602  // compose string byte/character-wise
603  for (y = 0; y < (m_Value.size() / 8); y++)
604  {
605  // compose current character bit-wise
606  for (z = 0; z < 8; z++)
607  {
608  // add current bit to current char
609  cRawCharacter += char(m_Value[z + y * 8] << (7 - z));
610 
611  } // for (z = 0; z < 8; z++)
612 
613  // add current char to string
614  StringOutputs[x] += cRawCharacter;
615 
616  // reset character
617  cRawCharacter = 0;
618 
619  } // for (y = 0; y < (m_Value.size() / 8); y++)
620 
621  } // for (x = 0; x < m_iIterated; x++)
622 
623  // check, if a storage is connected
624  if (not m_BitValues.empty())
625  {
626  // print warning to stderr
627  ::std::cerr << "In file " << __FILE__ << " at line " << __LINE__ << ": string array input type not (yet) defined " << ::std::endl;
628 
629  } // if (not m_BitValues.empty())
630 
631  // finally break
632  break;
633 
634  } // switch (m_eUnit)
635 
636  } // else
637 
638 
639 
640  try
641  {
642  // finally call calculate on all connected storages
643  for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
644  {
645  // call calculate on current storage
646  (**Storage)->Calculate();
647 
648  } // for (Storage = m_BitValues.begin(); Storage != m_BitValues.end(); Storage++)
649 
650  } // try
651  catch (const ::oETCS::DF::Error::CException&)
652  {
653  // just re-throw exception
654  throw;
655 
656  } // catch (const ::oETCS::DF::Error::CException&)
657 
658 
659  } // if (m_iIterated != 0)
660 
661  // Bouml preserved body end 0006C602
662 
663 } // void CVariable::Calculate() throw(::oETCS::DF::Error::CException)
664 
665 
666 
667 
668 unsigned long CVariable::GetSize() const throw()
669 {
670  // Bouml preserved body begin 00078282
671  // return the number of bits used for the variable (size multiplied by iterations)
672  return (m_lSize * m_iIterated);
673  // Bouml preserved body end 00078282
674 
675 } // unsigned long CVariable::GetSize() const throw()
676 
677 
678 
679 
680 void CVariable::SetValue(const ::std::string& Value) throw()
681 {
682  // Bouml preserved body begin 000A8602
683  unsigned int x(0);
684 
685 
686  // resize member vector
687  m_Value.resize(Value.length());
688 
689  // copy string byte/character-wise
690  for (x = 0; x < Value.length(); x++)
691  {
692  // set member from parameter
693  m_Value[x] = Value[x];
694 
695  } // for (x = 0; x < Value.length(); x++)
696  // Bouml preserved body end 000A8602
697 
698 } // void CVariable::SetValue() throw()
699 
700 
701 
702 
703 oETCS::DF::CVariable& CVariable::operator<<(const ::std::vector< bool >& Bits) throw(::oETCS::DF::Error::CException)
704 {
705  // Bouml preserved body begin 00079E82
706  ::std::vector< bool >::const_iterator Left(Bits.begin());
707  ::std::vector< bool >::const_iterator Right(Bits.begin());
708 
709 
710 
711  // check, if bit vector has enough data for this variable
712  if ((m_lSize * m_iIterated) > Bits.size())
713  {
714  // throw exception
715  throw (::oETCS::DF::Error::CInput("bit vector does not hold enough data for this variable"));
716 
717  } // if ((m_lSize * m_iIterated) > Bits.size())
718 
719  // set right end for bits needed for this variable
720  Right += (m_lSize * m_iIterated);
721 
722  // copy bits from parameter to local member
723  m_Value = ::std::vector< bool >(Left, Right);
724 
725  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
726  // DEBUG
727  ::std::cout << "CVariable::operator<<() bits used: ";
728  for (decltype (m_Value.begin()) lb = m_Value.begin(); lb != m_Value.end(); lb++)
729  {
730  ::std::cout << *lb << "," << ::std::flush;
731 
732  } // for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
733  ::std::cout << " # bits: "<< m_Value.size() << ::std::endl;
734  #endif
735 
736  // finally return reference to this instance
737  return (*this);
738  // Bouml preserved body end 00079E82
739 
740 } // oETCS::DF::CVariable CVariable::operator<<() throw(::oETCS::DF::Error::CException)
741 
742 
743 
744 
746 {
747  // Bouml preserved body begin 000ABC02
748  // check, if a storage is connected
749  if (not m_BitValues.empty() && m_BitValues[0]->operator ->() != nullptr)
750  {
751  // get bits from storage
752  Bits = (*m_BitValues[0])->GetBitVector(m_lSize);
753 
754  } // if (not m_BitValues.empty() && m_BitValues[0]->operator ->() != nullptr)
755  else
756  {
757  // resize bit vector to 0
758  Bits.resize(0);
759 
760  } // else
761 
762  // return reference to this instance
763  return (*this);
764  // Bouml preserved body end 000ABC02
765 
766 } // oETCS::DF::CVariable CVariable::operator>>() throw(::oETCS::DF::Error::CException)
767 
768 
769 
770 
772 
773 {
774  // Bouml preserved body begin 000AA082
776  ::oETCS::DF::VARIABLE_VALUE_VECTOR_T::iterator vv;
777  ::std::stringstream Conversion;
778  decltype (Value.begin()) v;
779  long long llValue(0);
780  double dValue(0.0);
781  char cPrefix(0);
782  unsigned char x(0);
783  unsigned char y(0);
784  const unsigned char* pByte(0);
785  bool bConverted(false);
786 
787 
788 
789  // check, if value is non-empty
790  if (not Value.empty())
791  {
792  // get prefix from value
793  cPrefix = Value[0];
794 
795  // switch prefix
796  switch (cPrefix)
797  {
798  case 'd':
799  // stream value string in conversion stream (without prefix)
800  Conversion << Value.substr(1, Value.size() - 1);
801 
802  // convert stream in double
803  bConverted = (Conversion >> dValue);
804 
805  // check, if conversion was not successful
806  if (not bConverted)
807  {
808  // set default integer value 0 to value
809  llValue = 0;
810 
811  } // if (not bConverted)
812  else
813  {
814  // convert double in integer
815  llValue = dValue;
816 
817  } // else
818 
819  // set size of value vector depending on size of integer
820  ValueVector.resize(8 * sizeof (llValue));
821 
822  // initialise value vector iterator
823  vv = ValueVector.begin();
824 
825  // initialise byte pointer at the end/MSB of the integer
826  pByte = reinterpret_cast< const unsigned char* >(&llValue) + sizeof (llValue) - 1;
827 
828  // copy bytes of value into vector
829  for (x = 0; x < sizeof (llValue); x++)
830  {
831  // copy all bits of current byte
832  for (y = 0; y < 8; y++)
833  {
834  // copy current bit
835  *vv = ((1 << (7 - y)) & (*pByte)) == 0 ? false : true;
836 
837  // increase iterator to next bit
838  vv++;
839 
840  } // for (y = 0; y < 8; y++)
841 
842  // increase byte pointer
843  pByte--;
844 
845  } // for (x = 0; x < sizeof (llValue); x++)
846 
847  break;
848 
849 
850  case 'i':
851 
852  // stream value string in conversion stream (without prefix)
853  Conversion << Value.substr(1, Value.size() - 1);
854 
855  // convert stream in integer
856  bConverted = (Conversion >> llValue);
857 
858  // check, if conversion was not successful
859  if (not bConverted)
860  {
861  // set default value 0 to value
862  llValue = 0;
863 
864  } // if (not bConverted)
865 
866  // set size of value vector depending on size of integer
867  ValueVector.resize(8 * sizeof (llValue));
868 
869  // initialise value vector iterator
870  vv = ValueVector.begin();
871 
872  // initialise byte pointer at the end/MSB of the integer
873  pByte = reinterpret_cast< const unsigned char* >(&llValue) + sizeof (llValue) - 1;
874 
875  // copy bytes of value into vector
876  for (x = 0; x < sizeof (llValue); x++)
877  {
878  // copy all bits of current byte
879  for (y = 0; y < 8; y++)
880  {
881  // copy current bit
882  *vv = ((1 << (7 - y)) & (*pByte));
883 
884  // increase iterator to next bit
885  vv++;
886 
887  } // for (y = 0; y < 8; y++)
888 
889  // increase byte pointer
890  pByte--;
891 
892  } // for (x = 0; x < sizeof (llValue); x++)
893 
894  break;
895 
896 
897  case 's':
898 
899  // set value vector size to 8 times the string size
900  ValueVector.resize((Value.size() - 1) * 8);
901 
902  // process string character-wise (ignore prefix)
903  for (v = Value.begin() + 1, vv = ValueVector.begin(); v != Value.end() && vv != ValueVector.end(); v++, vv + 8)
904  {
905  // copy current char bit-wise
906  for (x = 0; x < 8; x++)
907  {
908  // copy current bit to value vector
909  *(vv + x) = ((*v) & (1 << x)) == 0 ? 0 : 1;
910 
911  } // for (x = 0; x < 8; x++)
912 
913  } // for (v = Value.begin() + 1, vv = ValueVector.begin(); v != Value.end() && vv != ValueVector.end(); v++, vv + 8)
914 
915  break;
916 
917 
918  case '0':
919  case '1':
920  default:
921 
922  // set value vector to same size as value string
923  ValueVector.resize(Value.size());
924 
925  // copy element-wise
926  for (v = Value.begin(), vv = ValueVector.begin(); v != Value.end() && vv != ValueVector.end(); v++, vv++)
927  {
928  // copy current element
929  *vv = (*v == '0' ? false : true);
930 
931  } // for (v = Value.begin(), vv = ValueVector.begin(); v != Value.end() && vv != ValueVector.end(); v++, vv++)
932 
933  break;
934 
935  } // switch (cPrefix)
936 
937  } // if (not Value.empty())
938 
939 
940  // return value vector
941  return (ValueVector);
942  // Bouml preserved body end 000AA082
943 
944 } // oETCS::DF::VARIABLE_VALUE_VECTOR_T CVariable::StringToValueVector() throw()
945 
946 
947 
948 
949 
950 CPacket::CPacket(oETCS::DF::CEVCStateMachine * const pStateMachine, const unsigned char & cID, const ::std::vector< oETCS::DF::CVariable * >& Variables) throw()
951 :CLanguage(pStateMachine),
952  m_cID(cID),
953  m_Variables(Variables)
954 {
955  // Bouml preserved body begin 0006A902
956  // empty constructor
957  // Bouml preserved body end 0006A902
958 
959 } // CPacket::CPacket() throw()
960 
961 
962 
963 
965 {
966  // Bouml preserved body begin 0006A982
967  // empty destructor
968  // Bouml preserved body end 0006A982
969 
970 } // CPacket::~CPacket() throw()
971 
972 
973 
974 
975 unsigned long CPacket::GetSize() const throw()
976 {
977  // Bouml preserved body begin 00078302
978  unsigned int x(0);
979  unsigned long lSize(0);
980  const unsigned int NUMBER_VARIABLES(m_Variables.size());
981 
982 
983  // process all included variables
984  for (x = 0; x < NUMBER_VARIABLES; x++)
985  {
986  // add size of current variable to size
987  lSize += m_Variables[x]->GetSize();
988 
989  } // for (x = 0; x < NUMBER_VARIABLES; x++)
990 
991  // return complete size
992  return (lSize);
993  // Bouml preserved body end 00078302
994 
995 } // unsigned long CPacket::GetSize() const throw()
996 
997 
998 
999 
1000 oETCS::DF::CPacket& CPacket::operator<<(::std::vector< bool >& Bits) throw(::oETCS::DF::Error::CException)
1001 {
1002  // Bouml preserved body begin 00079E02
1003  unsigned char cID(0);
1004  unsigned int x(0);
1005  const unsigned int NUMBER_VARIABLES(m_Variables.size());
1006  ::std::vector< bool >::iterator Left(Bits.begin());
1007  ::std::vector< bool >::iterator Right(Bits.begin());
1008 
1009 
1010 
1011  // check, if bit vector at least contains enough data for identifier
1012  if ((sizeof (m_cID) * 8) > Bits.size())
1013  {
1014  // throw exception
1015  throw (::oETCS::DF::Error::CInput("no enough data in bit vector for a packet"));
1016 
1017  } // if ((sizeof (m_cID) * 8) > Bits.size())
1018 
1019 
1020  // set right identifier for getting the first bits defining the identifier
1021  Right += sizeof (m_cID) * 8;
1022 
1023  // compose identifier form first bits
1024  for (x = 0; x < (sizeof (m_cID) * 8); x++)
1025  {
1026  // add current bit to identifier
1027  cID += (Bits[x]) << ((sizeof (m_cID) * 8) - 1 - x);
1028 
1029  } // for (x = 0; x < sizeof (m_cID) * 8; x++)
1030 
1031  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1032  // DEBUG
1033  ::std::cout << "CPacket::operator<<() found ID: " << int(cID) << " while ID of this packet " << int(m_cID) << ::std::endl;
1034  #endif
1035 
1036  // check, if bit stream includes this packet (if not just ignore it)
1037  if (m_cID == cID)
1038  {
1039  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1040  // DEBUG
1041  ::std::cout << "CPacket::operator<<() found matching ID: " << int(m_cID) << ::std::endl;
1042  #endif
1043 
1044  // process all included variables
1045  for (x = 0; x < NUMBER_VARIABLES; x++)
1046  {
1047  // check, if still enough bits are available in stream
1048  if (Bits.size() < m_Variables[x]->GetSize())
1049  {
1050  // throw exception
1051  throw (::oETCS::DF::Error::CInput("not even enough bits in stream for variables in packet"));
1052 
1053  } // if (Bits.size() < m_Variables[x]->GetSize())
1054 
1055  try
1056  {
1057  // compute new right end of bits for current variable
1058  Right = Left + m_Variables[x]->GetSize();
1059 
1060  // send relevant bits to current variable
1061  (*m_Variables[x]) << ::std::vector< bool >(Left, Right);
1062 
1063  // execute variable real value calculation to enable iteration, factor calculation etc.
1064  m_Variables[x]->Calculate();
1065 
1066  // strip used bits for current packets from bit stream
1067  Bits.erase(Left, Right);
1068 
1069  // reset left iterator
1070  Left = Bits.begin();
1071 
1072  } // try
1073  catch (const ::oETCS::DF::Error::CException&)
1074  {
1075  // just re-throw exception
1076  throw;
1077 
1078  } // catch (const ::oETCS::DF::Error::CException&)
1079 
1080  } // for (x = 0; x < NUMBER_VARIABLES; x++)
1081 
1082  } // if (m_cID == cID)
1083  else
1084  {
1085  // throw exception
1086  throw (::oETCS::DF::Error::CInput("false packet ID in stream"));
1087 
1088  } // else
1089 
1090 
1091  // return reference to this instance
1092  return (*this);
1093  // Bouml preserved body end 00079E02
1094 
1095 } // oETCS::DF::CPacket CPacket::operator<<() throw(::oETCS::DF::Error::CException)
1096 
1097 
1098 
1099 
1100 oETCS::DF::CPacket& CPacket::operator>>(::std::vector< bool >& Bits) throw()
1101 {
1102  // Bouml preserved body begin 000ABB82
1103  decltype (m_Variables.begin()) x(0);
1104  ::std::vector< bool > LocalBits(0);
1105 
1106 
1107 
1108  // resize bits
1109  Bits.resize(0);
1110 
1111  // process all variables in this packet
1112  for (x = m_Variables.begin(); x != m_Variables.end(); x++)
1113  {
1114  // get bits from current variable
1115  **x >> LocalBits;
1116 
1117  // add bits to parameter
1118  Bits.insert(Bits.end(), LocalBits.begin(), LocalBits.end());
1119 
1120  } // for (x = m_Variables.begin(); x != m_Variables.end(); x++)
1121 
1122 
1123  // return reference to this instance
1124  return (*this);
1125  // Bouml preserved body end 000ABB82
1126 
1127 } // oETCS::DF::CPacket CPacket::operator>>() throw()
1128 
1129 
1130 
1131 
1132 CTelegram::CTelegram(oETCS::DF::CEVCStateMachine * const pStateMachine, const ::std::vector< oETCS::DF::CVariable * >& Header, const ::std::vector< oETCS::DF::CPacket * >& Packets) throw()
1133 :CLanguage(pStateMachine),
1134  m_Packets(Packets),
1135  m_Header(Header)
1136 {
1137  // Bouml preserved body begin 0006A702
1138  // empty constructor
1139  // Bouml preserved body end 0006A702
1140 
1141 } // CTelegram::CTelegram() throw()
1142 
1143 
1144 
1145 
1147 {
1148  // Bouml preserved body begin 0006A782
1149  // empty destructor
1150  // Bouml preserved body end 0006A782
1151 
1152 } // CTelegram::~CTelegram() throw()
1153 
1154 
1155 
1156 
1157 unsigned long CTelegram::GetSize() const throw()
1158 {
1159  // Bouml preserved body begin 00078382
1160  unsigned int x(0);
1161  unsigned long lSize(0);
1162  const unsigned int NUMBER_PACKETS(m_Packets.size());
1163  const unsigned int NUMBER_HEADER(m_Header.size());
1164 
1165 
1166 
1167  // process all included variables in header
1168  for (x = 0; x < NUMBER_HEADER; x++)
1169  {
1170  // add size of current variable to size
1171  lSize += m_Header[x]->GetSize();
1172 
1173  } // for (x = 0; x < NUMBER_HEADER; x++)
1174 
1175  // process all included packets
1176  for (x = 0; x < NUMBER_PACKETS; x++)
1177  {
1178  // add size of current variable to size
1179  lSize += m_Packets[x]->GetSize();
1180 
1181  } // for (x = 0; x < NUMBER_PACKETS; x++)
1182 
1183  // return complete size
1184  return (lSize);
1185  // Bouml preserved body end 00078382
1186 
1187 } // unsigned long CTelegram::GetSize() const throw()
1188 
1189 
1190 
1191 
1192 ::std::vector< unsigned char > CTelegram::operator<<(const ::std::vector< bool >& Bits) throw(::oETCS::DF::Error::CException)
1193 {
1194  // Bouml preserved body begin 00078402
1195  unsigned int x(0);
1196  const unsigned int NUMBER_VARIABLES_HEADER(m_Header.size());
1197  const unsigned int NUMBER_PACKETS(m_Packets.size());
1198  ::std::vector< bool > LocalBits(Bits);
1199  ::std::vector< bool >::iterator Left(LocalBits.begin());
1200  ::std::vector< bool >::iterator Right(LocalBits.begin());
1201  ::std::vector< unsigned char > FoundPacketIDs(0);
1202 
1203 
1204 
1205 
1206  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1207  // DEBUG
1208  ::std::cout << "CTelegram::operator<<() bits before header: ";
1209  for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
1210  {
1211  ::std::cout << *lb << "," << ::std::flush;
1212 
1213  } // for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
1214  ::std::cout << " # bits: "<< LocalBits.size() << ::std::endl;
1215  #endif // __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1216 
1217 
1218  // first process header
1219  for (x = 0; x < NUMBER_VARIABLES_HEADER; x++)
1220  {
1221  try
1222  {
1223  // compute new right end of bits for current variable
1224  Right = Left + m_Header[x]->GetSize();
1225 
1226  // check, if still enough bits are available in stream
1227  if (Right == LocalBits.end())
1228  {
1229  // throw exception
1230  throw (::oETCS::DF::Error::CInput("not even enough bits in stream for telegram header"));
1231 
1232  } // if (Right == LocalBits.end())
1233 
1234  // send relevant bits to current header variable
1235  (*m_Header[x]) << ::std::vector< bool >(Left, Right);
1236 
1237  // compute new left interval in bit stream
1238  Left = Right;
1239 
1240 
1241  // execute variable real value calculation to enable iteration, factor calculation etc.
1242  m_Header[x]->Calculate();
1243 
1244  } // try
1245  catch (const ::oETCS::DF::Error::CException&)
1246  {
1247  // just re-throw exception
1248  throw;
1249 
1250  } // catch (const ::oETCS::DF::Error::CException&)
1251 
1252  } // for (x = 0; x < NUMBER_VARIABLES_HEADER; x++)
1253 
1254  // strip used bits for header from local bit stream
1255  LocalBits.erase(LocalBits.begin(), Right);
1256 
1257 
1258  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1259  // DEBUG
1260  ::std::cout << "CTelegram::operator<<() bits after header: ";
1261  for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
1262  {
1263  ::std::cout << *lb << "," << ::std::flush;
1264 
1265  } // for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
1266  ::std::cout << " # bits: "<< LocalBits.size() << ::std::endl;
1267  #endif
1268 
1269 
1270  // process all packets
1271  for (x = 0; x < NUMBER_PACKETS; x++)
1272  {
1273  try
1274  {
1275  // stream rest of local bit stream to current package
1276  (*m_Packets[x]) << LocalBits;
1277 
1278  // add packet ID of current packet to vector
1279  FoundPacketIDs.push_back(m_Packets[x]->m_cID);
1280 
1281 
1282  #ifdef __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1283  // DEBUG
1284  ::std::cout << "CTelegram::operator<<() bits after packet: ";
1285  for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
1286  {
1287  ::std::cout << *lb << "," << ::std::flush;
1288 
1289  } // for (decltype (LocalBits.begin()) lb = LocalBits.begin(); lb != LocalBits.end(); lb++)
1290  ::std::cout << " # bits: "<< LocalBits.size() << ::std::endl;
1291  #endif // __OETCS_DF_LANGUAGE_DEBUG_OUTPUT__
1292 
1293  } // try
1294  catch (const ::oETCS::DF::Error::CInput&)
1295  {
1296  // exception if input type are ignored since they mean only that bits do not fit the current packet
1297 
1298  } // catch (const ::oETCS::DF::Error::CInput&)
1299  catch (const ::oETCS::DF::Error::CException&)
1300  {
1301  // just re-throw exception
1302  throw;
1303 
1304  } // catch (const ::oETCS::DF::Error::CException&)
1305 
1306  } // for (x = 0; x < NUMBER_PACKETS; x++)
1307 
1308 
1309 
1310  // check, if bit stream was completely consumed
1311  if (!LocalBits.empty())
1312  {
1313  // throw exception
1314  throw (::oETCS::DF::Error::CInput("not all bits in stream could be used for telegram reconstruction"));
1315 
1316  } // if (!LocalBits.empty())
1317 
1318  // finally return list of found packet IDs
1319  return (FoundPacketIDs);
1320  // Bouml preserved body end 00078402
1321 
1322 } // unsigned char CTelegram::operator<<() throw(::oETCS::DF::Error::CException)
1323 
1324 
1325 
1326 
1327 oETCS::DF::CTelegram& CTelegram::operator>>(::std::vector< bool >& Bits) throw()
1328 {
1329  // Bouml preserved body begin 000ABB02
1330  decltype (m_Header.begin()) x(0);
1331  decltype (m_Packets.begin()) y(0);
1332  ::std::vector< bool > LocalBits(0);
1333 
1334 
1335 
1336  // resize parameter
1337  Bits.resize(0);
1338 
1339  // process all header variables first
1340  for (x = m_Header.begin(); x != m_Header.end(); x++)
1341  {
1342  // get bits from current header variable
1343  **x >> LocalBits;
1344 
1345  // insert current bits into parameter
1346  Bits.insert(Bits.begin(), LocalBits.begin(), LocalBits.end());
1347 
1348  } // for (x = m_Header.begin(); x != m_Header.end(); x++)
1349 
1350  // process all packets
1351  for (y = m_Packets.begin(); y != m_Packets.end(); y++)
1352  {
1353  // get bits from current packet
1354  **y >> LocalBits;
1355 
1356  // insert current bits into parameter
1357  Bits.insert(Bits.begin(), LocalBits.begin(), LocalBits.end());
1358 
1359  } // for (y = m_Packets.begin(); y != m_Packets.end(); y++)
1360 
1361 
1362  // return reference to this instance
1363  return (*this);
1364  // Bouml preserved body end 000ABB02
1365 
1366 } // oETCS::DF::CTelegram CTelegram::operator>>() throw()
1367 
1368 
1369 
1370 
1371 
1372 
1373 } // namespace oETCS::DF
1374 
1375 } // 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/.