DABC (Data Acquisition Backbone Core)  2.9.9
SlowControlData.h
Go to the documentation of this file.
1 // $Id: SlowControlData.h 4473 2020-04-15 13:35:08Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #ifndef MBS_SlowControlData
17 #define MBS_SlowControlData
18 
19 #include <cstdint>
20 #include <cstdio>
21 #include <cstring>
22 #include <string>
23 #include <vector>
24 
25 
26 namespace mbs {
27 
33  protected:
34 
35  uint32_t fEventId;
36  uint32_t fEventTime;
37 
38  std::vector<std::string> fLongRecords;
39  std::vector<int64_t> fLongValues;
40 
41  std::vector<std::string> fDoubleRecords;
42  std::vector<double> fDoubleValues;
43 
44  std::string fDescriptor;
45 
47  {
48  fDescriptor.clear();
49 
50  fDescriptor.append(dabc::format("%u ", (unsigned) fLongRecords.size()));
51  fDescriptor.append(1,'\0');
52 
53  for (unsigned ix = 0; ix < fLongRecords.size(); ++ix) {
54  // record the name of just written process variable:
55  fDescriptor.append(fLongRecords[ix]);
56  fDescriptor.append(1,'\0');
57  }
58 
59  fDescriptor.append(dabc::format("%u ", (unsigned) fDoubleRecords.size()));
60  fDescriptor.append(1,'\0');
61 
62  for (unsigned ix = 0; ix < fDoubleRecords.size(); ix++) {
63  // record the name of just written process variable:
64  fDescriptor.append(fDoubleRecords[ix]);
65  fDescriptor.append(1,'\0');
66  }
67 
68  while (fDescriptor.size() % 4 != 0) fDescriptor.append(1,'\0');
69  }
70 
71 
72  public:
73 
75  fEventId(0),
76  fEventTime(0),
77  fLongRecords(),
78  fLongValues(),
80  fDoubleValues(),
81  fDescriptor()
82  {
83  }
84 
85  virtual ~SlowControlData() {}
86 
87  void Clear()
88  {
89  fEventId = 0;
90  fEventTime = 0;
91  fLongRecords.clear();
92  fLongValues.clear();
93  fDoubleRecords.clear();
94  fDoubleValues.clear();
95  fDescriptor.clear();
96  }
97 
98  bool Empty() const { return fLongRecords.empty() && fDoubleRecords.empty(); }
99 
100  void SetEventId(uint32_t id) { fEventId = id; }
101  uint32_t GetEventId() const { return fEventId; }
102 
103  void SetEventTime(uint32_t tm) { fEventTime = tm; }
104  uint32_t GetEventTime() const { return fEventTime; }
105 
107  void AddLong(const std::string &name, int64_t value, bool checkduplicate = false)
108  {
109  if (checkduplicate)
110  for (unsigned n=0;n<fLongRecords.size();n++)
111  if (fLongRecords[n]==name) {
112  fLongValues[n] = value;
113  return;
114  }
115 
116  fLongRecords.push_back(name);
117  fLongValues.push_back(value);
118  }
119 
121  void AddDouble(const std::string &name, double value, bool checkduplicate = false)
122  {
123  if (checkduplicate)
124  for (unsigned n=0;n<fDoubleRecords.size();n++)
125  if (fDoubleRecords[n]==name) {
126  fDoubleValues[n] = value;
127  return;
128  }
129  fDoubleRecords.push_back(name);
130  fDoubleValues.push_back(value);
131  }
132 
133  unsigned NumLongs() const { return fLongRecords.size(); }
134  int64_t GetLongValue(unsigned indx) { return indx < fLongValues.size() ? fLongValues[indx] : 0; }
135  std::string GetLongName(unsigned indx) { return indx < fLongRecords.size() ? fLongRecords[indx] : std::string(); }
136 
137  unsigned NumDoubles() const { return fDoubleRecords.size(); }
138  double GetDoubleValue(unsigned indx) { return indx < fDoubleValues.size() ? fDoubleValues[indx] : 0.; }
139  std::string GetDoubleName(unsigned indx) { return indx < fDoubleRecords.size() ? fDoubleRecords[indx] : std::string(); }
140 
141 
142  unsigned GetRawSize()
143  {
144  BuildDescriptor();
145 
146  return sizeof(uint32_t) + // event number
147  sizeof(uint32_t) + // time
148  sizeof(uint64_t) + // numlongs
149  fLongValues.size()*sizeof(int64_t) + // longs
150  sizeof(uint64_t) + // numdoubles
151  fDoubleValues.size()*sizeof(double) + // doubles
152  fDescriptor.size();
153  }
154 
155  unsigned Write(void* buf, unsigned buflen)
156  {
157  unsigned size = GetRawSize();
158  if (size > buflen) return 0;
159 
160  char* ptr = (char*) buf;
161 
162  memcpy(ptr, &fEventId, sizeof(fEventId)); ptr+=sizeof(fEventId);
163 
164  memcpy(ptr, &fEventTime, sizeof(fEventTime)); ptr+=sizeof(fEventTime);
165 
166  uint64_t num64 = fLongValues.size();
167  memcpy(ptr, &num64, sizeof(num64)); ptr+=sizeof(num64);
168 
169  for (unsigned ix = 0; ix < fLongValues.size(); ++ix) {
170  int64_t val = fLongValues[ix]; // machine independent representation here
171  memcpy(ptr, &val, sizeof(val)); ptr+=sizeof(val);
172  }
173 
174  // header with number of double records
175  num64 = fDoubleValues.size();
176  memcpy(ptr, &num64, sizeof(num64)); ptr+=sizeof(num64);
177 
178  // data values for double records:
179  for (unsigned ix = 0; ix < fDoubleValues.size(); ix++) {
180  double val = fDoubleValues[ix]; // should be always 8 bytes
181  memcpy(ptr, &val, sizeof(val)); ptr+=sizeof(val);
182  }
183 
184  // copy description of record names at subevent end:
185  memcpy(ptr, fDescriptor.c_str(), fDescriptor.size());
186 
187  return size;
188  }
189 
190  bool Read(void* buf, unsigned bufsize)
191  {
192  if ((buf==0) || (bufsize<24)) return false;
193 
194  Clear();
195 
196  char* ptr = (char*) buf;
197  char* theEnd = ptr + bufsize;
198 
199  memcpy(&fEventId, ptr, sizeof(fEventId)); ptr+=sizeof(fEventId);
200 
201  memcpy(&fEventTime, ptr, sizeof(fEventTime)); ptr+=sizeof(fEventTime);
202 
203  uint64_t num64 = 0;
204  memcpy(&num64, ptr, sizeof(num64)); ptr+=sizeof(num64);
205  fLongValues.reserve(num64);
206  for (uint64_t n=0;n<num64;n++) {
207  int64_t val(0);
208  memcpy(&val, ptr, sizeof(val)); ptr+=sizeof(val);
209  fLongValues.push_back(val);
210  }
211 
212  num64 = 0;
213  memcpy(&num64, ptr, sizeof(num64)); ptr+=sizeof(num64);
214  fDoubleValues.reserve(num64);
215  for (uint64_t n=0;n<num64;n++) {
216  double val = 0.;
217  memcpy(&val, ptr, sizeof(val)); ptr+=sizeof(val);
218  fDoubleValues.push_back(val); // should be always 8 bytes
219  }
220 
221  unsigned num = 0;
222  if (sscanf(ptr, "%u", &num)!=1) {
223  printf("cannot get number of long names\n");
224  return false;
225  }
226  if (num != fLongValues.size()) {
227  printf("mismatch between count long names %u and values %u\n", num, (unsigned) fLongValues.size());
228  return false;
229  }
230  ptr = ptr + strlen(ptr) + 1;
231 
232  fLongRecords.reserve(num);
233  for (unsigned n=0;n<num;n++) {
234  if (ptr>=theEnd) {
235  printf("decoding error\n");
236  return false;
237  }
238  fLongRecords.push_back(ptr);
239  ptr = ptr + strlen(ptr) + 1;
240  }
241 
242  num = 0;
243  if (sscanf(ptr, "%u", &num)!=1) {
244  printf("cannot get number of double names\n");
245  return false;
246  }
247  if (num != fDoubleValues.size()) {
248  printf("mismatch between count double names %u and values %u\n", num, (unsigned) fDoubleValues.size());
249  return false;
250  }
251  ptr = ptr + strlen(ptr) + 1;
252 
253  fDoubleRecords.reserve(num);
254  for (unsigned n=0;n<num;n++) {
255  if (ptr>=theEnd) {
256  printf("decoding error\n");
257  return false;
258  }
259  fDoubleRecords.push_back(ptr);
260  ptr = ptr + strlen(ptr) + 1;
261  }
262 
263  return true;
264  }
265  };
266 }
267 
268 #endif
Record for manipulation with slow control data.
void SetEventId(uint32_t id)
void SetEventTime(uint32_t tm)
std::string GetDoubleName(unsigned indx)
std::vector< double > fDoubleValues
values of double records
int64_t GetLongValue(unsigned indx)
std::vector< std::string > fLongRecords
names of long records
uint32_t GetEventId() const
std::string GetLongName(unsigned indx)
uint32_t fEventTime
unix time in seconds
unsigned Write(void *buf, unsigned buflen)
unsigned NumLongs() const
bool Read(void *buf, unsigned bufsize)
std::vector< int64_t > fLongValues
values of long records
uint32_t GetEventTime() const
void AddDouble(const std::string &name, double value, bool checkduplicate=false)
Method add double record.
double GetDoubleValue(unsigned indx)
std::vector< std::string > fDoubleRecords
names of double records
unsigned NumDoubles() const
std::string fDescriptor
descriptor
void AddLong(const std::string &name, int64_t value, bool checkduplicate=false)
Method add long record.
uint32_t fEventId
event number
std::string format(const char *fmt,...)
Definition: string.cxx:49
Support for MBS - standard GSI DAQ.
Definition: api.h:36