primarydriver.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef PRIMARYDRIVER_H_
15 #define PRIMARYDRIVER_H_
16 
17 #include "driver.h"
18 #include "interface.h"
19 
20 class DECLSPEC_KAME XPrimaryDriver : public XDriver {
21 public:
22  XPrimaryDriver(const char *name, bool runtime, Transaction &tr_meas, const shared_ptr<XMeasure> &meas);
23  virtual ~XPrimaryDriver() = default;
24 
25  //! Shows all forms belonging to driver
26  virtual void showForms() = 0;
27 
28  //! Shuts down your threads, unconnects GUI, and deactivates signals.\n
29  //! This function may be called even if driver has already stopped.
30  //! This should not cause an exception.
31  virtual void stop() = 0;
32 
33 private:
34  friend class XRawStreamRecordReader;
35  friend class XRawStreamRecorder;
36 protected:
37  //! Starts up your threads, connects GUI, and activates signals.
38  //! This function should not cause an exception.
39  virtual void start() = 0;
40  //! Be called for closing interfaces.
41  //! This function should not cause an exception.
42  virtual void closeInterface() = 0;
43 
44  //! These are FIFO.
45  struct RawData : public std::vector<char> {
46  //! Pushes raw data to raw record
47  //! Use signed/unsigned char, int16_t(16bit), and int32_t for integers.
48  //! IEEE 754 float and double for floting point numbers.
49  //! Little endian bytes will be stored into thread-local \sa rawData().
50  //! \sa pop(), rawData()
51  template <typename tVar>
52  inline void push(tVar);
53  private:
54  inline void push_char(char);
55  inline void push_int16_t(int16_t);
56  inline void push_int32_t(int32_t);
57  inline void push_double(double);
58  };
59 
60  struct DECLSPEC_KAME RawDataReader {
61  typedef std::vector<char>::const_iterator const_iterator;
62  //! reads raw record
63  //! \sa push(), rawData()
64  template <typename tVar>
65  inline tVar pop() throw (XBufferUnderflowRecordError&);
66 
67  const_iterator begin() const {return m_data.begin();}
68  const_iterator end() const {return m_data.end();}
69  unsigned int size() const {return m_data.size();}
70  const std::vector<char> &data() const {return m_data;}
71  const_iterator &popIterator() {return it;}
72  private:
73  friend class XPrimaryDriver;
74  friend class XRawStreamRecordReader;
75  RawDataReader(const std::vector<char> &data) : m_data(data) {it = data.begin();}
76  RawDataReader();
77  const_iterator it;
78  const std::vector<char> &m_data;
79  inline char pop_char();
80  inline int16_t pop_int16_t();
81  inline int32_t pop_int32_t();
82  inline double pop_double();
83  };
84 
85  //! This function will be called when raw data are written.
86  //! Implement this function to convert the raw data to the record (Payload).
87  //! \sa analyze()
88  virtual void analyzeRaw(RawDataReader &reader, Transaction &tr) throw (XRecordError&) = 0;
89 
90  //! will call analyzeRaw()
91  //! \param rawdata the data being processed.
92  //! \param time_awared time when a visible phenomenon started
93  //! \param time_recorded usually pass \p XTime::now()
94  //! \sa Payload::timeAwared()
95  //! \sa Payload::time()
96  void finishWritingRaw(const shared_ptr<const RawData> &rawdata,
97  const XTime &time_awared, const XTime &time_recorded);
98 public:
99  struct DECLSPEC_KAME Payload : public XDriver::Payload {
100  const RawData &rawData() const {return *m_rawData;}
101  private:
102  friend class XPrimaryDriver;
103  shared_ptr<const RawData> m_rawData;
104  };
105 };
106 
107 inline void
108 XPrimaryDriver::RawData::push_char(char x) {
109  push_back(x);
110 }
111 inline void
112 XPrimaryDriver::RawData::push_int16_t(int16_t x) {
113  int16_t y = x;
114  char *p = reinterpret_cast<char *>(&y);
115 #ifdef __BIG_ENDIAN__
116  for(char *z = p + sizeof(x) - 1; z >= p; z--) {
117 #else
118  for(char *z = p; z < p + sizeof(x); z++) {
119 #endif
120  push_back( *z);
121  }
122 }
123 inline void
124 XPrimaryDriver::RawData::push_int32_t(int32_t x) {
125  int32_t y = x;
126  char *p = reinterpret_cast<char *>(&y);
127 #ifdef __BIG_ENDIAN__
128  for(char *z = p + sizeof(x) - 1; z >= p; z--) {
129 #else
130  for(char *z = p; z < p + sizeof(x); z++) {
131 #endif
132  push_back( *z);
133  }
134 }
135 inline void
136 XPrimaryDriver::RawData::push_double(double x) {
137  static_assert(sizeof(double) == 8, "Not 8-byte sized double"); // for compatibility.
138  double y = x;
139  char *p = reinterpret_cast<char *>( &y);
140 #ifdef __BIG_ENDIAN__
141  for(char *z = p + sizeof(x) - 1; z >= p; z--) {
142 #else
143  for(char *z = p; z < p + sizeof(x); z++) {
144 #endif
145  push_back( *z);
146  }
147 }
148 inline char
149 XPrimaryDriver::RawDataReader::pop_char() {
150  char c = *(it++);
151  return c;
152 }
153 inline int16_t
154 XPrimaryDriver::RawDataReader::pop_int16_t() {
155  union {
156  int16_t x;
157  char p[sizeof(int16_t)];
158  } uni;
159 #ifdef __BIG_ENDIAN__
160  for(char *z = uni.p + sizeof(uni) - 1; z >= uni.p; z--) {
161 #else
162  for(char *z = uni.p; z < uni.p + sizeof(uni); z++) {
163 #endif
164  *z = *(it++);
165  }
166  return uni.x;
167 }
168 inline int32_t
169 XPrimaryDriver::RawDataReader::pop_int32_t() {
170  union {
171  int32_t x;
172  char p[sizeof(int32_t)];
173  } uni;
174 #ifdef __BIG_ENDIAN__
175  for(char *z = uni.p + sizeof(uni) - 1; z >= uni.p; z--) {
176 #else
177  for(char *z = uni.p; z < uni.p + sizeof(uni); z++) {
178 #endif
179  *z = *(it++);
180  }
181  return uni.x;
182 }
183 inline double
184 XPrimaryDriver::RawDataReader::pop_double() {
185  union {
186  double x;
187  char p[sizeof(double)];
188  } uni;
189 #ifdef __BIG_ENDIAN__
190  for(char *z = uni.p + sizeof(uni) - 1; z >= uni.p; z--) {
191 #else
192  for(char *z = uni.p; z < uni.p + sizeof(uni); z++) {
193 #endif
194  *z = *(it++);
195  }
196  return uni.x;
197 }
198 
199 template <>
200 inline char XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
201  if(it + sizeof(char) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
202  return pop_char();
203 }
204 template <>
205 inline unsigned char XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
206  if(it + sizeof(char) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
207  return static_cast<unsigned char>(pop_char());
208 }
209 template <>
210 inline int16_t XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
211  if(it + sizeof(int16_t) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
212  return pop_int16_t();
213 }
214 template <>
215 inline uint16_t XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
216  if(it + sizeof(int16_t) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
217  return static_cast<uint16_t>(pop_int16_t());
218 }
219 template <>
220 inline int32_t XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
221  if(it + sizeof(int32_t) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
222  return pop_int32_t();
223 }
224 template <>
225 inline uint32_t XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
226  if(it + sizeof(int32_t) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
227  return static_cast<uint32_t>(pop_int32_t());
228 }
229 template <>
230 inline float XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
231  if(it + sizeof(float) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
232  union {
233  int32_t x;
234  float y;
235  } uni;
236  static_assert(sizeof(uni.x) == sizeof(uni.y), "Size mismatch");
237  uni.x = pop_int32_t();
238  return uni.y;
239 }
240 template <>
241 inline double XPrimaryDriver::RawDataReader::pop() throw (XBufferUnderflowRecordError&) {
242  if(it + sizeof(double) > end()) throw XBufferUnderflowRecordError(__FILE__, __LINE__);
243  static_assert(sizeof(double) == 8, "Not 8-byte sized double");
244  return pop_double();
245 }
246 
247 template <>
248 inline void XPrimaryDriver::RawData::push(char x) {
249  push_char(x);
250 }
251 template <>
252 inline void XPrimaryDriver::RawData::push(unsigned char x) {
253  push_char(static_cast<char>(x));
254 }
255 template <>
256 inline void XPrimaryDriver::RawData::push(int16_t x) {
257  push_int16_t(x);
258 }
259 template <>
260 inline void XPrimaryDriver::RawData::push(uint16_t x) {
261  push_int16_t(static_cast<int16_t>(x));
262 }
263 template <>
264 inline void XPrimaryDriver::RawData::push(int32_t x) {
265  push_int32_t(x);
266 }
267 template <>
268 inline void XPrimaryDriver::RawData::push(uint32_t x) {
269  push_int32_t(static_cast<int32_t>(x));
270 }
271 template <>
272 inline void XPrimaryDriver::RawData::push(float f) {
273  union {
274  int32_t x;
275  float y;
276  } uni;
277  static_assert(sizeof(uni.x) == sizeof(uni.y), "Size mismatch");
278  uni.y = f;
279  push_int32_t(uni.x);
280 }
281 template <>
282 inline void XPrimaryDriver::RawData::push(double x) {
283  push_double(x);
284 }
285 
286 #endif /*PRIMARYDRIVER_H_*/

Generated for KAME4 by  doxygen 1.8.3