UniRec  3.0.0
bidirectionalInterface.cpp
Go to the documentation of this file.
1 
11 
12 #include <libtrap/trap.h>
13 
14 namespace NemeaPlusPlus {
15 
17 {
18  if (m_sendEoFonExit) {
19  sendEoF();
20  }
21 
23 }
24 
26  uint8_t inputInterfaceID,
27  uint8_t outputInterfaceID)
28  : m_template(nullptr)
29  , m_inputInterfaceID(inputInterfaceID)
30  , m_outputInterfaceID(outputInterfaceID)
31  , m_prioritizedDataPointer(nullptr)
32  , m_sendEoFonExit(true)
33  , m_EoFOnNextReceive(false)
34 {
36 }
37 
38 std::optional<UnirecRecordView> UnirecBidirectionalInterface::receive()
39 {
40  const void* receivedData;
41  uint16_t dataSize = 0;
42 
43  if (isEoFReceived()) {
44  throw EoFException();
45  }
46 
48  receivedData = m_prioritizedDataPointer;
49  m_prioritizedDataPointer = nullptr;
50  return UnirecRecordView(receivedData, m_template);
51  }
52 
53  int errorCode = trap_recv(m_inputInterfaceID, &receivedData, &dataSize);
54  if (errorCode == TRAP_E_TIMEOUT) {
55  return std::nullopt;
56  }
57  if (errorCode == TRAP_E_FORMAT_CHANGED) {
58  m_prioritizedDataPointer = receivedData;
59  throw FormatChangeException();
60  }
61  handleReceiveErrorCodes(errorCode);
62 
63  if (dataSize <= 1) {
64  m_EoFOnNextReceive = true;
65  }
66 
67  return UnirecRecordView(receivedData, m_template);
68 }
69 
71 {
72  return m_EoFOnNextReceive;
73 }
74 
76 {
77  if (errorCode == TRAP_E_OK) {
78  return;
79  }
80  if (errorCode == TRAP_E_NOT_INITIALIZED) {
81  throw std::runtime_error(
82  "UnirecBidirectionalInterface::receive() has failed. Trap interface is not "
83  "initialized.");
84  }
85  if (errorCode == TRAP_E_TERMINATED) {
86  throw std::runtime_error(
87  "UnirecBidirectionalInterface::receive() has failed. Trap interface is terminated.");
88  }
89  if (errorCode == TRAP_E_NOT_SELECTED) {
90  throw std::runtime_error(
91  "UnirecBidirectionalInterface::receive() has failed. Interface ID out of range.");
92  }
93  throw std::runtime_error(
94  "UnirecBidirectionalInterface::receive() has failed. Return code: "
95  + std::to_string(errorCode) + ", msg: " + trap_last_error_msg);
96 }
97 
98 void UnirecBidirectionalInterface::setRequieredFormat(const std::string& templateSpecification)
99 {
100  int ret
101  = trap_set_required_fmt(m_inputInterfaceID, TRAP_FMT_UNIREC, templateSpecification.c_str());
102  if (ret != TRAP_E_OK) {
103  throw std::runtime_error(
104  "UnirecBidirectionalInterface::setRequieredFormat() has failed. Unable to set required "
105  "format.");
106  }
107 }
108 
110 {
111  trap_ifcctl(TRAPIFC_INPUT, m_inputInterfaceID, TRAPCTL_SETTIMEOUT, timeout);
112 }
113 
115 {
116  uint8_t dataType;
117  const char* spec = nullptr;
118 
119  int ret = trap_get_data_fmt(TRAPIFC_INPUT, m_inputInterfaceID, &dataType, &spec);
120  if (ret != TRAP_E_OK) {
121  throw std::runtime_error(
122  "UnirecBidirectionalInterface::changeTemplate() has failed. Data format was not "
123  "loaded.");
124  }
125 
127  if (m_template == nullptr) {
128  throw std::runtime_error(
129  "UnirecBidirectionalInterface::changeTemplate() has failed. Template could not be "
130  "edited.");
131  }
132 
133  std::string specCopy = spec;
134  trap_set_data_fmt(m_outputInterfaceID, TRAP_FMT_UNIREC, specCopy.c_str());
135 
137  if (ret != TRAP_E_OK) {
138  throw std::runtime_error("UnirecBidirectionalInterface::changeTemplate() has failed.");
139  }
140 
142  if (ret != TRAP_E_OK) {
143  throw std::runtime_error("UnirecBidirectionalInterface::changeTemplate() has failed.");
144  }
145 
147 }
148 
150 {
151  return UnirecRecord(m_template, maxVariableFieldsSize);
152 }
153 
155 {
156  int errorCode = trap_send(m_outputInterfaceID, unirecRecord.data(), unirecRecord.size());
157  return handleSendErrorCodes(errorCode);
158 }
159 
161 {
162  int errorCode
163  = trap_send(m_outputInterfaceID, unirecRecordView.data(), unirecRecordView.size());
164  return handleSendErrorCodes(errorCode);
165 }
166 
168 {
169  if (errorCode == TRAP_E_TIMEOUT) {
170  return false;
171  }
172  if (errorCode == TRAP_E_OK) {
173  return true;
174  }
175  if (errorCode == TRAP_E_NOT_INITIALIZED) {
176  throw std::runtime_error(
177  "UnirecBidirectionalInterface::send() has failed. Trap interface is not initialized.");
178  }
179  if (errorCode == TRAP_E_TERMINATED) {
180  throw std::runtime_error(
181  "UnirecBidirectionalInterface::send() has failed. Trap interface is terminated.");
182  }
183  if (errorCode == TRAP_E_BAD_IFC_INDEX) {
184  throw std::runtime_error(
185  "UnirecBidirectionalInterface::send() has failed. Interface ID out of range.");
186  }
187  throw std::runtime_error(
188  "UnirecBidirectionalInterface::send() has failed. Return code: " + std::to_string(errorCode)
189  + ", msg: " + trap_last_error_msg);
190 }
191 
193 {
194  trap_send_flush(m_outputInterfaceID);
195 }
196 
198 {
199  m_sendEoFonExit = false;
200 }
201 
203 {
204  trap_ifcctl(TRAPIFC_OUTPUT, m_outputInterfaceID, TRAPCTL_SETTIMEOUT, timeout);
205 }
206 
208 {
209  trap_ifcctl(TRAPIFC_OUTPUT, m_outputInterfaceID, TRAPCTL_AUTOFLUSH_TIMEOUT, timeout);
210 }
211 
213 {
214  char dummy[1] = {0};
215  trap_send(m_outputInterfaceID, dummy, sizeof(dummy));
216 }
217 
218 } // namespace NemeaPlusPlus
Defines a bidirectional interface for sending and receiving unirec records using the TRAP interface p...
An exception that is thrown when the end of the input stream is reached.
An exception that is thrown when the record format changes.
UnirecBidirectionalInterface(uint8_t inputInterfaceID, uint8_t outputInterfaceID)
void sendFlush() const
Flushes any pending UniRec records in the Trap interface.
UnirecRecord createUnirecRecord(size_t maxVariableFieldsSize=UR_MAX_SIZE)
Creates a new UniRec record with the specified maximum variable fields size.
void setSendAutoflushTimeout(int timeout)
Sets the autoflush timeout for the output Trap interface.
~UnirecBidirectionalInterface()
Destructor for the UnirecBidirectionalInterface class.
std::optional< UnirecRecordView > receive()
Receives data from the interface and returns an optional UnirecRecordView object.
void setRequieredFormat(const std::string &templateSpecification)
Sets the required Unirec format specification.
void doNotsendEoFOnExit()
Disables sending an end-of-file marker on exit.
bool send(UnirecRecord &unirecRecord) const
Sends a UniRec record through the Trap interface.
void setSendTimeout(int timeout)
Sets the send timeout for the Trap interface.
void setReceiveTimeout(int timeout)
Sets the receive timeout for the interface. This method sets the timeout for receiving UniRec records...
void changeTemplate()
Changes the Unirec template used by the bidirectional interface.
Provides a view into a UniRec record.
size_t size() const noexcept
Returns the size of the UniRec record.
const void * data() const noexcept
Returns a const pointer to the data of the UniRec record.
A class for working with UniRec records and their fields.
size_t size() const noexcept
Returns the size of the UniRec record.
const void * data() const noexcept
Returns a pointer to the data of the UniRec record.
ur_template_t * ur_define_fields_and_update_template(const char *ifc_data_fmt, ur_template_t *tmplt)
Defined new fields and expand an UniRec template Define new fields (function ur_define_set_of_fields)...
Definition: unirec.c:616
#define ur_set_output_template(ifc, tmplt)
Set UniRec template to ouput interface.
Definition: unirec.h:847
void ur_free_template(ur_template_t *tmplt)
Destroy UniRec template Free all memory allocated for a template created previously by ur_create_temp...
Definition: unirec.c:1094
#define ur_set_input_template(ifc, tmplt)
Set UniRec template to input interface.
Definition: unirec.h:863