22 printf(
"TMReaderInterface::ctor!\n");
30 sprintf(buf,
"%d", v);
34 static std::string
Errno(
const char* s)
38 r +=
" failed: errno: ";
46 static int ReadPipe(FILE *fp,
char* buf,
int length)
50 int rd = fread(buf, 1, length, fp);
70 printf(
"ErrorReader::ctor!\n");
72 fErrorString =
"The ErrorReader always returns an error";
78 printf(
"ErrorReader::dtor!\n");
81 int Read(
void* buf,
int count)
99 printf(
"FileReader::ctor!\n");
101 fFp = fopen(filename,
"r");
111 printf(
"FileReader::dtor!\n");
132 printf(
"FileReader::Close!\n");
150 printf(
"PipeReader::ctor!\n");
152 fPipe = popen(pipename,
"r");
162 printf(
"PipeReader::dtor!\n");
171 assert(
fPipe != NULL);
183 printf(
"PipeReader::Close!\n");
202 ZlibReader(
const char* filename)
205 printf(
"ZlibReader::ctor!\n");
206 fFilename = filename;
207 fGzFile = gzopen(filename,
"rb");
210 fErrorString =
Errno((std::string(
"gzopen(\"")+fFilename+
"\")").c_str());
217 printf(
"PipeReader::dtor!\n");
222 int Read(
void* buf,
int count)
226 assert(fGzFile != NULL);
227 int rd = gzread(fGzFile, buf, count);
230 fErrorString =
Errno((std::string(
"gzread(\"")+fFilename+
"\")").c_str());
238 printf(
"ZlibReader::Close!\n");
246 std::string fFilename;
272 printf(
"Lz4Reader::ctor!\n");
277 fErrorString =
"LZ4F_createDecompressionContext() error ";
291 printf(
"Lz4Reader::dtor!\n");
301 fErrorString =
"LZ4F_freeDecompressionContext() error ";
321 char* cptr = (
char*)buf;
324 while (clen < count) {
325 int more = count - clen;
339 }
else if (rd == 0) {
351 size_t dst_size = more;
365 assert(dst_size!=0 || src_size!=0);
384 printf(
"Lz4Reader::Close!\n");
411 fFp = fopen(filename,
"w");
415 int Write(
const void* buf,
int count)
418 return fwrite(buf, 1, count,
fFp);
435 const char* s = strstr(name,suffix);
439 return (s-name)+strlen(suffix) == strlen(name);
445 signal(SIGPIPE, SIG_IGN);
448 signal(SIGXFSZ, SIG_IGN);
454 else if (strncmp(
source,
"ssh://", 6) == 0)
456 const char* name =
source + 6;
457 const char* s = strstr(name,
"/");
462 e->
fErrorString =
"TMidasFile::Open: Invalid ssh:// URI. Should be: ssh://user@host/file/path/...";
466 const char* remoteFile = s + 1;
468 std::string remoteHost;
469 for (s=name; *s !=
'/'; s++)
474 pipe =
"ssh -e none -T -x -n ";
481 pipe +=
" | gzip -dc";
483 pipe +=
" | bzip2 -dc";
489 else if (strncmp(
source,
"dccp://", 7) == 0)
491 const char* name =
source + 7;
497 pipe +=
" /dev/fd/1";
500 pipe +=
" | gzip -dc";
502 pipe +=
" | bzip2 -dc";
508 else if (strncmp(
source,
"pipein://", 9) == 0)
510 std::string pipe =
source + 9;
523 return new ZlibReader(
source);
546 return new ZlibReader(
source);
560 return *(uint16_t*)ptr;
565 return *(uint32_t*)ptr;
568 static void PutU16(
char* ptr, uint16_t v)
573 static void PutU32(
char* ptr, uint32_t v)
581 return (size + 7) & ~7;
589 assert(
sizeof(
char)==1);
590 assert(
sizeof(uint16_t)==2);
591 assert(
sizeof(uint32_t)==4);
598 const int event_header_size = 4*4;
599 char event_header[event_header_size];
601 int rd = reader->
Read(event_header, event_header_size);
606 }
else if (rd == 0) {
609 }
else if (rd != event_header_size) {
610 fprintf(stderr,
"TMReadEvent: error: read %d shorter than event header size %d\n", (
int)rd, (
int)event_header_size);
632 e->
data.resize(event_header_size + to_read);
634 memcpy(&e->
data[0], event_header, event_header_size);
636 rd = reader->
Read(&e->
data[event_header_size], to_read);
641 }
else if ((
size_t)rd != to_read) {
642 fprintf(stderr,
"TMReadEvent: error: short read %d instead of %d\n", (
int)rd, (
int)to_read);
658 sprintf(buf,
"event: id %d, mask 0x%04x, serial %d, time %d, size %d, error %d, banks %d",
event_id,
trigger_mask,
serial_number,
time_stamp,
data_size,
error, (
int)
banks.size());
665 for (
unsigned i=0; i<
banks.size(); i++) {
710 fprintf(stderr,
"TMEvent::ParseEvent: error: vector size %d mismatch against event size in event header: data_size %d, event_size %d\n", (
int)
data.size(), (
int)
data_size, (
int)(
event_header_size +
data_size));
719 const char* event_header = (
const char*)buf;
722 fprintf(stderr,
"TMEvent::ctor: error: buffer size %d is smaller than event header size %d\n", (
int)buf_size, (
int)
event_header_size);
746 assert(
sizeof(
char)==1);
747 assert(
sizeof(uint16_t)==2);
748 assert(
sizeof(uint32_t)==4);
761 if (zevent_size != buf_size) {
762 fprintf(stderr,
"TMEvent::ctor: error: buffer size %d mismatch against event size in event header: data_size %d, event_size %d\n", (
int)buf_size, (
int)zdata_size, (
int)zevent_size);
770 const char* cptr = (
const char*)buf;
772 data.assign(cptr, cptr + zevent_size);
774 assert(
data.size() == zevent_size);
777 void TMEvent::Init(uint16_t xevent_id, uint16_t xtrigger_mask, uint32_t xserial_number, uint32_t xtime_stamp,
size_t capacity)
805 data.reserve(capacity);
811 char* event_header =
data.data();
818 PutU32(event_header+16, 0);
826 size_t end_of_event_offset =
data.size();
828 data.resize(end_of_event_offset + bank_size);
830 char* pbank =
data.data() + end_of_event_offset;
832 pbank[0] = bank_name[0];
833 pbank[1] = bank_name[1];
834 pbank[2] = bank_name[2];
835 pbank[3] = bank_name[3];
840 memcpy(pbank+4*4, buf, size);
846 char* event_header =
data.data();
869 if (e->
data.size() < off + 8) {
870 fprintf(stderr,
"TMEvent::FindFirstBank: error: data size %d is too small\n", (
int)e->
data.size());
875 uint32_t bank_header_data_size =
GetU32(&e->
data[off]);
876 uint32_t bank_header_flags =
GetU32(&e->
data[off+4]);
880 if (bank_header_data_size + 8 != e->
data_size) {
881 fprintf(stderr,
"TMEvent::FindFirstBank: error: bank header size %d mismatch against data size %d\n", (
int)bank_header_data_size, (
int)e->
data_size);
892 static char xchar(
char c)
894 if (c>=
'0' && c<=
'9')
896 if (c>=
'a' && c<=
'z')
898 if (c>=
'A' && c<=
'Z')
909 size_t remaining = e->
data.size() - pos;
913 if (remaining == 0) {
920 fprintf(stderr,
"TMEvent::FindNextBank: error: too few bytes %d remaining at the end of event\n", (
int)remaining);
926 size_t ibank = e->
banks.size();
927 e->
banks.resize(ibank+1);
938 size_t data_offset = 0;
946 data_offset = pos+4+4+4+4;
951 data_offset = pos+4+4+4;
956 data_offset = pos+4+2+2;
964 fprintf(stderr,
"TMEvent::FindNextBank: error: invalid tid %d\n", b->
type);
973 size_t npos = data_offset + aligned_data_size;
977 if (npos > e->
data.size()) {
978 fprintf(stderr,
"TMEvent::FindNextBank: error: invalid bank data size %d: aligned %d, npos %d, end of event %d\n", b->
data_size, (
int)aligned_data_size, (
int)npos, (
int)e->
data.size());
1049 for (
unsigned i=0; i<
banks.size(); i++) {
1050 if (
banks[i].name == bank_name)
1071 if (pos>0 && b && bank_name) {
1072 if (b->
name == bank_name)
1094 printf(
"Event: id 0x%04x, mask 0x%04x, serial 0x%08x, time 0x%08x, data size %d, vector size %d, capacity %d\n",
1101 (
int)
data.capacity()
1109 printf(
"%d banks:", (
int)
banks.size());
1110 for (
size_t i=0; i<
banks.size(); i++) {
1111 printf(
" %s",
banks[i].name.c_str());
1116 for (
size_t i=0; i<
banks.size(); i++) {
1117 printf(
"bank %3d: name \"%s\", tid %2d, data_size %8d\n",
1119 banks[i].name.c_str(),
1121 banks[i].data_size);
1125 for (
size_t j=0; j<
banks[i].data_size; j+=4) {
1126 printf(
"%11d: 0x%08x\n", (
int)j, *(uint32_t*)(p+j));
1136 const char* p =
data.data();
1139 printf(
" 0: 0x%08x\n",
GetU32(p+0*4));
1140 printf(
" 1: 0x%08x\n",
GetU32(p+1*4));
1141 printf(
" 2: 0x%08x\n",
GetU32(p+2*4));
1142 printf(
" 3: 0x%08x (0x%08x and 0x%08x-0x10)\n",
GetU32(p+3*4),
data_size, (
int)
data.size());
1145 printf(
" 4: 0x%08x\n",
GetU32(p+4*4));
ErrorReader(const char *filename)
int Read(void *buf, int count)
FileReader(const char *filename)
int Read(void *buf, int count)
int Write(const void *buf, int count)
FileWriter(const char *filename)
Lz4Reader(TMReaderInterface *reader)
LZ4F_decompressionContext_t fContext
TMReaderInterface * fReader
void AllocSrcBuf(int size)
int Read(void *buf, int count)
int Read(void *buf, int count)
PipeReader(const char *pipename)
uint32_t type
type of bank data, enum of TID_xxx
uint32_t data_size
size of bank data in bytes
size_t data_offset
offset of data for this bank in the event data[] container
std::string name
bank name, 4 characters max
std::string BankListToString() const
print the list of MIDAS banks
void FindAllBanks()
scan the MIDAS event, find all data banks
std::string HeaderToString() const
print the MIDAS event header
TMBank * FindBank(const char *bank_name)
scan the MIDAS event
bool found_all_banks
all the banks in the event data have been discovered
std::vector< TMBank > banks
list of MIDAS banks, fill using FindAllBanks()
void Reset()
reset everything
void PrintBanks(int level=0)
void AddBank(const char *bank_name, int tid, const char *buf, size_t size)
add new MIDAS bank
char * GetEventData()
get pointer to MIDAS event data
void Init(uint16_t event_id, uint16_t trigger_mask=0, uint32_t serial_number=0, uint32_t time_stamp=0, size_t capacity=0)
uint32_t time_stamp
MIDAS event time stamp (unix time in sec)
size_t bank_scan_position
location where scan for MIDAS banks was last stopped
uint32_t bank_header_flags
flags from the MIDAS event bank header
void ParseHeader(const void *buf, size_t buf_size)
parse event header
void ParseEvent()
parse event data
std::vector< char > data
MIDAS event bytes.
size_t event_header_size
size of MIDAS event header
uint32_t serial_number
MIDAS event serial number.
uint32_t data_size
MIDAS event data size.
uint16_t trigger_mask
MIDAS trigger mask.
uint16_t event_id
MIDAS event ID.
char * GetBankData(const TMBank *)
get pointer to MIDAS data bank
bool error
event has an error - incomplete, truncated, inconsistent or corrupted
std::string BankToString(const TMBank *) const
print definition of one MIDAS bank
virtual int Read(void *buf, int count)=0
virtual int Write(const void *buf, int count)=0
size_t LZ4F_decompress(LZ4F_decompressionContext_t dctx, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const LZ4F_decompressOptions_t *dOptPtr)
LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t *dctxPtr, unsigned version)
LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t dctx)
unsigned LZ4F_isError(LZ4F_errorCode_t code)
const char * LZ4F_getErrorName(LZ4F_errorCode_t code)
static size_t FindFirstBank(TMEvent *e)
static int ReadPipe(FILE *fp, char *buf, int length)
void TMWriteEvent(TMWriterInterface *writer, const TMEvent *event)
TMReaderInterface * TMNewReader(const char *source)
static std::string to_string(int v)
static std::string Lz4Error(int errorCode)
static void PutU32(char *ptr, uint32_t v)
static uint32_t GetU32(const void *ptr)
static size_t FindNextBank(TMEvent *e, size_t pos, TMBank **pb)
TMWriterInterface * TMNewWriter(const char *destination)
static void PutU16(char *ptr, uint16_t v)
static std::string Errno(const char *s)
static int hasSuffix(const char *name, const char *suffix)
static uint16_t GetU16(const void *ptr)
TMEvent * TMReadEvent(TMReaderInterface *reader)
static size_t Align8(size_t size)