HepMC3 event record library
Readerprotobuf.cc
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of HepMC
4// Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details)
5//
6/**
7 * @file Readerprotobuf.cc
8 * @brief Implementation of \b class Readerprotobuf
9 *
10 */
12
13#include "HepMC3/Print.h"
14#include "HepMC3/Version.h"
15
17
18#include <fcntl.h>
19#include <sys/stat.h>
20
21#include <cstring>
22
23namespace HepMC3 {
24
25/// @brief Header of the protobuf file
26std::string const ProtobufMagicHeader = "hmpb";
27/// @brief Size of the protobuf file header
28size_t const ProtobufMagicHeaderBytes = 4;
29
30HEPMC3_DECLARE_READER_FILE(Readerprotobuf)
31HEPMC3_DECLARE_READER_STREAM(Readerprotobuf)
32HEPMC3_DECLARE_READER_SPSTREAM(Readerprotobuf)
33
34/// @brief Constant
35static size_t const MDBytesLength = 10;
36
37Readerprotobuf::Readerprotobuf(const std::string &filename) {
38
39 int fd = open(filename.c_str(), O_RDONLY);
40 if (fd < 0) {
41 HEPMC3_ERROR_LEVEL(100,"Readerprotobuf: Problem opening file: " << filename)
42 perror(filename.c_str());
43 return;
44 }
45
46 m_inf_zcstream = std::unique_ptr<google::protobuf::io::FileInputStream>(
47 new google::protobuf::io::FileInputStream(fd));
48 // We don't need to worry about closing fd
49 m_inf_zcstream->SetCloseOnDelete(true);
50
51 if (m_inf_zcstream->GetErrno()) {
52 HEPMC3_ERROR_LEVEL(100,"Readerprotobuf: Problem opening file: "<< filename << "\n"<< strerror(m_inf_zcstream->GetErrno()))
53 m_inf_zcstream.reset();
54 return;
55 }
56
58
60}
61
62Readerprotobuf::Readerprotobuf(std::istream &stream) : m_in_stream(&stream) {
63
64 if (!stream.good()) {
65 HEPMC3_ERROR_LEVEL(100,"Cannot initialize Readerprotobuf on istream which is not good().")
66 return;
67 }
68
69 m_in_zcistream = std::unique_ptr<google::protobuf::io::IstreamInputStream>(
70 new google::protobuf::io::IstreamInputStream(&stream));
72
74}
75
76Readerprotobuf::Readerprotobuf(std::shared_ptr<std::istream> stream)
77 : Readerprotobuf(*stream) {
78 m_shared_stream = stream;
79}
80
82
83 const void *MagicIntro = nullptr;
84 int nbytes = 0;
85 m_in_zcstream->Next(&MagicIntro, &nbytes);
86
87 // Check the first four bytes it should read "hmpb"
88 if (strncmp(static_cast<const char *>(MagicIntro),
90 HEPMC3_ERROR_LEVEL(100,"Failed to find expected Magic first "<< ProtobufMagicHeaderBytes<< " bytes, is this really a hmpb file?")
91 return false;
92 }
93
94 // needed to read ProtobufMagicHeaderBytes, but read nbytes, back up
96
97 if (!read_Header()) {
98 HEPMC3_ERROR_LEVEL(100,"Readerprotobuf: Problem parsing start of file, expected to find Header, but instead found message type: "<< m_md_pb.message_type())
99 return false;
100 }
101
102 if (!read_GenRunInfo()) {
103 HEPMC3_ERROR_LEVEL(100,"Readerprotobuf: Problem parsing start of file, expected to find RunInfo, but instead found message type: "<< m_md_pb.message_type())
104 return false;
105 }
106
107 return true;
108}
109
111 if (failed()) {
112 return false;
113 }
114
115 if (!m_md_pb.ParseFromBoundedZeroCopyStream(m_in_zcstream, MDBytesLength)) {
116 return false;
117 }
118
119 if (failed()) {
120 return false;
121 }
122
123 // close the stream if we have read to the end of the file
124 if (m_md_pb.message_type() == HepMC3_pb::MessageDigest::Footer) {
125 close();
126 }
127
128 return true;
129}
130
132 if (!read_digest()) {
133 return false;
134 }
135
136 if (m_md_pb.message_type() != HepMC3_pb::MessageDigest::Header) {
137 return false;
138 }
139
140 if (!m_hdr_pb.ParseFromBoundedZeroCopyStream(m_in_zcstream,
141 m_md_pb.bytes())) {
142 // if we fail to read a message then close the stream to indicate failed
143 // state
144 close();
145 return false;
146 }
147
148 return true;
149}
150
152 if (!read_digest()) {
153 return false;
154 }
155
156 if (m_md_pb.message_type() != HepMC3_pb::MessageDigest::RunInfo) {
157 return false;
158 }
159
160 set_run_info(std::make_shared<HepMC3::GenRunInfo>());
161
162 if (!m_gri_pb.ParseFromBoundedZeroCopyStream(m_in_zcstream,
163 m_md_pb.bytes())) {
164 close();
165 return false;
166 }
167
168 Deserialize::FillGenRunInfo(m_gri_pb, run_info());
169
170 return true;
171}
172
173bool Readerprotobuf::read_GenEvent(bool /*skip*/, GenEvent &evt) {
174 if (!read_digest()) {
175 return false;
176 }
177
178 if (m_md_pb.message_type() != HepMC3_pb::MessageDigest::Event) {
179 return false;
180 }
181
182 if (!m_evt_pb.ParseFromBoundedZeroCopyStream(m_in_zcstream,
183 m_md_pb.bytes())) {
184 close();
185 return false;
186 }
187
188 evt.read_data(m_evt_pb);
189
190 return true;
191}
192
193bool Readerprotobuf::skip(const int n) {
194 static HepMC3::GenEvent dummyev;
195 for (int nn = n; nn > 0; --nn) {
196 if (!read_GenEvent(true, dummyev)) {
197 return false;
198 }
199 }
200 return !failed();
201}
202
204
205 if (!read_GenEvent(false, evt)) {
206 return false;
207 }
208
209 evt.set_run_info(run_info());
210
211 return true;
212}
213
215 if (m_inf_zcstream) {
216 m_inf_zcstream.reset();
217 }
218 if (m_in_zcistream) {
219 m_in_zcistream.reset();
220 }
221 m_in_stream = nullptr;
222}
223
225 if (m_inf_zcstream) {
226 return m_inf_zcstream->GetErrno();
227 }
228 return !m_in_stream;
229}
230
231} // namespace HepMC3
#define HEPMC3_ERROR_LEVEL(LEVEL, MESSAGE)
Macro for printing error messages.
Definition Errors.h:27
Definition of static class Print.
Definition of class Readerprotobuf.
Declaration of the Verrion functions and some macros.
Stores event-related information.
Definition GenEvent.h:47
void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the GenRunInfo object by smart pointer.
Definition GenEvent.h:148
void read_data(const GenEventData &data)
Fill GenEvent based on GenEventData.
virtual void set_run_info(std::shared_ptr< GenRunInfo > run)
Set the global GenRunInfo object.
Definition Reader.h:56
virtual std::shared_ptr< GenRunInfo > run_info() const
Get the global GenRunInfo object.
Definition Reader.h:44
GenEvent I/O parsing and serialization for protobuf-based binary files.
HepMC3_pb::GenRunInfoData m_gri_pb
GenRunInfo data.
bool read_event(GenEvent &evt) override
Read event from file.
std::istream * m_in_stream
The stream object that is read from.
bool failed() override
Get stream error state.
Readerprotobuf(const std::string &filename)
filename constructor
HepMC3_pb::MessageDigest m_md_pb
Message digest.
bool skip(const int n) override
skips the next n events
HepMC3_pb::Header m_hdr_pb
Header.
void close() override
Close file stream.
bool read_GenEvent(bool skip, GenEvent &evt)
Parse the next protobuf message as a GenEvent message.
HepMC3_pb::GenEventData m_evt_pb
GenEventInfo data.
std::unique_ptr< google::protobuf::io::IstreamInputStream > m_in_zcistream
Stream input.
bool read_digest()
Read the next protobuf message digest.
bool read_GenRunInfo()
Parse the next protobuf message as a GenRunInfo message.
std::unique_ptr< google::protobuf::io::FileInputStream > m_inf_zcstream
File input.
bool read_Header()
Parse the next protobuf message as a Header message.
bool read_file_start()
Parse the front matter of the protobuf message stream before the events.
std::shared_ptr< std::istream > m_shared_stream
Passed in shared_ptr to an input stream.
google::protobuf::io::ZeroCopyInputStream * m_in_zcstream
Zero copy input stream.
HepMC3 main namespace.
static size_t const MDBytesLength
Constant.
size_t const ProtobufMagicHeaderBytes
Size of the protobuf file header.
std::string const ProtobufMagicHeader
Header of the protobuf file.
Definition of utility functions for protobufIO.