HIPO  4.3.0
High Performance Output data format for experimental physics
event.cpp
Go to the documentation of this file.
1 //******************************************************************************
2 //* ██╗ ██╗██╗██████╗ ██████╗ ██╗ ██╗ ██████╗ *
3 //* ██║ ██║██║██╔══██╗██╔═══██╗ ██║ ██║ ██╔═████╗ *
4 //* ███████║██║██████╔╝██║ ██║ ███████║ ██║██╔██║ *
5 //* ██╔══██║██║██╔═══╝ ██║ ██║ ╚════██║ ████╔╝██║ *
6 //* ██║ ██║██║██║ ╚██████╔╝ ██║██╗╚██████╔╝ *
7 //* ╚═╝ ╚═╝╚═╝╚═╝ ╚═════╝ ╚═╝╚═╝ ╚═════╝ *
8 //************************ Jefferson National Lab (2017) ***********************
9 /*
10  * Copyright (c) 2017. Jefferson Lab (JLab). All rights reserved. Permission
11  * to use, copy, modify, and distribute this software and its documentation
12  * for educational, research, and not-for-profit purposes, without fee and
13  * without a signed licensing agreement.
14  *
15  * IN NO EVENT SHALL JLAB BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL
16  * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
17  * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JLAB HAS
18  * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19  *
20  * JLAB SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE. THE HIPO DATA FORMAT SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
23  * ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". JLAB HAS NO OBLIGATION TO
24  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25  *
26  * This software was developed under the United States Government license.
27  * For more information contact author at gavalian@jlab.org
28  * Department of Experimental Nuclear Physics, Jefferson Lab.
29  */
30  /*
31  * File: event.h
32  * Author: gavalian
33  *
34  * Created on April 12, 2017, 10:14 AM
35  */
36 
41 #include "event.h"
42 #include "constants.h"
43 
44 namespace hipo {
45 
46 
48  #if __cplusplus > 199711L
49  //printf("\n*****>>>>> compiled with c++11 support.\n");
50  #endif
51  // default allocation size for the event is 128 Kb
52  dataBuffer.resize(128*1024);
53  reset();
54  }
55 
56  event::event(int size){
57  dataBuffer.resize(size);
58  reset();
59  }
60 
61  event::~event()= default;
62 
65  }
66 
69  }
70 
71 
72  void event::getStructure(hipo::structure &str, int group, int item){
73  std::pair<int,int> index = getStructurePosition(group,item);
74  if(index.first>0){
75  str.init(&dataBuffer[index.first], index.second + BANK_STRUCTURE_SIZE);
76  str.notify();
77  } else {
78  str.initStructureBySize(group,item,1,0);
79  str.notify();
80  //printf("*** error *** : structure (%5d,%5d) does not exist\n", group,item);
81  }
82  }
83 
84  void event::getStructure4(hipo::structure &str, int group, int item){
85  std::pair<int,int> index = getStructurePosition4(group,item);
86  //printf("\n\n>>> GET STRUCTURE %d %d -> %d %d \n",group,item, index.first, index.second);
87  if(index.first>0){
88  str.init(&dataBuffer[index.first], index.second + BANK_STRUCTURE_SIZE);
89  str.notify();
90  } else {
91  str.initStructureBySize(group,item,1,0);
92  str.notify();
93  //printf("*** error *** : structure (%5d,%5d) does not exist\n", group,item);
94  }
95  }
96 
97  void event::getStructureNoCopy(const char *buffer, hipo::structure &str, int group, int item){
98  std::pair<int,int> index = getStructurePosition(buffer,group,item);
99  if(index.first>0){
100  str.initNoCopy(&buffer[index.first], index.second + BANK_STRUCTURE_SIZE);
101  str.notify();
102  } else {
103  str.initStructureBySize(group,item,1,0);
104  str.notify();
105  //printf("*** error *** : structure (%5d,%5d) does not exist\n", group,item);
106  }
107  }
108  void event::getStructure(const char *buffer, hipo::structure &str, int group, int item){
109  std::pair<int,int> index = getStructurePosition(buffer,group,item);
110  if(index.first>0){
111  str.init(&buffer[index.first], index.second + BANK_STRUCTURE_SIZE);
112  str.notify();
113  } else {
114  str.initStructureBySize(group,item,1,0);
115  str.notify();
116  //printf("*** error *** : structure (%5d,%5d) does not exist\n", group,item);
117  }
118  }
120 
121  }
122 
124  std::pair<int,int> index = getStructurePosition(&dataBuffer[0],
126  if(index.first>0){
127  int oSize = index.second + BANK_STRUCTURE_SIZE;
128  int sSize = bank.getSize() + BANK_STRUCTURE_SIZE;
129  if(oSize==sSize){
130  std::memcpy(&dataBuffer[index.first],&(bank.getStructureBuffer()[0]),sSize);
131  } else {
132  printf("[event::replace] error in replacing the bank %s\n",bank.getSchema().getName().c_str());
133  }
134  }
135  }
137  remove(str.getSchema().getGroup(),str.getSchema().getItem());
138  }
139 
140  void event::remove(int group, int item){
141  //int str_size = str.getStructureBufferSize();
142  //int data_size = str.getSize();
143  std::pair<int,int> index = getStructurePosition(&dataBuffer[0],group,item);
144  printf("-removing %d, %d\n",index.first,index.second);
145  if(index.first>0){
146  int eventSize = getSize();
147  int toCopy = eventSize - index.first - (index.second + BANK_STRUCTURE_SIZE);
148  int newSize = eventSize - (index.second + BANK_STRUCTURE_SIZE);
149  std::memmove(&dataBuffer[index.first],&dataBuffer[index.first+BANK_STRUCTURE_SIZE+index.second],toCopy);
150  printf(" first = %d, second = %d\n",index.first,index.second);
151  printf(" \t memcopy = %d, %d, ncopy %d , size = %d , new size = %d\n",
152  index.first, index.first+BANK_STRUCTURE_SIZE+index.second, toCopy, eventSize, newSize
153  );
154  uint32_t newSize_u = static_cast<uint32_t>(newSize);
155  std::memcpy(&dataBuffer[EH_SIZE_OFFSET], &newSize_u, sizeof(newSize_u));
156  }
157  //printf("size = %d, new size = %d, structure removed size = %d, position = %d, to copy = %d\n",
158  // eventSize, newSize, index.second +8, index.first, toCopy );
159  }
160 
162 
163  int str_size = str.getStructureBufferSize();
164  int data_size = str.getSize();
165  int evt_size = getSize();
166  int evt_capacity = dataBuffer.size();
167 
168  //if(dataBuffer.size()<= () ){
169  // dataBuffer.resize(size+1024);
170  //}
171  if(data_size>0){
172  //printf(" writing structure %d/%d - size %d, data size %d\n",str.getGroup(),str.getItem(),str_size,data_size);
173  if((evt_size + str_size)<evt_capacity){
174  memcpy(&dataBuffer[evt_size], &str.getStructureBuffer()[0],str_size);
175  uint32_t new_size = static_cast<uint32_t>(evt_size + str_size);
176  std::memcpy(&dataBuffer[EH_SIZE_OFFSET], &new_size, sizeof(new_size));
177  } else {
178  printf("event::add : error adding structure with size = %5d (capacity = %5d, size = %5d)\n",
179  str_size,evt_capacity, evt_size);
180  }
181  }
182  }
183 
185 
186  int _n_data_length = _n.dataLength();
187  if(_n_data_length==0) return;
188 
189  int ev_size = getSize();
190  int _n_size = _n.size() + BANK_STRUCTURE_SIZE;
191  int ev_capacity = dataBuffer.size();
192  if((ev_size + _n_size)<ev_capacity){
193  memcpy(&dataBuffer[ev_size], _n.pointer(),_n_size);
194  uint32_t new_size = static_cast<uint32_t>(ev_size + _n_size);
195  std::memcpy(&dataBuffer[EH_SIZE_OFFSET], &new_size, sizeof(new_size));
196  } else {
197  printf("event::add : error adding structure with size = %5d (capacity = %5d, size = %5d)\n",
198  _n_size,ev_capacity, ev_size);
199  }
200  }
202  add(node);
203  }
204 
205  void event::read(hipo::node &node, int group, int item){
206 
207  }
208 
209 void event::get(hipo::node &_n, int group, int item){
210  std::pair<int,int> index = getStructurePosition(group,item);
211  printf(" found the structure : %d/%d - properties = %d, %d\n",group,item,index.first,index.second);
212  if(index.first>0){
213  _n.init(&dataBuffer[index.first], index.second + BANK_STRUCTURE_SIZE);
214  printf("calling notify.....\n");
215  _n.notify();
216  } else {
217  _n.initEmpty();
218  _n.notify();
219  //printf("*** error *** : structure (%5d,%5d) does not exist\n", group,item);
220  }
221  }
222 
224  uint32_t eventTag_u;
225  std::memcpy(&eventTag_u, &dataBuffer[EH_TAG_OFFSET], sizeof(eventTag_u));
226  return static_cast<int>(eventTag_u);
227  }
228 
229  void event::setTag(int tag){
230  uint32_t tag_u = static_cast<uint32_t>(tag);
231  std::memcpy(&dataBuffer[EH_TAG_OFFSET], &tag_u, sizeof(tag_u));
232  }
233 
234  void event::init(std::vector<char> &buffer){
235  dataBuffer.resize(buffer.size());
236  std::memcpy(&dataBuffer[0],&buffer[0],buffer.size());
237  }
238 
239  std::pair<int,int> event::getStructurePosition(const char *buffer, int group, int item){
240  int position = EVENT_HEADER_SIZE;
241  uint32_t eventSize_u;
242  std::memcpy(&eventSize_u, &buffer[EH_SIZE_OFFSET], sizeof(eventSize_u));
243  int eventSize = static_cast<int>(eventSize_u);
244  while(position+BANK_STRUCTURE_SIZE<eventSize){
245  uint16_t gid;
246  std::memcpy(&gid, &buffer[position], sizeof(gid));
247  uint8_t iid = static_cast<uint8_t>(buffer[position+2]);
248  int length;
249  std::memcpy(&length, &buffer[position+4], sizeof(length));
250  if(gid==group&&iid==item) return std::make_pair(position,length);
251  position += (length + BANK_STRUCTURE_SIZE);
252  }
253  return std::make_pair(-1,0);
254  }
255 
256  std::pair<int,int> event::getStructurePosition(int group, int item){
257  int position = EVENT_HEADER_SIZE;
258  uint32_t eventSize_u;
259  std::memcpy(&eventSize_u, &dataBuffer[EH_SIZE_OFFSET], sizeof(eventSize_u));
260  int eventSize = static_cast<int>(eventSize_u);
261  while(position+BANK_STRUCTURE_SIZE<eventSize){
262  uint16_t gid;
263  std::memcpy(&gid, &dataBuffer[position], sizeof(gid));
264  uint8_t iid = static_cast<uint8_t>(dataBuffer[position+2]);
265  int word;
266  std::memcpy(&word, &dataBuffer[position+4], sizeof(word));
267  int length = word&STRUCT_SIZE_MASK;
268  if(gid==group&&iid==item) return std::make_pair(position,length);
269  position += (length + BANK_STRUCTURE_SIZE);
270  }
271  return std::make_pair(-1,0);
272  }
273 
274  std::pair<int,int> event::getStructurePosition4(int group, int item){
275  int position = EVENT_HEADER_SIZE;
276  uint32_t eventSize_u;
277  std::memcpy(&eventSize_u, &dataBuffer[EH_SIZE_OFFSET], sizeof(eventSize_u));
278  int eventSize = static_cast<int>(eventSize_u);
279  while(position+BANK_STRUCTURE_SIZE<eventSize){
280  uint16_t gid;
281  std::memcpy(&gid, &dataBuffer[position], sizeof(gid));
282  uint8_t iid = static_cast<uint8_t>(dataBuffer[position+2]);
283  int length;
284  std::memcpy(&length, &dataBuffer[position+4], sizeof(length));
285  if(gid==group&&iid==item) return std::make_pair(position,length);
286  position += (length + BANK_STRUCTURE_SIZE);
287  }
288  return std::make_pair(-1,0);
289  }
290 /*
291  std::pair<int,int> event::getStructurePosition(const char *buffer, int group, int item){
292  int position = 16;
293  int eventSize = *(reinterpret_cast<uint32_t*>(&buffer[4]));
294  while(position+8<eventSize){
295  uint16_t gid = *(reinterpret_cast<uint16_t*>(&buffer[position]));
296  uint8_t iid = *(reinterpret_cast<uint8_t*>(&buffer[position+2]));
297  uint8_t type = *(reinterpret_cast<uint8_t*>(&buffer[position+3]));
298  int length = *(reinterpret_cast<int*>(&buffer[position+4]));
299  //printf("group = %4d , item = %4d\n",(unsigned int) gid, (unsigned int) iid);
300  if(gid==group&&iid==item) return std::make_pair(position,length);
301  position += (length + 8);
302  }
303  return std::make_pair(-1,0);
304  }
305 */
306  void event::init(const char *buffer, int size){
307  if(dataBuffer.size()<=size){
308  dataBuffer.resize(size+1024);
309  }
310  std::memcpy(&dataBuffer[0],buffer,size);
311  uint32_t size_u = static_cast<uint32_t>(size);
312  std::memcpy(&dataBuffer[EH_SIZE_OFFSET], &size_u, sizeof(size_u));
313  }
314 
316  uint32_t size_u;
317  std::memcpy(&size_u, &dataBuffer[EH_SIZE_OFFSET], sizeof(size_u));
318  return static_cast<int>(size_u);
319  }
320 
321  void event::reset(){
322  dataBuffer[0] = 'E'; dataBuffer[1] = 'V';
323  dataBuffer[2] = 'N'; dataBuffer[3] = 'T';
324  uint32_t val;
325  val = EVENT_HEADER_SIZE; std::memcpy(&dataBuffer[EH_SIZE_OFFSET], &val, sizeof(val));
326  val = 0; std::memcpy(&dataBuffer[EH_TAG_OFFSET], &val, sizeof(val));
327  val = 0; std::memcpy(&dataBuffer[EH_RESERVED_OFFSET], &val, sizeof(val));
328  }
329  std::vector<char> &event::getEventBuffer(){ return dataBuffer;}
330  /*
331  template<class T> node<T> event::getNode(){
332  node<T> en;
333  en.setLength(4);
334  en.setAddress(NULL);
335  } */
336  void event::show(){
337  printf(" EVENT SIZE = %d\n",getSize());
338  int position = EVENT_HEADER_SIZE;
339  uint32_t eventSize_u;
340  std::memcpy(&eventSize_u, &dataBuffer[EH_SIZE_OFFSET], sizeof(eventSize_u));
341  int eventSize = static_cast<int>(eventSize_u);
342  while(position+BANK_STRUCTURE_SIZE<eventSize){
343  uint16_t gid;
344  std::memcpy(&gid, &dataBuffer[position], sizeof(gid));
345  uint8_t iid = static_cast<uint8_t>(dataBuffer[position+2]);
346  uint8_t type = static_cast<uint8_t>(dataBuffer[position+3]);
347  int sizeWord;
348  std::memcpy(&sizeWord, &dataBuffer[position+4], sizeof(sizeWord));
349  int length = sizeWord&STRUCT_SIZE_MASK;
350  int format = (sizeWord>>STRUCT_FORMAT_SHIFT)&STRUCT_FORMAT_BYTE;
351  //printf("group = %4d , item = %4d\n",(unsigned int) gid, (unsigned int) iid);
352  //if(gid==group&&iid==item) return std::make_pair(position,length);
353  printf("%12s node [%9d %4d] type = %12d, fotmat size = %3d , length = %12d\n"," ",gid,iid,type,format,length);
354  position += (length + BANK_STRUCTURE_SIZE);
355  }
356  }
357 
358 
359 
360  void event::get(const char *buffer, hipo::node &_n, int group, int item){
361  std::pair<int,int> index = getStructurePosition(buffer,group,item);
362  if(index.first>0){
363  _n.init(&buffer[index.first], index.second + BANK_STRUCTURE_SIZE);
364  //_n.notify();
365  } else {
366  _n.initEmpty();
367  _n.notify();
368  //printf("*** error *** : structure (%5d,%5d) does not exist\n", group,item);
369  }
370  }
371 }
Represents a HIPO bank, a tabular data structure with rows and typed columns.
Definition: bank.h:352
schema & getSchema()
Definition: bank.h:443
std::vector< char > & getEventBuffer()
Definition: event.cpp:329
static void getStructureNoCopy(const char *buffer, hipo::structure &str, int group, int item)
Extract a structure from a raw buffer without copying the data.
Definition: event.cpp:97
event()
Default constructor. Creates an empty event.
Definition: event.cpp:47
void write(hipo::node &node)
Write a node into this event.
Definition: event.cpp:201
void addStructure(hipo::structure &str)
Add a structure to the event.
Definition: event.cpp:161
void get(hipo::node &_n, int group, int item)
Get a node from the event by group and item identifiers.
Definition: event.cpp:209
void override(hipo::structure &str)
Override an existing structure in the event.
Definition: event.cpp:119
void setTag(int tag)
Definition: event.cpp:229
void read(hipo::bank &b)
Read a bank from this event (alias for getStructure).
Definition: event.cpp:67
void getStructure(hipo::structure &str, int group, int item)
Extract a structure from the event by group and item identifiers.
Definition: event.cpp:72
std::pair< int, int > getStructurePosition(int group, int item)
Find the position and length of a structure in the event buffer.
Definition: event.cpp:256
void init(std::vector< char > &buffer)
Initialize the event from an existing buffer.
Definition: event.cpp:234
void show()
Display the event contents to standard output.
Definition: event.cpp:336
void remove(hipo::bank &str)
Remove a bank from the event.
Definition: event.cpp:136
std::pair< int, int > getStructurePosition4(int group, int item)
Find the position and length of a structure using 4-byte header format.
Definition: event.cpp:274
int getSize()
Definition: event.cpp:315
int getTag()
Definition: event.cpp:223
void reset()
Reset the event to an empty state.
Definition: event.cpp:321
void add(hipo::node &_n)
Add a node to the event.
Definition: event.cpp:184
virtual ~event()
Destructor.
void replace(hipo::bank &bank)
Replace an existing bank in the event.
Definition: event.cpp:123
void getStructure4(hipo::structure &str, int group, int item)
Extract a structure using 4-byte header format.
Definition: event.cpp:84
Low-level node representing a tagged data element in a HIPO structure.
Definition: node.h:68
int size() const noexcept
Definition: node.h:138
int dataLength() const noexcept
Definition: node.h:183
void initEmpty()
Initialize the node to an empty state.
Definition: node.cpp:79
const char * pointer()
Definition: node.h:219
void init(const char *b, int length)
Initialize the node by copying raw bytes into the internal buffer.
Definition: node.h:91
virtual void notify()
Callback invoked when the node content is updated (e.g., after deserialization).
Definition: node.h:317
std::string getName() const
Get the schema name.
Definition: dictionary.h:125
int getItem()
Get the item identifier.
Definition: dictionary.h:131
int getGroup()
Get the group identifier.
Definition: dictionary.h:128
Low-level data structure representing a HIPO structure.
Definition: bank.h:64
void initStructureBySize(int __group, int __item, int __type, int __size)
Initialize the structure buffer with the given group, item, type, and data size.
Definition: bank.cpp:67
int getSize() const noexcept
Definition: bank.h:106
int getStructureBufferSize()
Definition: bank.h:79
void initNoCopy(const char *buffer, int size)
Definition: bank.cpp:112
std::vector< char > & getStructureBuffer()
Definition: bank.h:77
virtual void notify()
Called when the structure is updated (e.g., after reading an event).
Definition: bank.h:236
void init(const char *buffer, int size)
Definition: bank.cpp:116
HIPO event container and manipulation interface.
Definition: bank.cpp:47
constexpr uint32_t STRUCT_FORMAT_BYTE
Definition: constants.h:129
constexpr int BANK_STRUCTURE_SIZE
Definition: constants.h:17
constexpr int EH_SIZE_OFFSET
Definition: constants.h:49
constexpr int STRUCT_FORMAT_SHIFT
Definition: constants.h:128
constexpr int EVENT_HEADER_SIZE
Definition: constants.h:16
constexpr int EH_TAG_OFFSET
Definition: constants.h:50
constexpr int EH_RESERVED_OFFSET
Definition: constants.h:51
constexpr uint32_t STRUCT_SIZE_MASK
Definition: constants.h:126