UniRec 3.0.0
Loading...
Searching...
No Matches
unirecRecord.hpp
Go to the documentation of this file.
1
10#pragma once
11
12#include "unirecArray.hpp"
13#include "unirecRecordView.hpp"
14#include "unirecTypeTraits.hpp"
15#include "unirecTypes.hpp"
16
17#include <cstddef>
18#include <exception>
19#include <numeric>
20#include <string>
21#include <type_traits>
22#include <unirec/unirec.h>
23#include <vector>
24
25namespace NemeaPlusPlus {
26
34public:
41 : m_recordSize(0)
42 , m_recordData(nullptr)
43 , m_unirecTemplate(nullptr)
44 {
45 }
46
56 UnirecRecord(ur_template_t* unirecTemplate, size_t maxVariableFieldsSize = UR_MAX_SIZE)
57 : m_recordSize(maxVariableFieldsSize)
58 , m_unirecTemplate(unirecTemplate)
59 {
60 m_recordData = ur_create_record(unirecTemplate, maxVariableFieldsSize);
61 if (!m_recordData) {
62 throw std::runtime_error("Allocation of UniRec record failed");
63 }
64 }
65
66 void copyFieldsFrom(const UnirecRecord& otherRecord)
67 {
69 throw std::runtime_error(
70 "UnirecRecord::copyFieldsFrom() has failed. Record has no template or allocated "
71 "memory!");
72 }
73
74 // TODO: check sufficient record size
75
76 if (otherRecord.m_recordData != nullptr) {
80 otherRecord.m_unirecTemplate,
81 otherRecord.m_recordData);
82 }
83 }
84
85 void copyFieldsFrom(const UnirecRecordView& otherRecordView)
86 {
88 throw std::runtime_error(
89 "UnirecRecord::copyFieldsFrom() has failed. Record has no template or allocated "
90 "memory!");
91 }
92
93 // TODO: check sufficient record size
94
95 if (otherRecordView.m_recordData != nullptr) {
99 otherRecordView.m_unirecTemplate,
100 otherRecordView.m_recordData);
101 }
102 }
103
111
117 const void* data() const noexcept { return m_recordData; }
118
124 size_t size() const noexcept { return ur_rec_size(m_unirecTemplate, m_recordData); }
125
154 template<typename T>
156 {
157 using BaseType = typename std::remove_cv_t<
158 typename std::remove_pointer_t<typename std::remove_reference_t<T>>>;
159
160 checkDataTypeCompatibility<T>(fieldID);
161
162 if constexpr (is_string_v<T>) {
163 return getFieldAsStringType<T>(fieldID);
164 } else if constexpr (std::is_pointer_v<T>) {
165 return getFieldAsPointer<T>(fieldID);
166 } else if constexpr (std::is_reference_v<T>) {
167 return getFieldAsReference<BaseType>(fieldID);
168 } else {
169 return getFieldAsValue<T>(fieldID);
170 }
171 }
172
188 template<typename T>
190 {
191 return UnirecArray<T>(
192 static_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID)),
194 ur_get_type(fieldID));
195 }
196
222 template<typename T>
223 UnirecArray<T> reserveUnirecArray(size_t elementsCount, ur_field_id_t fieldID)
224 {
225 int retCode = ur_array_allocate(m_unirecTemplate, m_recordData, fieldID, elementsCount);
226 if (retCode != UR_OK) {
227 throw std::runtime_error("Unable to allocate memory for UnirecArray");
228 }
229
230 return UnirecArray<T>(
231 static_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID)),
232 elementsCount,
233 fieldID);
234 }
235
250 template<typename T>
251 void setFieldFromType(const T& fieldData, ur_field_id_t fieldID)
252 {
253 if constexpr (is_string_v<T>) {
254 ur_set_string(m_unirecTemplate, m_recordData, fieldID, fieldData.data());
255 } else {
256 *static_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID)) = fieldData;
257 }
258 }
259
269 template<typename T>
270 void setFieldFromUnirecArray(const UnirecArray<T>& unirecArray, ur_field_id_t fieldID)
271 {
272 checkDataTypeCompatibility<T>(fieldID);
273
274 if (ur_is_array(fieldID)) {
275 ur_array_allocate(m_unirecTemplate, m_recordData, fieldID, unirecArray.size());
276 std::copy(
277 unirecArray.begin(),
278 unirecArray.end(),
279 static_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID)));
280 } else {
281 setFieldFromType<T>(unirecArray.at(0), fieldID);
282 }
283 }
284
285 UnirecRecord(const UnirecRecord& other) { copyFrom(other); }
286
288 {
289 if (&other == this) {
290 return *this;
291 }
292
293 if (m_recordData != nullptr) {
295 m_recordData = nullptr;
296 }
297
298 copyFrom(other);
299 return *this;
300 }
301
314 template<typename T>
315 void setFieldFromVector(const std::vector<T>& sourceVector, ur_field_id_t fieldID)
316 {
317 checkDataTypeCompatibility<T>(fieldID);
318
319 if (!ur_is_array(fieldID)) {
320 throw std::runtime_error("Cannot set vector to non-array unirec field");
321 }
322
323 ur_array_allocate(m_unirecTemplate, m_recordData, fieldID, sourceVector.size());
324 std::copy(
325 sourceVector.begin(),
326 sourceVector.end(),
327 static_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID)));
328 }
329
330private:
331 template<typename T>
333 {
334 using BaseType = typename std::remove_cv_t<
335 typename std::remove_pointer_t<typename std::remove_reference_t<T>>>;
336 using RequiredType = typename std::conditional_t<is_string_v<BaseType>, T, BaseType>;
337
338 ur_field_type_t expectedType;
339 if (ur_is_array(fieldID)) {
340 expectedType = getExpectedUnirecType<RequiredType*>();
341 } else {
342 expectedType = getExpectedUnirecType<RequiredType*>();
343 }
344
345 if (expectedType != ur_get_type(fieldID)) {
346 throw std::runtime_error(
347 "UnirecRecord data type format mismatch: " + std::string(typeid(T).name()));
348 }
349 }
350
351 template<typename T>
353 {
354 return T(
355 static_cast<const char*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID)),
357 }
358
359 template<typename T>
361 {
362 return static_cast<T>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID));
363 }
364
365 template<typename T>
367 {
368 return *reinterpret_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID));
369 }
370
371 template<typename T>
373 {
374 return *static_cast<T*>(ur_get_ptr_by_id(m_unirecTemplate, m_recordData, fieldID));
375 }
376
377 void copyFrom(const UnirecRecord& other)
378 {
381 if (other.m_recordData != nullptr) {
384 if (!m_recordData) {
385 throw std::runtime_error("Allocation of UniRec record failed");
386 }
387 }
388 }
389
391
394};
395
396} // namespace NemeaPlusPlus
A wrapper class for a contiguous array of values with the same unirec fieldID.
Definition: unirecArray.hpp:30
constexpr T & at(size_t pos) const
Returns a reference to the element at the specified position in the UniRec field array,...
constexpr Iterator begin() const noexcept
Returns an iterator to the first element of the UniRec field array.
Definition: unirecArray.hpp:94
constexpr Iterator end() const noexcept
Returns an iterator to the element following the last element of the UniRec field array.
constexpr size_t size() const noexcept
Returns the number of elements in the UniRec field array.
Definition: unirecArray.hpp:89
Provides a view into a UniRec record.
A class for working with UniRec records and their fields.
UnirecRecord(const UnirecRecord &other)
void copyFrom(const UnirecRecord &other)
UnirecRecord(ur_template_t *unirecTemplate, size_t maxVariableFieldsSize=UR_MAX_SIZE)
Constructor with template and maximum variable fields size.
void setFieldFromUnirecArray(const UnirecArray< T > &unirecArray, ur_field_id_t fieldID)
Sets the value of a UniRec field using a UnirecArray.
T getFieldAsReference(ur_field_id_t fieldID) const
UnirecArray< T > reserveUnirecArray(size_t elementsCount, ur_field_id_t fieldID)
Reserves memory for a UniRecArray within a UniRec field.
void copyFieldsFrom(const UnirecRecord &otherRecord)
T getFieldAsValue(ur_field_id_t fieldID) const
void copyFieldsFrom(const UnirecRecordView &otherRecordView)
UnirecArray< T > getFieldAsUnirecArray(ur_field_id_t fieldID)
Gets a UniRecArray representing a UniRec field.
UnirecRecord()
Default constructor.
UnirecRecord & operator=(const UnirecRecord &other)
size_t size() const noexcept
Returns the size of the UniRec record.
T getFieldAsStringType(ur_field_id_t fieldID) const
T getFieldAsPointer(ur_field_id_t fieldID) const
void setFieldFromVector(const std::vector< T > &sourceVector, ur_field_id_t fieldID)
Sets the value of a UniRec array field using a vector of values.
T getFieldAsType(ur_field_id_t fieldID) const
Gets the value of a UniRec field and converts it to the specified type.
ur_template_t * m_unirecTemplate
void checkDataTypeCompatibility(ur_field_id_t fieldID) const
void setFieldFromType(const T &fieldData, ur_field_id_t fieldID)
Sets the value of a UniRec field using data of a specified type.
const void * data() const noexcept
Returns a pointer to the data of the UniRec record.
#define ur_set_string(tmplt, rec, field_id, str)
Set variable-length field to given string. Set contents of a variable-length field in the record....
Definition: unirec.h:517
#define ur_array_allocate(tmplt, rec, field_id, elem_cnt)
Preallocates UniRec array field to have requested number of elements.
Definition: unirec.h:629
#define ur_is_array(field_id)
Definition: unirec.h:526
#define ur_rec_size(tmplt, rec)
Get size of UniRec record (static and variable length) Get total size of whole UniRec record.
Definition: unirec.h:680
#define UR_MAX_SIZE
Definition: unirec.h:1013
void * ur_create_record(const ur_template_t *tmplt, uint16_t max_var_size)
Definition: unirec.c:1220
#define ur_get_var_len(tmplt, rec, field_id)
Get size of a variable sized field in the record. Get size of a variable-length field in the record....
Definition: unirec.h:474
#define ur_array_get_elem_cnt(tmplt, rec, field_id)
Get number of elements stored in an UniRec array.
Definition: unirec.h:546
void ur_copy_fields(const ur_template_t *dst_tmplt, void *dst, const ur_template_t *src_tmplt, const void *src)
Copy data from one UniRec record to another. Copies all fields present in both templates from src to ...
Definition: unirec.c:1259
#define ur_get_type(field_id)
Get type of UniRec field Get type of any UniRec defined field.
Definition: unirec.h:388
void ur_free_record(void *record)
Definition: unirec.c:1229
#define ur_get_ptr_by_id(tmplt, data, field_id)
Get pointer to UniRec field Get pointer to fixed or varible length UniRec field. In contrast to ur_ge...
Definition: unirec.h:442
Header file containing the definition of the UnirecArray class and its Iterator subclass.
Provides a view into a UniRec record.
Provides a set of type traits and aliases for working with unirec++.
This file contains functions for determining the expected UniRec type for various C++ types.
Definition of UniRec structures and functions.
ur_field_type_t
Definition: unirec.h:95
int16_t ur_field_id_t
Type of UniRec field identifiers.
Definition: unirec.h:136
#define UR_OK
No problem.
Definition: unirec.h:90
UniRec template. It contains a table mapping a field to its position in an UniRec record.
Definition: unirec.h:191