1 #include "daq/slc/nsm/NSMData.h"
3 #include "daq/slc/nsm/NSMCommunicator.h"
4 #include "daq/slc/nsm/NSMCallback.h"
5 #include "daq/slc/nsm/NSMHandlerException.h"
7 #include <daq/slc/system/Time.h>
9 #include <daq/slc/base/ConfigFile.h>
10 #include <daq/slc/base/StringUtil.h>
11 #include <daq/slc/base/Writer.h>
12 #include <daq/slc/base/Reader.h>
14 #include <nsm2/belle2nsm.h>
16 #include <nsm2/nsmlib2.h>
26 NSMData::NSMData(
const std::string& dataname,
27 const std::string& format,
int revision)
29 m_pdata(NULL), m_size(0), m_offset(0)
33 setRevision(revision);
38 m_pdata(NULL), m_size(0), m_offset(0)
43 NSMData::NSMData(
const NSMData& data)
46 m_allocated = data.m_allocated;
48 setFormat(data.getFormat());
49 setRevision(data.getRevision());
50 setIndex(data.getIndex());
51 setName(data.getName());
54 m_pdata = malloc(m_size);
55 memcpy(m_pdata, data.m_pdata, m_size);
57 if (data.m_pdata != NULL) m_pdata = data.m_pdata;
59 const DBField::NameList& name_v(data.getFieldNames());
60 for (DBField::NameList::const_iterator it = name_v.begin();
61 it != name_v.end(); it++) {
62 const std::string& name(*it);
65 if (pro.getType() == DBField::OBJECT) {
66 NSMDataList data_v(data.getObjects(name));
67 for (
size_t i = 0; i < data_v.size(); i++) {
69 cdata.m_pdata = (
void*)((
char*)m_pdata +
70 pro.getOffset() + cdata.m_size * i);
72 m_data_v_m.insert(NSMDataListMap::value_type(name, data_v));
80 if (m_allocated && m_pdata != NULL) {
88 AbstractDBObject::reset();
89 if (m_allocated && m_pdata != NULL) {
95 void NSMData::addValue(
const std::string& name,
const void* data,
96 DBField::Type type,
int length)
99 if (length == 0) length = 1;
100 int size = pro.getTypeSize() * length;
101 if (size <= 0)
return;
102 if (!hasField(name)) {
107 memcpy((
char*)m_pdata + pro.getOffset(), data, size);
111 void NSMData::setValue(
const std::string& name,
const void* data,
115 if (length == 0) length = 1;
116 int size = pro.getTypeSize() * length;
117 if (data != NULL && hasField(name) && size > 0) {
118 memcpy((
char*)m_pdata + pro.getOffset(), data, size);
124 if (m_pdata == NULL) {
125 b2nsm_context(com.getContext());
126 if (getenv(
"NSM2_INCDIR") == NULL) {
128 setenv(
"NSM2_INCDIR", file.get(
"nsm.data.incpath").c_str(), 0);
130 if ((m_pdata = b2nsm_openmem(getName().c_str(), getFormat().c_str(),
131 getRevision())) == NULL) {
133 nsmlib_strerror(com.getContext()), getName().c_str(), getFormat().c_str(),
143 if (m_pdata == NULL) {
144 b2nsm_context(com.getContext());
145 if (getenv(
"NSM2_INCDIR") == NULL) {
147 setenv(
"NSM2_INCDIR", file.get(
"nsm.data.incpath").c_str(), 0);
149 if ((m_pdata = b2nsm_allocmem(getName().c_str(), getFormat().c_str(),
150 getRevision(), interval)) == NULL) {
152 nsmlib_strerror(com.getContext())));
155 memset(m_pdata, 0, m_size);
168 void* NSMData::parse(
const char* incpath,
bool malloc_new)
170 #if NSM_PACKAGE_VERSION >= 1914
171 if (getenv(
"NSM2_INCDIR") == NULL) {
173 setenv(
"NSM2_INCDIR", file.get(
"nsm.data.incpath").c_str(), 0);
178 if ((ptr = (
NSMparse*)nsmlib_parsefile(getFormat().c_str(), getRevision(),
179 incpath, fmtstr, &revision)) == NULL) {
181 getFormat().c_str(), getRevision(), nsmlib_parseerr(NULL)));
183 if (getRevision() != revision && revision > 0) {
184 setRevision(revision);
188 parse(ptr, length, name_in);
189 if (m_size > 0 && malloc_new) {
191 return (m_pdata = malloc(m_size));
194 throw (
NSMHandlerException(
"too old nsmlib (nsmparse) : version = %d", NSM_PACKAGE_VERSION));
199 void NSMData::flush()
201 #if NSM_PACKAGE_VERSION >= 1914
202 m_tstamp =
Time().getSecond();
204 m_com->getCallback().set(
"nsmdata.tstamp", m_tstamp);
208 #if NSM_PACKAGE_VERSION >= 1914
212 while (ptr != NULL) {
214 if (length < 0) length = 0;
215 int type = ptr->type;
216 std::string name = ptr->name;
217 int offset = ptr->offset;
219 if (type ==
'l') type = DBField::LONG;
220 else if (type ==
'i') type = DBField::INT;
221 else if (type ==
's') type = DBField::SHORT;
222 else if (type ==
'c') type = DBField::CHAR;
223 else if (type ==
'L') type = DBField::LONG;
224 else if (type ==
'I') type = DBField::INT;
225 else if (type ==
'S') type = DBField::SHORT;
226 else if (type ==
'C') type = DBField::CHAR;
227 else if (type ==
'd') type = DBField::DOUBLE;
228 else if (type ==
'f') type = DBField::FLOAT;
229 else if (type ==
'(') {
230 NSMData data(getName(), getFormat() +
"." + name, getRevision());
231 char* pdata = ((
char*)m_pdata + offset);
232 data.m_pdata = pdata;
233 ptr = data.parse(ptr->next, length, name);
234 data.setFormat(getFormat() +
"." + name);
235 int len = (length == 0) ? 1 : length;
237 for (
int i = 0; i < len; i++) {
239 data.m_pdata = (
void*)(pdata + i * data.getSize());
240 data_v.push_back(data);
242 m_data_v_m.insert(NSMDataListMap::value_type(name, data_v));
243 type = DBField::OBJECT;
244 m_size += data.m_size * length;
245 }
else if (type ==
')') {
251 int len = (length == 0) ? 1 : length;
252 m_size += pro.getTypeSize() * len;
253 if (ptr == NULL)
break;
260 void* NSMData::getValue(
const std::string& name)
262 if (!hasValue(name))
return NULL;
263 char* data = (
char*)get();
264 return (data + getProperty(name).getOffset());
267 const void* NSMData::getValue(
const std::string& name)
270 if (!hasValue(name))
return NULL;
271 char* data = (
char*)get();
272 return (data + getProperty(name).getOffset());
275 void NSMData::readObject(
Reader& reader)
277 setName(reader.readString());
278 setFormat(reader.readString());
279 setRevision(reader.readInt());
280 int size = reader.readInt();
281 if (m_size > 0 && m_size < size) {
284 m_pdata = malloc(size);
287 int npars = reader.readInt();
288 for (
int n = 0; n < npars; n++) {
289 std::string name = reader.readString();
290 DBField::Type type = (DBField::Type)reader.readInt();
291 size_t length = reader.readInt();
292 size_t offset = reader.readInt();
294 void* buf = getValue(name);
295 if (length == 0) length = 1;
296 if (type == DBField::OBJECT) {
298 for (
size_t i = 0; i < length; i++) {
300 data.m_pdata = (
char*)getValue(name) + length * i;
301 reader.readObject(data);
302 data_v.push_back(data);
304 m_data_v_m.insert(NSMDataListMap::value_type(name, data_v));
306 for (
size_t i = 0; i < length; i++) {
308 case DBField::CHAR: ((
char*)buf)[i] = reader.readChar();
break;
309 case DBField::SHORT: ((int16*)buf)[i] = reader.readShort();
break;
310 case DBField::INT: ((int32*)buf)[i] = reader.readInt();
break;
311 case DBField::LONG: ((int64*)buf)[i] = reader.readLong();
break;
312 case DBField::FLOAT: ((
float*)buf)[i] = reader.readFloat();
break;
313 case DBField::DOUBLE: ((
double*)buf)[i] = reader.readDouble();
break;
321 void NSMData::writeObject(
Writer& writer)
const
323 writer.writeString(getName());
324 writer.writeString(getFormat());
325 writer.writeInt(getRevision());
326 writer.writeInt(getSize());
327 const DBField::NameList& name_v(getFieldNames());
328 writer.writeInt(name_v.size());
329 for (DBField::NameList::const_iterator it = name_v.begin();
330 it != name_v.end(); it++) {
331 const std::string& name(*it);
332 writer.writeString(name);
334 writer.writeInt(pro.getType());
335 writer.writeInt(pro.getLength());
336 writer.writeInt(pro.getOffset());
337 size_t length = pro.getLength();
338 const void* buf = getValue(name);
339 if (length == 0) length = 1;
340 if (pro.getType() == DBField::OBJECT) {
341 const NSMDataList& data_v(getObjects(name));
342 for (
size_t i = 0; i < length; i++) {
343 writer.writeObject(data_v[i]);
346 for (
size_t i = 0; i < length; i++) {
347 switch (pro.getType()) {
348 case DBField::CHAR: writer.writeChar(((
char*)buf)[i]);
break;
349 case DBField::SHORT: writer.writeShort(((int16*)buf)[i]);
break;
350 case DBField::INT: writer.writeInt(((int64*)buf)[i]);
break;
351 case DBField::LONG: writer.writeLong(((int32*)buf)[i]);
break;
352 case DBField::FLOAT: writer.writeFloat(((
float*)buf)[i]);
break;
353 case DBField::DOUBLE: writer.writeDouble(((
double*)buf)[i]);
break;
361 void NSMData::print(
const std::string& name_in)
const
364 search(map, name_in);
366 for (NameValueList::iterator it = map.begin();
367 it != map.end(); it++) {
368 if (it->name.size() > length) length = it->name.size();
370 for (NameValueList::iterator it = map.begin();
371 it != map.end(); it++) {
372 printf(StringUtil::form(
"%%-%ds : %%s\n", length).c_str(),
373 it->name.c_str(), it->value.c_str());
377 void NSMData::search(NSMData::NameValueList& map,
378 const std::string& name_in)
const
380 const DBField::NameList& name_v(getFieldNames());
381 for (DBField::NameList::const_iterator it = name_v.begin();
382 it != name_v.end(); it++) {
383 const std::string& name(*it);
385 size_t length = pro.getLength();
386 std::string name_out = name_in;
387 if (name_in.size() > 0) name_out +=
".";
391 if (pro.getType() == DBField::OBJECT) {
392 const NSMDataList& data_v(getObjects(name));
393 for (
size_t i = 0; i < length; i++) {
394 data_v[i].search(map, StringUtil::form(
"%s[%d]", name_out.c_str(), i));
397 const void* buf = getValue(name);
398 if (pro.getType() == DBField::CHAR) {
401 nv.value = (
char*)buf;
404 const char* name_c = name_out.c_str();
405 for (
int i = 0; i < (int)length; i++) {
406 std::string vname = StringUtil::form(
"%s[%d]", name_c, i);
408 switch (pro.getType()) {
410 val = StringUtil::form(
"%d", ((int16*)buf)[i]);
break;
412 val = StringUtil::form(
"%d", ((int32*)buf)[i]);
break;
414 val = StringUtil::form(
"%ld", ((int64*)buf)[i]);
break;
416 val = StringUtil::form(
"%f", ((
float*)buf)[i]);
break;
417 case DBField::DOUBLE:
418 val = StringUtil::form(
"%d", ((
double*)buf)[i]);
break;
429 if (pro.getType() == DBField::OBJECT) {
430 const NSMDataList& data_v(getObjects(name));
431 data_v[0].search(map, name_out);
435 nv.value = getValueText(name);
442 void NSMData::printPV(
const std::string& name_in)
const
444 const DBField::NameList& name_v(getFieldNames());
445 for (DBField::NameList::const_iterator it = name_v.begin();
446 it != name_v.end(); it++) {
447 const std::string& name(*it);
449 size_t length = pro.getLength();
450 std::string name_out = name_in;
451 if (name_in.size() > 0) name_out +=
":";
453 name_out += (getName() +
":") + (getFormat() +
":");
457 switch (pro.getType()) {
461 case DBField::LONG: pvtype =
"longin";
break;
463 case DBField::DOUBLE: pvtype =
"ai";
break;
467 if (pro.getType() == DBField::OBJECT) {
468 const NSMDataList& data_v(getObjects(name));
469 for (
size_t i = 0; i < length; i++) {
470 data_v[i].printPV(StringUtil::form(
"%s[%d]", name_out.c_str(), i));
473 for (
size_t i = 0; i < length; i++) {
474 printf(
"record(%s, \"B2_nsm:%s[%d]\")\n"
476 " field(SCAN, \".1 second\")\n"
477 " field(DTYP, \"nsm2_data_%s\")\n"
478 "}\n\n", pvtype.c_str(), name_out.c_str(), (
int)i, pvtype.c_str());
482 if (pro.getType() == DBField::OBJECT) {
483 const NSMDataList& data_v(getObjects(name));
484 data_v[0].print(name_out);
486 printf(
"record(%s, \"B2_nsm2:%s\")\n"
488 " field(SCAN, \".1 second\")\n"
489 " field(DTYP, \"nsm2_data_%s\")\n"
490 "}\n\n", pvtype.c_str(), name_out.c_str(), pvtype.c_str());
496 const void* NSMData::find(
const std::string& name_in, DBField::Type& type,
int& length)
const
499 std::string name_out = name_in;
500 if ((pos = name_in.find(
".")) != std::string::npos) {
501 StringList str = StringUtil::split(name_out,
'.');
502 StringList sstr = StringUtil::split(str[0],
'[');
503 const NSMDataList& data_v(getObjects(sstr[0]));
505 if (sstr.size() > 1) {
506 index = atoi(sstr[1].c_str());
508 name_out = name_in.substr(pos + 1);
509 return data_v[index].find(name_out, type, length);
512 if ((pos = name_out.find(
"[")) != std::string::npos) {
513 StringList str = StringUtil::split(name_out,
'[');
515 index = atoi(str[1].c_str());
517 if (!hasValue(name_out))
return NULL;
519 length = pro.getLength();
520 type = pro.getType();
521 const void* buf = getValue(name_out);
523 case DBField::CHAR:
return (((
const char*)buf) + index);
524 case DBField::SHORT:
return (((
const int16*)buf) + index);
525 case DBField::INT:
return (((
const int32*)buf) + index);
526 case DBField::LONG:
return (((
const int64*)buf) + index);
527 case DBField::FLOAT:
return (((
const float*)buf) + index);
528 case DBField::DOUBLE:
return (((
const double*)buf) + index);
529 default:
return NULL;
534 int NSMData::getNObjects(
const std::string& name)
const
536 NSMDataListMap::const_iterator it = m_data_v_m.find(name);
537 if (it != m_data_v_m.end())
return it->second.size();
541 const NSMData& NSMData::getObject(
const std::string& name,
int index)
const
543 NSMDataListMap::const_iterator it = m_data_v_m.find(name);
544 if (it != m_data_v_m.end())
return it->second[index];
545 else throw (std::out_of_range(StringUtil::form(
"%s:%d", __FILE__, __LINE__)));
548 NSMData& NSMData::getObject(
const std::string& name,
int index)
550 NSMDataListMap::iterator it = m_data_v_m.find(name);
551 if (it != m_data_v_m.end())
return it->second[index];
552 else throw (std::out_of_range(StringUtil::form(
"%s:%d", __FILE__, __LINE__)));
555 const NSMData::NSMDataList& NSMData::getObjects(
const std::string& name)
const
557 NSMDataListMap::const_iterator it = m_data_v_m.find(name);
558 if (it != m_data_v_m.end())
return it->second;
559 else throw (std::out_of_range(StringUtil::form(
"%s:%d", __FILE__, __LINE__)));
562 NSMData::NSMDataList& NSMData::getObjects(
const std::string& name)
564 NSMDataListMap::iterator it = m_data_v_m.find(name);
565 if (it != m_data_v_m.end())
return it->second;
566 else throw (std::out_of_range(StringUtil::form(
"%s:%d", __FILE__, __LINE__)));