PAASS
Software suite to Acquire and Analyze Data from Pixie16
hribf_buffers.cpp
Go to the documentation of this file.
1 
22 #include <sstream>
23 #include <iostream>
24 #include <string.h>
25 #include <unistd.h>
26 #include <iomanip>
27 #include <vector>
28 
29 #include "hribf_buffers.h"
30 #include "poll2_socket.h"
31 
32 #define SMALLEST_CHUNK_SIZE 20
33 #define NO_HEADER_SIZE 8192
34 #define OPTIMAL_CHUNK_SIZE 8187
35 
36 #define HEAD 1145128264
37 #define DATA 1096040772
38 #define SCAL 1279345491
39 #define DEAD 1145128260
40 #define DIR 542263620
41 #define PAC 541278544
42 #define ENDFILE 541478725
43 #define ENDBUFF 0xFFFFFFFF
44 
45 #define LDF_DATA_LENGTH 8193 // Maximum length of an ldf style DATA buffer.
46 
47 const unsigned int end_spill_size = 20;
48 const unsigned int pacman_word1 = 2;
49 const unsigned int pacman_word2 = 9999;
50 
52 void set_char_array(const std::string &input_, char *arr_, const unsigned int &size_){
53  size_t size_to_copy = size_;
54  if(size_ > input_.size()){ size_to_copy = input_.size(); }
55  for(unsigned int i = 0; i < size_; i++){
56  if(i < size_to_copy){ arr_[i] = input_[i]; }
57  else{ arr_[i] = ' '; }
58  }
59  arr_[size_] = '\0';
60 }
61 
63 bool is_hribf_buffer(const unsigned int &input_){
64  return (input_==HEAD || input_==DATA || input_==SCAL || input_==DEAD || input_==DIR || input_==PAC || input_==ENDFILE);
65 }
66 
68 BufferType::BufferType(unsigned int bufftype_, unsigned int buffsize_, unsigned int buffend_/*=0xFFFFFFFF*/){
69  bufftype = bufftype_;
70  buffsize = buffsize_;
71  buffend = buffend_;
72  zero = 0;
73  debug_mode = false;
74  Reset();
75 }
76 
78 bool BufferType::Write(std::ofstream *file_){
79  return false;
80 }
81 
83 bool BufferType::Read(std::ifstream *file_){
84  return false;
85 }
86 
88 bool BufferType::ReadHeader(std::ifstream *file_){
89  unsigned int check_bufftype;
90  file_->read((char*)&check_bufftype, 4);
91  if(check_bufftype != bufftype){ // Not a valid buffer
92  return false;
93  }
94  return true;
95 }
96 
98 PLD_header::PLD_header() : BufferType(HEAD, 0){ // 0x44414548 "HEAD"
99  this->Reset();
100 }
101 
104 }
105 
108  unsigned int buffer_len = 100;
109  buffer_len += strlen(run_title);
110  while(buffer_len % 4 != 0){ buffer_len++; }
111  return buffer_len;
112 }
113 
116  time (&runStartTime);
117 
118  char *date_holder = ctime(&runStartTime);
119  set_char_array(std::string(date_holder), start_date, 24); // Strip the trailing newline character
120 }
121 
124  time (&runStopTime);
125 
126  // Calculate the time difference between stop and start.
127  run_time = (float)difftime(runStopTime, runStartTime);
128 
129  char *date_holder = ctime(&runStopTime);
130  set_char_array(std::string(date_holder), end_date, 24); // Strip the trailing newline character
131 }
132 
134 void PLD_header::SetFacility(std::string input_){
135  set_char_array(input_, facility, 16);
136 }
137 
139 void PLD_header::SetTitle(std::string input_){
140  if(run_title){ delete[] run_title; }
141  run_title = new char[input_.size()+1];
142  for(unsigned int i = 0; i < input_.size(); i++){
143  run_title[i] = input_[i];
144  }
145  run_title[input_.size()] = '\0';
146 }
147 
149 bool PLD_header::Write(std::ofstream *file_){
150  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
151 
152  unsigned int len_of_title = strlen(run_title);
153  unsigned int padding_bytes = 0;
154  while((len_of_title + padding_bytes) % 4 != 0){
155  padding_bytes++;
156  }
157  unsigned int total_title_len = len_of_title + padding_bytes;
158 
159  if(debug_mode){ std::cout << "debug: writing " << 100 + total_title_len << " byte HEAD buffer\n"; }
160 
161  file_->write((char*)&bufftype, 4);
162  file_->write((char*)&run_num, 4);
163  file_->write((char*)&max_spill_size, 4);
164  file_->write((char*)&run_time, 4);
165  file_->write(format, 16);
166  file_->write(facility, 16);
167  file_->write(start_date, 24);
168  file_->write(end_date, 24);
169  file_->write((char*)&total_title_len, 4);
170  file_->write(run_title, len_of_title);
171 
172  char padding = ' ';
173  for(unsigned int i = 0; i < padding_bytes; i++){
174  file_->write(&padding, 1);
175  }
176 
177  file_->write((char*)&buffend, 4); // Close the buffer
178 
179  return true;
180 }
181 
183 bool PLD_header::Read(std::ifstream *file_){
184  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
185 
186  unsigned int check_bufftype;
187  file_->read((char*)&check_bufftype, 4);
188  if(check_bufftype != bufftype){ // Not a valid HEAD buffer
189  if(debug_mode){ std::cout << "debug: not a valid HEAD buffer\n"; }
190  file_->seekg(-4, file_->cur); // Rewind to the beginning of this buffer
191  return false;
192  }
193 
194  unsigned int end_buff_check;
195  unsigned int len_of_title;
196  file_->read((char*)&run_num, 4);
197  file_->read((char*)&max_spill_size, 4);
198  file_->read((char*)&run_time, 4);
199  file_->read(format, 16); format[16] = '\0';
200  file_->read(facility, 16); facility[16] = '\0';
201  file_->read(start_date, 24); start_date[24] = '\0';
202  file_->read(end_date, 24); end_date[24] = '\0';
203  file_->read((char*)&len_of_title, 4);
204 
205  if(run_title){ delete[] run_title; }
206  run_title = new char[len_of_title+1];
207 
208  file_->read(run_title, len_of_title); run_title[len_of_title] = '\0';
209  file_->read((char*)&end_buff_check, 4);
210 
211  if(end_buff_check != buffend){ // Buffer was not terminated properly
212  if(debug_mode){ std::cout << "debug: buffer not terminated properly\n"; }
213  return false;
214  }
215 
216  return true;
217 }
218 
221  set_char_array("U OF TENNESSEE ", facility, 16);
222  set_char_array("PIXIE LIST DATA ", format, 16);
223  set_char_array("Mon Jan 01 00:00:00 2000", start_date, 24);
224  set_char_array("Mon Jan 01 00:00:00 2000", end_date, 24);
225  max_spill_size = 0;
226  run_title = NULL;
227  run_time = 0.0;
228  run_num = 0;
229 }
230 
233  std::cout << " 'HEAD' buffer-\n";
234  std::cout << " Facility: " << std::string(facility) << "\n";
235  std::cout << " Format: " << std::string(format) << "\n";
236  std::cout << " Start: " << std::string(start_date) << "\n";
237  std::cout << " Stop: " << std::string(end_date) << "\n";
238  std::cout << " Title: " << std::string(run_title) << "\n";
239  std::cout << " Run number: " << run_num << "\n";
240  std::cout << " Max spill: " << max_spill_size << " words\n";
241  std::cout << " ACQ time: " << run_time << " seconds\n";
242 }
243 
245 void PLD_header::PrintDelimited(const char &delimiter_/*='\t'*/){
246  std::cout << std::string(facility) << delimiter_;
247  std::cout << std::string(format) << delimiter_;
248  std::cout << std::string(start_date) << delimiter_;
249  std::cout << std::string(end_date) << delimiter_;
250  std::cout << std::string(run_title) << delimiter_;
251  std::cout << run_num << delimiter_;
252  std::cout << max_spill_size << delimiter_;
253  std::cout << run_time;
254 }
255 
257 PLD_data::PLD_data() : BufferType(DATA, 0){ // 0x41544144 "DATA"
258  this->Reset();
259 }
260 
262 bool PLD_data::Write(std::ofstream *file_, char *data_, unsigned int nWords_){
263  if(!file_ || !file_->is_open() || !file_->good() || nWords_ == 0){ return false; }
264 
265  if(debug_mode){ std::cout << "debug: writing spill of " << nWords_ << " words\n"; }
266 
267  file_->write((char*)&bufftype, 4);
268  file_->write((char*)&nWords_, 4);
269  file_->write(data_, 4*nWords_);
270 
271  file_->write((char*)&buffend, 4); // Close the buffer
272 
273  return true;
274 }
275 
277 bool PLD_data::Read(std::ifstream *file_, char *data_, unsigned int &nBytes, unsigned int max_bytes_, bool dry_run_mode/*=false*/){
278  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
279 
280  unsigned int check_bufftype;
281  file_->read((char*)&check_bufftype, 4);
282  if(check_bufftype != bufftype){ // Not a valid DATA buffer
283  if(debug_mode){ std::cout << "debug: not a valid DATA buffer\n"; }
284 
285  unsigned int countw = 0;
286  while(check_bufftype != bufftype){
287  file_->read((char*)&check_bufftype, 4);
288  if(file_->eof()){
289  if(debug_mode){ std::cout << "debug: encountered physical end-of-file before start of spill!\n"; }
290  return false;
291  }
292  countw++;
293  }
294 
295  if(debug_mode){ std::cout << "debug: read an extra " << countw << " words to get to first DATA buffer!\n"; }
296  }
297 
298  file_->read((char*)&nBytes, 4);
299  nBytes = nBytes * 4;
300 
301  if(debug_mode){ std::cout << "debug: reading spill of " << nBytes << " bytes\n"; }
302 
303  if(nBytes > max_bytes_){
304  if(debug_mode){ std::cout << "debug: spill size is greater than size of data array!\n"; }
305  return false;
306  }
307 
308  unsigned int end_buff_check;
309  if(!dry_run_mode){ file_->read(data_, nBytes); }
310  else{ file_->seekg(nBytes, std::ios::cur); }
311  file_->read((char*)&end_buff_check, 4);
312 
313  if(end_buff_check != buffend){ // Buffer was not terminated properly
314  if(debug_mode){ std::cout << "debug: buffer not terminated properly\n"; }
315  return false;
316  }
317 
318  return true;
319 }
320 
323  this->Reset();
324 }
325 
330 bool DIR_buffer::Write(std::ofstream *file_){
331  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
332 
333  if(debug_mode){ std::cout << "debug: writing " << ACTUAL_BUFF_SIZE*4 << " byte DIR buffer\n"; }
334 
335  file_->write((char*)&bufftype, 4);
336  file_->write((char*)&buffsize, 4);
337  file_->write((char*)&total_buff_size, 4);
338  file_->write((char*)&zero, 4); // Will be overwritten later
339  file_->write((char*)unknown, 8);
340  file_->write((char*)&run_num, 4);
341  file_->write((char*)&unknown[2], 4);
342 
343  // Fill the rest of the buffer with 0
344  for(unsigned int i = 0; i < NO_HEADER_SIZE-6; i++){
345  file_->write((char*)&zero, 4);
346  }
347 
348  return true;
349 }
350 
352 bool DIR_buffer::Read(std::ifstream *file_){
353  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
354 
355  unsigned int check_bufftype, check_buffsize;
356  file_->read((char*)&check_bufftype, 4);
357  file_->read((char*)&check_buffsize, 4);
358  if(check_bufftype != bufftype || check_buffsize != buffsize){ // Not a valid DIR buffer
359  if(debug_mode){ std::cout << "debug: not a valid DIR buffer\n"; }
360  file_->seekg(-8, file_->cur); // Rewind to the beginning of this buffer
361  return false;
362  }
363 
364  file_->read((char*)&total_buff_size, 4);
365  file_->read((char*)&total_buff_size, 4);
366  file_->read((char*)unknown, 8);
367  file_->read((char*)&run_num, 4);
368  file_->seekg((buffsize*4 - 20), file_->cur); // Skip the rest of the buffer
369 
370  return true;
371 }
372 
376  run_num = 0;
377  unknown[0] = 0;
378  unknown[1] = 1;
379  unknown[2] = 2;
380 }
381 
384  std::cout << " 'DIR ' buffer-\n";
385  std::cout << " Run number: " << run_num << "\n";
386  std::cout << " Number buffers: " << total_buff_size << "\n";
387 }
388 
390 void DIR_buffer::PrintDelimited(const char &delimiter_/*='\t'*/){
391  std::cout << run_num << delimiter_;
392  std::cout << total_buff_size;
393 }
394 
396 HEAD_buffer::HEAD_buffer() : BufferType(HEAD, 64){ // 0x44414548 "HEAD"
397  this->Reset();
398 }
399 
402  struct tm * local;
403  time_t temp_time;
404  time(&temp_time);
405  local = localtime(&temp_time);
406 
407  int month = local->tm_mon+1;
408  int day = local->tm_mday;
409  int year = local->tm_year;
410  int hour = local->tm_hour;
411  int minute = local->tm_min;
412  //int second = local->tm_sec;
413 
414  std::stringstream stream;
415  (month<10) ? stream << "0" << month << "/" : stream << month << "/";
416  (day<10) ? stream << "0" << day << "/" : stream << day << "/";
417  (year<110) ? stream << "0" << year-100 << " " : stream << year-100 << " ";
418 
419  (hour<10) ? stream << "0" << hour << ":" : stream << hour << ":";
420  (minute<10) ? stream << "0" << minute << " " : stream << minute << " ";
421  //stream << ":"
422  //(second<10) ? stream << "0" << second : stream << second;
423 
424  std::string dtime_str = stream.str();
425  if(dtime_str.size() > 16){ return false; }
426  for(unsigned int i = 0; i < 16; i++){
427  if(i >= dtime_str.size()){ date[i] = ' '; }
428  else{ date[i] = dtime_str[i]; }
429  }
430  return true;
431 }
432 
434 bool HEAD_buffer::SetTitle(std::string input_){
435  for(unsigned int i = 0; i < 80; i++){
436  if(i >= input_.size()){ run_title[i] = ' '; }
437  else{ run_title[i] = input_[i]; }
438  }
439  return true;
440 }
441 
446 bool HEAD_buffer::Write(std::ofstream *file_){
447  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
448 
449  if(debug_mode){ std::cout << "debug: writing " << ACTUAL_BUFF_SIZE*4 << " byte HEAD buffer\n"; }
450 
451  // write 140 bytes (35 words)
452  file_->write((char*)&bufftype, 4);
453  file_->write((char*)&buffsize, 4);
454  file_->write(facility, 8);
455  file_->write(format, 8);
456  file_->write(type, 16);
457  file_->write(date, 16);
458  file_->write(run_title, 80);
459  file_->write((char*)&run_num, 4);
460 
461  // Get the buffer length up to 256 bytes (add 29 words)
462  char temp[116];
463  for(unsigned int i = 0; i < 116; i++){ temp[i] = 0x0; }
464  file_->write(temp, 116);
465 
466  // Fill the rest of the buffer with 0xFFFFFFFF (end of buffer)
467  for(unsigned int i = 0; i < ACTUAL_BUFF_SIZE-64; i++){
468  file_->write((char*)&buffend, 4);
469  }
470 
471  return true;
472 }
473 
475 bool HEAD_buffer::Read(std::ifstream *file_){
476  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
477 
478  unsigned int check_bufftype, check_buffsize;
479  file_->read((char*)&check_bufftype, 4);
480  file_->read((char*)&check_buffsize, 4);
481  if(check_bufftype != bufftype || check_buffsize != buffsize){ // Not a valid HEAD buffer
482  if(debug_mode){ std::cout << "debug: not a valid HEAD buffer\n"; }
483  file_->seekg(-8, file_->cur); // Rewind to the beginning of this buffer
484  return false;
485  }
486 
487  file_->read(facility, 8); facility[8] = '\0';
488  file_->read(format, 8); format[8] = '\0';
489  file_->read(type, 16); type[16] = '\0';
490  file_->read(date, 16); date[16] = '\0';
491  file_->read(run_title, 80); run_title[80] = '\0';
492  file_->read((char*)&run_num, 4);
493  file_->seekg((ACTUAL_BUFF_SIZE*4 - 140), file_->cur); // Skip the rest of the buffer
494 
495  return true;
496 }
497 
500  set_char_array("HHIRF ", facility, 8);
501  set_char_array("L003 ", format, 8);
502  set_char_array("LIST DATA ", type, 16);
503  set_char_array("01/01/01 00:00 ", date, 16);
504  run_num = 0;
505 }
506 
509  std::cout << " 'HEAD' buffer-\n";
510  std::cout << " Facility: " << std::string(facility) << "\n";
511  std::cout << " Format: " << std::string(format) << "\n";
512  std::cout << " Type: " << std::string(type) << "\n";
513  std::cout << " Date: " << std::string(date) << "\n";
514  std::cout << " Title: " << std::string(run_title) << "\n";
515  std::cout << " Run number: " << run_num << "\n";
516 }
517 
519 void HEAD_buffer::PrintDelimited(const char &delimiter_/*='\t'*/){
520  std::cout << std::string(facility) << delimiter_;
521  std::cout << std::string(format) << delimiter_;
522  std::cout << std::string(type) << delimiter_;
523  std::cout << std::string(date) << delimiter_;
524  std::cout << std::string(run_title) << delimiter_;
525  std::cout << run_num;
526 }
527 
529 bool DATA_buffer::open_(std::ofstream *file_){
530  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
531 
532  if(debug_mode){ std::cout << "debug: writing 2 word DATA header\n"; }
533  file_->write((char*)&bufftype, 4); // write buffer header type
534  file_->write((char*)&buffsize, 4); // write buffer size
535  buff_pos = 2;
536 
537  return true;
538 }
539 
541 bool DATA_buffer::read_next_buffer(std::ifstream *f_, bool force_/*=false*/){
542  if(!f_ || !f_->good() || f_->eof()){ return false; }
543 
544  if(bcount == 0){
545  f_->read((char *)buffer1, ACTUAL_BUFF_SIZE*4);
546  }
547  else if(buff_pos + 3 <= ACTUAL_BUFF_SIZE-1 && !force_){
548  // Don't need to scan a new buffer yet. There are still
549  // words remaining in the one currently in memory.
550 
551  // Skip end of event delimiters.
552  while(curr_buffer[buff_pos] == ENDBUFF && buff_pos < ACTUAL_BUFF_SIZE-1){
553  buff_pos++;
554  }
555 
556  // If we have more good words in this buffer, keep reading it.
557  if(buff_pos + 3 < ACTUAL_BUFF_SIZE-1){
558  return true;
559  }
560  }
561 
562  // Read the buffer into memory.
563  if(bcount % 2 == 0){
564  f_->read((char *)buffer2, ACTUAL_BUFF_SIZE*4);
565  curr_buffer = buffer1;
566  next_buffer = buffer2;
567  }
568  else{
569  f_->read((char *)buffer1, ACTUAL_BUFF_SIZE*4);
570  curr_buffer = buffer2;
571  next_buffer = buffer1;
572  }
573 
574  // Reset the buffer index.
575  buff_pos = 0;
576 
577  // Increment the number of buffers read.
578  bcount++;
579 
580  // Read the buffer header and length.
581  buff_head = curr_buffer[buff_pos++];
582  buff_size = curr_buffer[buff_pos++];
583 
584  if(!f_->good()){ return false; }
585  else if(f_->eof()){ retval = 2; }
586 
587  return true;
588 }
589 
592  bcount = 0;
593  good_chunks = 0;
594  missing_chunks = 0;
595  buff_pos = 0;
596  this->Reset();
597 }
598 
600 bool DATA_buffer::Close(std::ofstream *file_){
601  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
602 
604  if(debug_mode)
605  std::cout << "debug: closing buffer with " << ACTUAL_BUFF_SIZE - buff_pos << " 0xFFFFFFFF words\n";
606  for(unsigned int i = buff_pos; i < ACTUAL_BUFF_SIZE; i++){
607  file_->write((char*)&buffend, 4);
608  }
609  }
610  buff_pos = 0;
611 
612  return true;
613 }
614 
616 bool DATA_buffer::Write(std::ofstream *file_, char *data_, unsigned int nWords_, int &buffs_written){
617  if(!file_ || !file_->is_open() || !file_->good() || !data_ || nWords_ == 0){
618  if(debug_mode){ std::cout << "debug: !file_ || !file_->is_open() || !data_ || nWords_ == 0\n"; }
619  return false;
620  }
621 
622  buffs_written = 0;
623 
624  // If this is a new buffer, write a buffer header.
625  // We are currently at the start of a new buffer. No need to close.
626  if(buff_pos == 0)
627  open_(file_);
628 
629  unsigned int spillpos = 0;
630  unsigned int chunkPayload;
631 
632  unsigned int oldBuffPos = buff_pos;
633  unsigned int chunkSizeB;
634  unsigned int totalNumChunks = 0;
635  unsigned int currentNumChunk = 0;
636 
637  char *arrptr = data_;
638 
639  // Calculate the total number of spill chunks.
640  while(spillpos < nWords_){
641  if(oldBuffPos + 4 > LDF_DATA_LENGTH)
642  oldBuffPos = 2;
643 
644  if(nWords_ - spillpos + 4 > LDF_DATA_LENGTH - oldBuffPos)
645  chunkPayload = LDF_DATA_LENGTH - oldBuffPos - 4;
646  else
647  chunkPayload = nWords_ - spillpos;
648 
649  spillpos += chunkPayload;
650  oldBuffPos += chunkPayload + 4;
651 
652  totalNumChunks++;
653 
654  if(oldBuffPos >= LDF_DATA_LENGTH)
655  oldBuffPos = 2;
656  }
657 
658  // Account for the spill footer.
659  totalNumChunks++;
660 
661  // Reset the spill position.
662  spillpos = 0;
663 
664  // Write the spill.
665  while(spillpos < nWords_){
666  if(buff_pos + 4 > LDF_DATA_LENGTH){
667  buffs_written++;
668  Close(file_);
669  open_(file_);
670  }
671 
672  if(nWords_ - spillpos + 4 > LDF_DATA_LENGTH - buff_pos)
673  chunkPayload = LDF_DATA_LENGTH - buff_pos - 4;
674  else
675  chunkPayload = nWords_ - spillpos;
676 
677  spillpos += chunkPayload;
678  chunkSizeB = 4*(chunkPayload + 3);
679 
680  if(debug_mode)
681  std::cout << "debug: writing " << 1+chunkSizeB/4 << " word spill chunk " << currentNumChunk << " of " << totalNumChunks << ".\n";
682 
683  file_->write((char*)&chunkSizeB, 4);
684  file_->write((char*)&totalNumChunks, 4);
685  file_->write((char*)&currentNumChunk, 4);
686  file_->write((char*)arrptr, 4*chunkPayload);
687  file_->write((char*)&buffend, 4);
688 
689  currentNumChunk++;
690 
691  buff_pos += chunkPayload + 4;
692  arrptr += 4*chunkPayload;
693 
694  if(buff_pos > LDF_DATA_LENGTH)
695  std::cout << "WARNING: Current ldf buffer overfilled by " << buff_pos - LDF_DATA_LENGTH << " words!\n";
696 
697  if(buff_pos >= LDF_DATA_LENGTH){
698  buffs_written++;
699  Close(file_);
700  open_(file_);
701  }
702  }
703 
705  std::cout << "WARNING: Final ldf buffer overfilled by " << buff_pos - LDF_DATA_LENGTH << " words!\n";
706 
707  // Write the spill footer.
708  if(buff_pos + 6 > LDF_DATA_LENGTH){
709  buffs_written++;
710  open_(file_);
711  }
712 
713  if(debug_mode)
714  std::cout << "debug: writing final spill chunk " << currentNumChunk << " of " << 1+end_spill_size/4 << " words.\n";
715 
716  file_->write((char*)&end_spill_size, 4);
717  file_->write((char*)&totalNumChunks, 4);
718  file_->write((char*)&currentNumChunk, 4);
719  file_->write((char*)&pacman_word1, 4);
720  file_->write((char*)&pacman_word2, 4);
721  file_->write((char*)&buffend, 4);
722 
723  // Update the buffer position.
724  buff_pos += 6;
725 
726  return true;
727 }
728 
730 bool DATA_buffer::Read(std::ifstream *file_, char *data_, unsigned int &nBytes, unsigned int max_bytes_, bool &full_spill, bool &bad_spill, bool dry_run_mode/*=false*/){
731  if(!file_ || !file_->is_open() || !file_->good()){
732  retval = 6;
733  return false;
734  }
735 
736  bad_spill = false;
737 
738  bool first_chunk = true;
739  unsigned int this_chunk_sizeB;
740  unsigned int total_num_chunks = 0;
741  unsigned int current_chunk_num = 0;
742  unsigned int prev_chunk_num;
743  unsigned int prev_num_chunks;
744  nBytes = 0; // Set the number of output bytes to zero
745 
746  while(true){
747  if(!read_next_buffer(file_)){
748  if(debug_mode){ std::cout << "debug: failed to read from input data file\n"; }
749  retval = 6;
750  return false;
751  }
752 
753  if(buff_head == DATA){
754  prev_chunk_num = current_chunk_num;
755  prev_num_chunks = total_num_chunks;
756 
757  this_chunk_sizeB = curr_buffer[buff_pos++];
758  total_num_chunks = curr_buffer[buff_pos++];
759  current_chunk_num = curr_buffer[buff_pos++];
760 
761  if(debug_mode){ std::cout << "debug: scanning spill chunk " << current_chunk_num << " of " << total_num_chunks << "\n"; }
762 
763  // Check if this is a spill fragment.
764  if(first_chunk){ // Check for starting read in middle of spill.
765  if(current_chunk_num != 0){
766  if(debug_mode){ std::cout << "debug: starting read in middle of spill (chunk " << current_chunk_num << " of " << total_num_chunks << ")\n"; }
767 
768  // Update the number of dropped chunks.
769  missing_chunks += current_chunk_num;
770 
771  full_spill = false;
772  }
773  else{ full_spill = true; }
774  first_chunk = false;
775  }
776  else if(total_num_chunks != prev_num_chunks){
777  if(debug_mode){ std::cout << "debug: skipped to new spill with " << total_num_chunks << " spill chunks without reading footer of old spill\n"; }
778 
779  // We are likely out of position in the spill. Scrap this current buffer and skip to the next one.
780  read_next_buffer(file_, true);
781 
782  // Update the number of dropped chunks.
783  missing_chunks += (prev_num_chunks-1) - prev_chunk_num;
784 
785  retval = 4;
786  return false;
787  }
788  else if(current_chunk_num != prev_chunk_num + 1){ // Missing a spill chunk.
789  if(debug_mode){
790  if(current_chunk_num == prev_chunk_num + 2){ std::cout << "debug: missing single spill chunk (" << prev_chunk_num+1 << ")\n"; }
791  else{ std::cout << "debug: missing multiple spill chunks (" << prev_chunk_num+1 << " to " << current_chunk_num-1 << ")\n"; }
792  }
793  full_spill = false;
794 
795  // We are likely out of position in the spill. Scrap this current buffer and skip to the next one.
796  read_next_buffer(file_, true);
797 
798  // Update the number of dropped chunks.
799  missing_chunks += (current_chunk_num-1) - prev_chunk_num;
800 
801  retval = 4;
802  return false;
803  }
804 
805  // Construct the spill.
806  if(current_chunk_num == total_num_chunks - 1){ // Spill footer
807  if(this_chunk_sizeB != end_spill_size){
808  if(debug_mode){ std::cout << "debug: spill footer (chunk " << current_chunk_num << " of " << total_num_chunks << ") has size " << this_chunk_sizeB << " != 5\n"; }
809 
810  // We are likely out of position in the spill. Scrap this current buffer and skip to the next one.
811  read_next_buffer(file_, true);
812 
813  // Update the number of dropped chunks.
814  //missing_chunks += 1;
815 
816  retval = 5;
817  return false;
818  }
819  else if(debug_mode){
820  if(full_spill){ std::cout << "debug: finished scanning spill of " << nBytes << " bytes\n"; }
821  else{ std::cout << "debug: finished scanning spill fragment of " << nBytes << " bytes\n"; }
822  }
823 
824  // Copy data into the output array.
825  if(!dry_run_mode){ memcpy(&data_[nBytes], &curr_buffer[buff_pos], 8); }
826  if(debug_mode){ std::cout << "debug: spill footer words are " << curr_buffer[buff_pos] << " and " << curr_buffer[buff_pos+1] << std::endl; }
827  nBytes += 8;
828  buff_pos += 2;
829 
830  retval = 0;
831  return true;
832  }
833  else{ // Normal spill chunk
834  unsigned int copied_bytes;
835  if(this_chunk_sizeB <= 12){
836  if(debug_mode){ std::cout << "debug: invalid number of bytes in chunk " << current_chunk_num+1 << " of " << total_num_chunks << ", " << this_chunk_sizeB << " B!\n"; }
837 
838  // Update the number of dropped chunks.
839  missing_chunks++;
840 
841  retval = 4;
842  return false;
843  }
844 
845  // Update the number of good spill chunks.
846  good_chunks++;
847 
848  copied_bytes = this_chunk_sizeB - 12;
849  if(!dry_run_mode){ memcpy(&data_[nBytes], &curr_buffer[buff_pos], copied_bytes); }
850  nBytes += copied_bytes;
851  buff_pos += copied_bytes/4;
852  }
853  }
854  else if(buff_head == ENDFILE){ // Catch the start of the end-of-file buffer and return
855  if(next_buffer[0] == ENDFILE){
856  if(debug_mode){ std::cout << "debug: encountered double EOF buffer marking end of file\n"; }
857  retval = 2;
858  }
859  else{
860  if(debug_mode){ std::cout << "debug: encountered EOF buffer marking end of run\n"; }
861 
862  // We need to skip this buffer.
863  read_next_buffer(file_, true);
864 
865  retval = 1;
866  }
867  return false;
868  }
869  else{ // Skip the entire buffer
870  if(debug_mode){
871  std::cout << "debug: encountered non DATA type buffer 0x" << std::hex << buff_head << std::dec << "\n";
872  std::cout << "debug: skipping entire remaining " << buff_size << " buffer words!\n";
873  }
874 
875  // This is not a data buffer. We need to force a scan of the next buffer.
876  // read_next_buffer will not scan the next buffer by default because it
877  // thinks there are still words left in this buffer to read.
878  read_next_buffer(file_, true);
879 
880  retval = 3;
881  continue;
882  }
883  }
884 
885  return false;
886 }
887 
892  buff_pos = 0;
893  bcount = 0;
894  retval = 0;
895  good_chunks = 0;
896  missing_chunks = 0;
897 }
898 
900 
902 bool EOF_buffer::Write(std::ofstream *file_){
903  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
904 
905  if(debug_mode){ std::cout << "debug: writing " << ACTUAL_BUFF_SIZE*4 << " byte EOF buffer\n"; }
906 
907  // write 8 bytes (2 words)
908  file_->write((char*)&bufftype, 4);
909  file_->write((char*)&buffsize, 4);
910 
911  // Fill the rest of the buffer with 0xFFFFFFFF (end of buffer)
912  for(unsigned int i = 0; i < ACTUAL_BUFF_SIZE-2; i++){
913  file_->write((char*)&buffend, 4);
914  }
915 
916  return true;
917 }
918 
920 bool EOF_buffer::Read(std::ifstream *file_){
921  if(!file_ || !file_->is_open() || !file_->good()){ return false; }
922 
923  unsigned int check_bufftype, check_buffsize;
924  file_->read((char*)&check_bufftype, 4);
925  file_->read((char*)&check_buffsize, 4);
926  if(check_bufftype != bufftype || check_buffsize != buffsize){ // Not a valid EOF buffer
927  if(debug_mode){ std::cout << "debug: not a valid EOF buffer\n"; }
928  file_->seekg(-8, file_->cur); // Rewind to the beginning of this buffer
929  return false;
930  }
931 
932  file_->seekg((buffsize*4), file_->cur); // Skip the rest of the buffer
933 
934  return true;
935 }
936 
939  std::stringstream stream; stream << current_file_num;
940  std::string run_num_str = stream.str();
941  std::string output;
942 
943  if(current_file_num == 0){ output = fname_prefix; }
944  else if(current_file_num < 10){ output = fname_prefix + "_0" + run_num_str; }
945  else{ output = fname_prefix + "_" + run_num_str; }
946 
947  if(output_format == 0){ output += ".ldf"; }
948  else if(output_format == 1){ output += ".pld"; }
949  else{ output += ".root"; } // PLACEHOLDER!!!
950  return output;
951 }
952 
954 bool PollOutputFile::get_full_filename(std::string &output){
955  unsigned int depth = (int)directories.size();
956 
957  // Get the depth of the current filename
958  std::string formatted_filename = "";
959  unsigned int index = 0;
960  while(index < current_filename.size()){
961  if(current_filename[index] == '.'){
962  if(current_filename[index+1] == '.'){ // '../'
963  if(depth > 0){ depth--; }
964  else{ // user supplied a stupid filename
965  output = current_filename;
966  return false;
967  }
968  index += 3;
969  }
970  else if(current_filename[index+1] == '/'){ // './'
971  index += 2;
972  }
973  else{
974  formatted_filename += current_filename[index];
975  index++;
976  }
977  }
978  else{
979  formatted_filename += current_filename[index];
980  index++;
981  }
982  }
983 
984  if(depth > 0){
985  output = "/";
986  for(unsigned int i = 0; i < depth; i++){
987  output += directories.at(i) + "/";
988  }
989  output += formatted_filename;
990  }
991  else{ output = formatted_filename; }
992 
993  return true;
994 }
995 
1000 bool PollOutputFile::overwrite_dir(int total_buffers_/*=-1*/){
1001  if(!output_file.is_open() || !output_file.good()){ return false; }
1002 
1003  // Set the buffer count in the "DIR " buffer
1004  if(total_buffers_ == -1){ // Set with the internal buffer count
1005  unsigned int size = output_file.tellp(); // Get the length of the file (in bytes)
1006  output_file.seekp(12); // Set position to just after the third word
1007 
1008  // Calculate the number of buffers in this file
1009  unsigned int total_num_buffer = size / (4 * ACTUAL_BUFF_SIZE);
1010  unsigned int overflow = size % (4 * ACTUAL_BUFF_SIZE);
1011  output_file.write((char*)&total_num_buffer, 4);
1012 
1013  if(debug_mode){
1014  std::cout << "debug: file size is " << size << " bytes (" << size/4 << " 4 byte words)\n";
1015  std::cout << "debug: file contains " << total_num_buffer << " buffers of " << ACTUAL_BUFF_SIZE << " words\n";
1016  if(overflow != 0){ std::cout << "debug: file has an overflow of " << overflow << " 4 byte words!\n"; }
1017  std::cout << "debug: set .ldf directory buffer number to " << total_num_buffer << std::endl;
1018  }
1019 
1020  if(overflow != 0){
1021  output_file.close();
1022  return false;
1023  }
1024  }
1025  else{ // Set with an external buffer count
1026  output_file.write((char*)&total_buffers_, 4);
1027  if(debug_mode){ std::cout << "debug: set .ldf directory buffer number to " << total_buffers_ << std::endl; }
1028  }
1029 
1030  output_file.close();
1031  return true;
1032 }
1033 
1036  max_spill_size = 0;
1037  current_file_num = 0;
1038  output_format = 0;
1039  number_spills = 0;
1040  fname_prefix = "poll_data";
1041  current_filename = "unknown";
1042  current_full_filename = "unknown";
1043  debug_mode = false;
1044 
1045  // Get the current working directory
1046  // current_directory DOES NOT include a trailing '/'
1047  char ch_cwd[1024];
1048  current_directory = std::string(getcwd(ch_cwd, 1024));
1049 
1050  // Find the depth of the current directory
1051  std::string temp = "";
1052  for(unsigned int i = 0; i < current_directory.size(); i++){
1053  if(current_directory[i] == '/'){
1054  if(temp != ""){
1055  directories.push_back(temp);
1056  temp = "";
1057  }
1058  }
1059  else{ temp += current_directory[i]; }
1060  }
1061 
1062  if(temp != ""){ directories.push_back(temp); }
1063 
1064  current_depth = directories.size();
1065 }
1066 
1069  initialize();
1070 }
1071 
1073 PollOutputFile::PollOutputFile(std::string filename_){
1074  initialize();
1075  fname_prefix = filename_;
1076 }
1077 
1079 void PollOutputFile::SetDebugMode(bool debug_/*=true*/){
1080  debug_mode = debug_;
1081  pldHead.SetDebugMode(debug_);
1082  pldData.SetDebugMode(debug_);
1083  dirBuff.SetDebugMode(debug_);
1084  headBuff.SetDebugMode(debug_);
1085  dataBuff.SetDebugMode(debug_);
1086  eofBuff.SetDebugMode(debug_);
1087 }
1088 
1090 bool PollOutputFile::SetFileFormat(unsigned int format_){
1091  if(format_ <= 2){
1092  output_format = format_;
1093  return true;
1094  }
1095  return false;
1096 }
1097 
1099 void PollOutputFile::SetFilenamePrefix(std::string filename_){
1100  fname_prefix = filename_;
1101  current_file_num = 0;
1102 }
1103 
1105 int PollOutputFile::Write(char *data_, unsigned int nWords_){
1106  if(!data_ || nWords_ == 0){ return -1; }
1107 
1108  if(!output_file.is_open() || !output_file.good()){ return -1; }
1109 
1110  if(nWords_ > max_spill_size){ max_spill_size = nWords_; }
1111 
1112  // Write data to disk
1113  int buffs_written;
1114  if(output_format == 0){
1115  if(!dataBuff.Write(&output_file, data_, nWords_, buffs_written)){ return -1; }
1116  }
1117  else if(output_format == 1){
1118  if(!pldData.Write(&output_file, data_, nWords_)){ return -1; }
1119  buffs_written = 1;
1120  }
1121  else{
1122  if(debug_mode){ std::cout << "debug: invalid output format for PollOutputFile::Write!\n"; }
1123  return -1;
1124  }
1125  number_spills++;
1126 
1127  return buffs_written;
1128 }
1129 
1134  if(!cli_){ return -1; }
1135 
1136  unsigned int end_packet = ENDBUFF;
1137  unsigned int buff_size = ACTUAL_BUFF_SIZE;
1138  std::streampos file_size = output_file.tellp();
1139 
1140  int bytes = -1; // size of char array in bytes
1141 
1142  // Size of basic types on this machine. Probably overly cautious, but it only
1143  // amounts to sending two extra bytes over the network per packet
1144  char size_of_int = sizeof(int); // Size of integer on this machine
1145  char size_of_spos = sizeof(std::streampos); // Size of streampos on this machine
1146 
1147  char *packet = NULL;
1148 
1149  if(!output_file.is_open() || !output_file.good()){
1150  // Below is the packet packet structure
1151  // ------------------------------------
1152  // 1 byte size of integer (may not be the same on a different machine)
1153  // 1 byte size of streampos (may not be the same on a different machine)
1154  // 4 byte packet length (inclusive, also includes the end packet flag)
1155  // 4 byte begin packet flag (0xFFFFFFFF)
1156  bytes = 2 + 2 * sizeof(int); // Total size of the packet (in bytes)
1157  packet = new char[bytes];
1158 
1159  unsigned int index = 0;
1160  memcpy(&packet[index], (char *)&size_of_int, 1); index += 1;
1161  memcpy(&packet[index], (char *)&size_of_spos, 1); index += 1;
1162  memcpy(&packet[index], (char *)&bytes, sizeof(int)); index += sizeof(int);
1163  memcpy(&packet[index], (char *)&end_packet, sizeof(int)); index += sizeof(int);
1164  }
1165  else{
1166  // Below is the packet packet structure
1167  // ------------------------------------
1168  // 1 byte size of integer (may not be the same on a different machine)
1169  // 1 byte size of streampos (may not be the same on a different machine)
1170  // 4 byte packet length (inclusive, also includes the end packet flag)
1171  // x byte file path (no size limit)
1172  // 8 byte file size streampos (long long)
1173  // 4 byte spill number ID (unsigned int)
1174  // 4 byte buffer size (unsigned int)
1175  // 4 byte begin packet flag (0xFFFFFFFF)
1176  // length of the file path.
1177  bytes = (2 + 4 * sizeof(int)) + sizeof(std::streampos) + current_full_filename.size(); // Total size of the packet (in bytes)
1178  packet = new char[bytes];
1179  const char *str = current_full_filename.c_str();
1180 
1181  unsigned int index = 0;
1182  memcpy(&packet[index], (char *)&size_of_int, 1); index += 1;
1183  memcpy(&packet[index], (char *)&size_of_spos, 1); index += 1;
1184  memcpy(&packet[index], (char *)&bytes, sizeof(int)); index += sizeof(int);
1185  memcpy(&packet[index], (char *)str, (unsigned int)current_full_filename.size()); index += current_full_filename.size();
1186  memcpy(&packet[index], (char *)&file_size, sizeof(std::streampos)); index += sizeof(std::streampos);
1187  memcpy(&packet[index], (char *)&number_spills, sizeof(int)); index += sizeof(int);
1188  memcpy(&packet[index], (char *)&buff_size, sizeof(int)); index += sizeof(int);
1189  memcpy(&packet[index], (char *)&end_packet, sizeof(int));
1190  }
1191  cli_->SendMessage(packet, bytes);
1192 
1193  delete[] packet;
1194 
1195  return bytes;
1196 }
1197 
1199 bool PollOutputFile::OpenNewFile(std::string title_, unsigned int &run_num_, std::string prefix, std::string output_directory/*="./"*/, bool continueRun /*= false*/){
1200  CloseFile();
1201 
1202  // Restart the spill counter for the new file
1203  number_spills = 0;
1204 
1205  std::string filename = GetNextFileName(run_num_,prefix,output_directory,continueRun);
1206  output_file.open(filename.c_str(), std::ios::binary);
1207  if(!output_file.is_open() || !output_file.good()){
1208  output_file.close();
1209  return false;
1210  }
1211 
1212  current_filename = filename;
1213  get_full_filename(current_full_filename);
1214 
1215  if(output_format == 0){
1216  dirBuff.SetRunNumber(run_num_);
1217  dirBuff.Write(&output_file); // Every .ldf file gets a DIR header
1218 
1219  headBuff.SetTitle(title_);
1220  headBuff.SetDateTime();
1221  headBuff.SetRunNumber(run_num_);
1222  headBuff.Write(&output_file); // Every .ldf file gets a HEAD file header
1223  }
1224  else if(output_format == 1){
1225  pldHead.SetTitle(title_);
1226  pldHead.SetRunNumber(run_num_);
1228 
1229  // Write a blank header for now and overwrite it later
1230  unsigned int temp = 0;
1231  for(unsigned int i = 0; i < pldHead.GetBufferLength()/4; i++){
1232  output_file.write((char*)&temp, 4);
1233  }
1234  temp = -1;
1235  output_file.write((char*)&temp, 4); // Close the buffer
1236  }
1237  else{
1238  if(debug_mode){ std::cout << "debug: invalid output format for PollOutputFile::OpenNewFile!\n"; }
1239  return false;
1240  }
1241 
1242  return true;
1243 }
1244 
1246 std::string PollOutputFile::GetNextFileName(unsigned int &run_num_, std::string prefix, std::string output_directory, bool continueRun /*=false*/) {
1247  std::stringstream filename;
1248  filename << output_directory << prefix << "_" << std::setfill('0') << std::setw(3) << run_num_;
1249 
1250  if(output_format == 0){ filename << ".ldf"; }
1251  else if(output_format == 1){ filename << ".pld"; }
1252 
1253  std::ifstream dummy_file(filename.str().c_str());
1254  unsigned int suffix = 0;
1255  while (dummy_file.is_open()) {
1256  dummy_file.close();
1257  filename.str("");
1258 
1259  if(continueRun){ filename << output_directory << prefix << "_" << std::setfill('0') << std::setw(3) << run_num_ << "-" << ++suffix; }
1260  else{ filename << output_directory << prefix << "_" << std::setfill('0') << std::setw(3) << ++run_num_; }
1261 
1262  if(output_format == 0){ filename << ".ldf"; }
1263  else if(output_format == 1){ filename << ".pld"; }
1264 
1265  dummy_file.open(filename.str().c_str());
1266  }
1267  dummy_file.close();
1268  return filename.str();
1269 }
1270 
1272  if(output_format == 0) return dirBuff.GetRunNumber();
1273  else if(output_format == 1) return pldHead.GetRunNumber();
1274  else if(debug_mode) std::cout << "debug: invalid output format for PollOutputFile::GetRunNumber!\n";
1275  return 0;
1276 }
1277 
1279 void PollOutputFile::CloseFile(float total_run_time_/*=0.0*/){
1280  if(!output_file.is_open() || !output_file.good()){ return; }
1281 
1282  if(output_format == 0){
1283  dataBuff.Close(&output_file); // Pad the final data buffer with 0xFFFFFFFF
1284 
1285  eofBuff.Write(&output_file); // First EOF buffer signals end of run
1286  eofBuff.Write(&output_file); // Second EOF buffer signals physical end of file
1287 
1288  overwrite_dir(); // Overwrite the total buffer number word and close the file
1289  }
1290  else if(output_format == 1){
1291  unsigned int temp = ENDFILE; // Write an EOF buffer
1292  output_file.write((char*)&temp, 4);
1293 
1294  temp = ENDBUFF; // Signal the end of the file
1295  output_file.write((char*)&temp, 4);
1296 
1297  // Overwrite the blank pld header at the beginning of the file and close it
1298  output_file.seekp(0);
1300  pldHead.SetMaxSpillSize(max_spill_size);
1301  pldHead.Write(&output_file);
1302  output_file.close();
1303  }
1304  else if(debug_mode){ std::cout << "debug: invalid output format for PollOutputFile::CloseFile!\n"; }
1305 }
PLD_header pldHead
Definition: headReader.cpp:11
void SetTitle(std::string input_)
Set the title of the output pld file (unlimited length).
virtual void Reset()
Set initial values.
unsigned int good_chunks
Total size of ldf buffer (in 4 byte words).
#define DATA
unsigned int run_num
virtual bool Write(std::ofstream *file_)
0x20464F45 "EOF "
void Print()
Print header information.
PLD_data()
Default constructor.
~PLD_header()
Destructor.
virtual bool Read(std::ifstream *file_)
Returns only false if not overloaded.
std::string get_filename()
Get the formatted filename of the current file.
virtual bool Read(std::ifstream *file_)
Read an EOF buffer from a file. Return false if buffer has the wrong header and return true otherwise...
unsigned int buffend
Definition: hribf_buffers.h:39
unsigned int bufftype
Definition: hribf_buffers.h:37
void SetFilenamePrefix(std::string filename_)
Set the output filename prefix.
virtual bool Write(std::ofstream *file_)
Returns only false if not overloaded.
bool SetDateTime()
Set the date and time of the ldf file.
const unsigned int pacman_word1
The size of the end of spill "event" (5 words).
char facility[17]
Definition: hribf_buffers.h:76
char end_date[25]
Definition: hribf_buffers.h:78
#define ACTUAL_BUFF_SIZE
Definition: hribf_buffers.h:31
Provides network connectivity for poll2.
DIR_buffer()
Default constructor.
virtual bool Write(std::ofstream *file_)
unsigned int run_num
virtual void Reset()
Set initial values.
unsigned int buff_head
The total number of ldf buffers read from file.
virtual void Reset()
Set initial values.
char format[17]
Definition: hribf_buffers.h:75
unsigned int GetBufferLength()
Get the length of the header buffer.
unsigned int buff_size
The ldf buffer header ID.
#define PAC
#define DEAD
#define SCAL
time_t runStopTime
Definition: hribf_buffers.h:82
int Write(char *data_, unsigned int nWords_)
Write nWords_ of data to the file.
void initialize()
Initialize the output file with initial parameters.
#define ENDBUFF
void PrintDelimited(const char &delimiter_='\t')
Print dir buffer information in a delimited list.
unsigned int buff_pos
Count of the number of missing spill chunks which were dropped.
float run_time
Definition: hribf_buffers.h:74
bool get_full_filename(std::string &output)
Get the full path of the current file.
unsigned int total_buff_size
#define ENDFILE
void Print()
Print dir buffer information.
unsigned int unknown[3]
bool SetTitle(std::string input_)
Set the title of the ldf file.
unsigned int GetRunNumber()
virtual void Reset()
Set initial values.
virtual bool Write(std::ofstream *file_)
Write a pld style header to a file.
DATA_buffer()
Default constructor.
void Print()
Print header information.
virtual bool Write(std::ofstream *file_, char *data_, unsigned int nWords_, int &buffs_written)
Write a data spill to file.
std::string GetNextFileName(unsigned int &run_num_, std::string prefix, std::string output_dir, bool continueRun=false)
Return the filename of the next output file.
unsigned int zero
Definition: hribf_buffers.h:40
unsigned int max_spill_size
Definition: hribf_buffers.h:73
virtual bool Read(std::ifstream *file_, char *data_, unsigned int &nBytes_, unsigned int max_bytes_, bool &full_spill, bool &bad_spill, bool dry_run_mode=false)
Read a data spill from a file.
void SetStartDateTime()
Set the date and tiem of when the file is opened.
void PrintDelimited(const char &delimiter_='\t')
Print header information in a delimited list.
bool read_next_buffer(std::ifstream *f_, bool force_=false)
virtual bool Write(std::ofstream *file_, char *data_, unsigned int nWords_)
0x41544144 "DATA"
unsigned int missing_chunks
Count of the number of good spill chunks which were read.
PLD_header()
Default constructor.
HEAD_buffer()
Default constructor.
char format[9]
unsigned int GetRunNumber()
bool debug_mode
Definition: hribf_buffers.h:41
void SetRunNumber(unsigned int input_)
void SetDebugMode(bool debug_=true)
Definition: hribf_buffers.h:63
bool Close(std::ofstream *file_)
0x41544144 "DATA"
void SetMaxSpillSize(unsigned int max_spill_size_)
#define NO_HEADER_SIZE
void PrintDelimited(const char &delimiter_='\t')
Print header information in a delimited list.
PollOutputFile()
Default constructor.
#define DIR
unsigned int bcount
Pointer to the next ldf buffer.
virtual void Reset()
Does nothing if not overloaded.
Definition: hribf_buffers.h:52
virtual bool Read(std::ifstream *file_, char *data_, unsigned int &nBytes, unsigned int max_bytes_, bool dry_run_mode=false)
Read a data spill from a file.
bool is_hribf_buffer(const unsigned int &input_)
Return true if the input word corresponds to the header of a ldf style buffer.
int SendMessage(char *message_, size_t length_)
char type[17]
void set_char_array(const std::string &input_, char *arr_, const unsigned int &size_)
End of spill vsn. The scan code searches for these words.
unsigned int buffer1[ACTUAL_BUFF_SIZE]
The error code for the read method.
BufferType(unsigned int bufftype_, unsigned int buffsize_, unsigned int buffend_=0xFFFFFFFF)
Generic BufferType constructor.
void SetDebugMode(bool debug_=true)
Toggle debug mode.
void CloseFile(float total_run_time_=0.0)
Write the footer and close the file.
void SetFacility(std::string input_)
Set the facility of the output pld file (max length 16).
const unsigned int end_spill_size
int SendPacket(Client *cli_)
char * run_title
Definition: hribf_buffers.h:79
unsigned int * next_buffer
Pointer to the current ldf buffer.
virtual bool Read(std::ifstream *file_)
Read a DIR buffer from a file. Return false if buffer has the wrong header and return true otherwise...
#define HEAD
virtual bool Read(std::ifstream *file_)
Read a HEAD buffer from a pld format file. Return false if buffer has the wrong header and return tru...
bool SetFileFormat(unsigned int format_)
Set the output file format.
bool open_(std::ofstream *file_)
The actual position in the current ldf buffer.
virtual bool Read(std::ifstream *file_)
Read a HEAD buffer from a file. Return false if buffer has the wrong header and return true otherwise...
unsigned int run_num
Definition: hribf_buffers.h:72
bool ReadHeader(std::ifstream *file_)
Return true if the first word of the current buffer is equal to this buffer type. ...
const unsigned int pacman_word2
Words to signify the end of a spill. The scan code searches for these words.
char run_title[81]
virtual bool Write(std::ofstream *file_)
bool OpenNewFile(std::string title_, unsigned int &run_num_, std::string prefix, std::string output_dir="./", bool continueRun=false)
Close the current file, if one is open, and open a new file for data output.
unsigned int buffsize
Definition: hribf_buffers.h:38
char start_date[25]
Definition: hribf_buffers.h:77
Handles poll2 output data files.
bool overwrite_dir(int total_buffers_=-1)
char facility[9]
time_t runStartTime
Definition: hribf_buffers.h:81
#define LDF_DATA_LENGTH
char date[17]
void SetEndDateTime()
Set the date and time of when the file is closed.
virtual void Reset()
Set initial values.
unsigned int * curr_buffer
Container for a second ldf buffer.
unsigned int buffer2[ACTUAL_BUFF_SIZE]
Container for a ldf buffer.