Program Listing for File common.h
↰ Return to documentation for file (include/libcaer/events/common.h
)
#ifndef LIBCAER_EVENTS_COMMON_H_
#define LIBCAER_EVENTS_COMMON_H_
#include "../libcaer.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CAER_EVENTS_HEADER_ONLY
# define caerLogEHO caerLog
#else
static inline void caerLogEHO(enum caer_log_level logLevel, const char *subSystem, const char *format, ...) {
// Ignore logLevel, all event packet messages are critical.
(void) (logLevel);
printf("%s: ", subSystem);
va_list argumentList;
va_start(argumentList, format);
vprintf(format, argumentList);
va_end(argumentList);
printf("\n");
}
#endif
#define VALID_MARK_SHIFT 0
#define VALID_MARK_MASK 0x00000001
#define TS_OVERFLOW_SHIFT 31
enum caer_default_event_types {
SPECIAL_EVENT = 0,
POLARITY_EVENT = 1,
FRAME_EVENT = 2,
IMU6_EVENT = 3,
IMU9_EVENT = 4,
SAMPLE_EVENT = 5,
EAR_EVENT = 6,
CONFIG_EVENT = 7,
POINT1D_EVENT = 8,
POINT2D_EVENT = 9,
POINT3D_EVENT = 10,
POINT4D_EVENT = 11,
SPIKE_EVENT = 12,
MATRIX4x4_EVENT = 13,
};
#define CAER_DEFAULT_EVENT_TYPES_COUNT 14
#define CAER_EVENT_PACKET_HEADER_SIZE 28
PACKED_STRUCT(struct caer_event_packet_header {
int16_t eventType;
int16_t eventSource;
int32_t eventSize;
int32_t eventTSOffset;
int32_t eventTSOverflow;
int32_t eventCapacity;
int32_t eventNumber;
int32_t eventValid;
});
typedef struct caer_event_packet_header *caerEventPacketHeader;
typedef const struct caer_event_packet_header *caerEventPacketHeaderConst;
static inline int16_t caerEventPacketHeaderGetEventType(caerEventPacketHeaderConst header) {
return (I16T(le16toh(U16T(header->eventType))));
}
static inline void caerEventPacketHeaderSetEventType(caerEventPacketHeader header, int16_t eventType) {
if (eventType < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(
CAER_LOG_CRITICAL, "EventPacket Header", "Called caerEventPacketHeaderSetEventType() with negative value!");
return;
}
header->eventType = I16T(htole16(U16T(eventType)));
}
static inline int16_t caerEventPacketHeaderGetEventSource(caerEventPacketHeaderConst header) {
return (I16T(le16toh(U16T(header->eventSource))));
}
static inline void caerEventPacketHeaderSetEventSource(caerEventPacketHeader header, int16_t eventSource) {
if (eventSource < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Header",
"Called caerEventPacketHeaderSetEventSource() with negative value!");
return;
}
header->eventSource = I16T(htole16(U16T(eventSource)));
}
static inline int32_t caerEventPacketHeaderGetEventSize(caerEventPacketHeaderConst header) {
return (I32T(le32toh(U32T(header->eventSize))));
}
static inline void caerEventPacketHeaderSetEventSize(caerEventPacketHeader header, int32_t eventSize) {
if (eventSize < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(
CAER_LOG_CRITICAL, "EventPacket Header", "Called caerEventPacketHeaderSetEventSize() with negative value!");
return;
}
header->eventSize = I32T(htole32(U32T(eventSize)));
}
static inline int32_t caerEventPacketHeaderGetEventTSOffset(caerEventPacketHeaderConst header) {
return (I32T(le32toh(U32T(header->eventTSOffset))));
}
static inline void caerEventPacketHeaderSetEventTSOffset(caerEventPacketHeader header, int32_t eventTSOffset) {
if (eventTSOffset < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Header",
"Called caerEventPacketHeaderSetEventTSOffset() with negative value!");
return;
}
header->eventTSOffset = I32T(htole32(U32T(eventTSOffset)));
}
static inline int32_t caerEventPacketHeaderGetEventTSOverflow(caerEventPacketHeaderConst header) {
return (I32T(le32toh(U32T(header->eventTSOverflow))));
}
static inline void caerEventPacketHeaderSetEventTSOverflow(caerEventPacketHeader header, int32_t eventTSOverflow) {
if (eventTSOverflow < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Header",
"Called caerEventPacketHeaderSetEventTSOverflow() with negative value!");
return;
}
header->eventTSOverflow = I32T(htole32(U32T(eventTSOverflow)));
}
static inline int32_t caerEventPacketHeaderGetEventCapacity(caerEventPacketHeaderConst header) {
return (I32T(le32toh(U32T(header->eventCapacity))));
}
static inline void caerEventPacketHeaderSetEventCapacity(caerEventPacketHeader header, int32_t eventsCapacity) {
if (eventsCapacity < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Header",
"Called caerEventPacketHeaderSetEventCapacity() with negative value!");
return;
}
header->eventCapacity = I32T(htole32(U32T(eventsCapacity)));
}
static inline int32_t caerEventPacketHeaderGetEventNumber(caerEventPacketHeaderConst header) {
return (I32T(le32toh(U32T(header->eventNumber))));
}
static inline void caerEventPacketHeaderSetEventNumber(caerEventPacketHeader header, int32_t eventsNumber) {
if (eventsNumber < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Header",
"Called caerEventPacketHeaderSetEventNumber() with negative value!");
return;
}
header->eventNumber = I32T(htole32(U32T(eventsNumber)));
}
static inline int32_t caerEventPacketHeaderGetEventValid(caerEventPacketHeaderConst header) {
return (I32T(le32toh(U32T(header->eventValid))));
}
static inline void caerEventPacketHeaderSetEventValid(caerEventPacketHeader header, int32_t eventsValid) {
if (eventsValid < 0) {
// Negative numbers (bit 31 set) are not allowed!
caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Header",
"Called caerEventPacketHeaderSetEventValid() with negative value!");
return;
}
header->eventValid = I32T(htole32(U32T(eventsValid)));
}
static inline const void *caerGenericEventGetEvent(caerEventPacketHeaderConst headerPtr, int32_t n) {
// Check that we're not out of bounds.
// Accessing elements after EventNumber() but before EventCapacity() doesn't
// make any sense here for the Generic Event getter, as we only support
// reading/querying data from those events, and that would always fail for
// those empty events, as they are all zeroed out.
if (n < 0 || n >= caerEventPacketHeaderGetEventNumber(headerPtr)) {
caerLogEHO(CAER_LOG_CRITICAL, "Generic Event",
"Called caerGenericEventGetEvent() with invalid event offset %" PRIi32
", while maximum allowed value is %" PRIi32 ". Negative values are not allowed!",
n, caerEventPacketHeaderGetEventNumber(headerPtr) - 1);
return (NULL);
}
// Return a pointer to the specified event.
return (((const uint8_t *) headerPtr)
+ (CAER_EVENT_PACKET_HEADER_SIZE + U64T(n * caerEventPacketHeaderGetEventSize(headerPtr))));
}
static inline int32_t caerGenericEventGetTimestamp(const void *eventPtr, caerEventPacketHeaderConst headerPtr) {
return (I32T(le32toh(U32T(*(
(const int32_t *) (((const uint8_t *) eventPtr) + U64T(caerEventPacketHeaderGetEventTSOffset(headerPtr))))))));
}
static inline int64_t caerGenericEventGetTimestamp64(const void *eventPtr, caerEventPacketHeaderConst headerPtr) {
return (I64T((U64T(caerEventPacketHeaderGetEventTSOverflow(headerPtr)) << TS_OVERFLOW_SHIFT)
| U64T(caerGenericEventGetTimestamp(eventPtr, headerPtr))));
}
static inline bool caerGenericEventIsValid(const void *eventPtr) {
// Look at first byte of event memory's lowest bit.
// This should always work since first event member must contain the valid mark
// and memory is little-endian, so lowest bit must be in first byte of memory.
return (*((const uint8_t *) eventPtr) & VALID_MARK_MASK);
}
static inline bool caerGenericEventCopy(void *eventPtrDestination, const void *eventPtrSource,
caerEventPacketHeaderConst headerPtrDestination, caerEventPacketHeaderConst headerPtrSource) {
if ((caerEventPacketHeaderGetEventType(headerPtrDestination) != caerEventPacketHeaderGetEventType(headerPtrSource))
|| (caerEventPacketHeaderGetEventSize(headerPtrDestination)
!= caerEventPacketHeaderGetEventSize(headerPtrSource))
|| (caerEventPacketHeaderGetEventTSOverflow(headerPtrDestination)
!= caerEventPacketHeaderGetEventTSOverflow(headerPtrSource))) {
return (false);
}
memcpy(eventPtrDestination, eventPtrSource, (size_t) caerEventPacketHeaderGetEventSize(headerPtrDestination));
return (true);
}
#define CAER_ITERATOR_ALL_START(PACKET_HEADER, EVENT_TYPE) \
for (int32_t caerIteratorCounter = 0; caerIteratorCounter < caerEventPacketHeaderGetEventNumber(PACKET_HEADER); \
caerIteratorCounter++) { \
EVENT_TYPE caerIteratorElement = (EVENT_TYPE) caerGenericEventGetEvent(PACKET_HEADER, caerIteratorCounter);
#define CAER_ITERATOR_ALL_END }
#define CAER_ITERATOR_VALID_START(PACKET_HEADER, EVENT_TYPE) \
for (int32_t caerIteratorCounter = 0; caerIteratorCounter < caerEventPacketHeaderGetEventNumber(PACKET_HEADER); \
caerIteratorCounter++) { \
EVENT_TYPE caerIteratorElement = (EVENT_TYPE) caerGenericEventGetEvent(PACKET_HEADER, caerIteratorCounter); \
if (!caerGenericEventIsValid(caerIteratorElement)) { \
continue; \
} // Skip invalid events.
#define CAER_ITERATOR_VALID_END }
static inline int64_t caerEventPacketGetDataSize(caerEventPacketHeaderConst header) {
return (I64T(caerEventPacketHeaderGetEventSize(header)) * I64T(caerEventPacketHeaderGetEventCapacity(header)));
}
static inline int64_t caerEventPacketGetSize(caerEventPacketHeaderConst header) {
return (CAER_EVENT_PACKET_HEADER_SIZE + caerEventPacketGetDataSize(header));
}
static inline int64_t caerEventPacketGetDataSizeEvents(caerEventPacketHeaderConst header) {
return (I64T(caerEventPacketHeaderGetEventSize(header)) * I64T(caerEventPacketHeaderGetEventNumber(header)));
}
static inline int64_t caerEventPacketGetSizeEvents(caerEventPacketHeaderConst header) {
return (CAER_EVENT_PACKET_HEADER_SIZE + caerEventPacketGetDataSizeEvents(header));
}
static inline bool caerEventPacketEquals(
caerEventPacketHeaderConst firstPacket, caerEventPacketHeaderConst secondPacket) {
// If any of the packets is NULL, they can't be equal.
if (firstPacket == NULL || secondPacket == NULL) {
return (false);
}
// If both packets are the same packet (pointer equal),
// they are of course indeed equal packets.
if (firstPacket == secondPacket) {
return (true);
}
// Actually compare memory now. We compare header equality, and
// all events up to eventNumber. The remaining events up to
// eventCapacity are by definition all zeroed out, so must be
// equal, if the capacity is the same, which it is, as we check
// for that when ensuring header equality.
if (memcmp(firstPacket, secondPacket, CAER_EVENT_PACKET_HEADER_SIZE) != 0) {
return (false);
}
size_t memCmpSize
= (size_t) (caerEventPacketHeaderGetEventNumber(firstPacket) * caerEventPacketHeaderGetEventSize(firstPacket));
if (memcmp(((const uint8_t *) firstPacket) + CAER_EVENT_PACKET_HEADER_SIZE,
((const uint8_t *) secondPacket) + CAER_EVENT_PACKET_HEADER_SIZE, memCmpSize)
!= 0) {
return (false);
}
return (true);
}
static inline void caerEventPacketClear(caerEventPacketHeader packet) {
// Handle empty event packets.
if (packet == NULL) {
return;
}
// Set events up to eventNumber to zero. The remaining events up to
// eventCapacity are by definition all zeroed out, so nothing to do
// there. Also reset the eventValid and eventNumber header fields.
size_t memZeroSize
= (size_t) (caerEventPacketHeaderGetEventNumber(packet) * caerEventPacketHeaderGetEventSize(packet));
memset(((uint8_t *) packet) + CAER_EVENT_PACKET_HEADER_SIZE, 0, memZeroSize);
caerEventPacketHeaderSetEventValid(packet, 0);
caerEventPacketHeaderSetEventNumber(packet, 0);
}
static inline void caerEventPacketClean(caerEventPacketHeader packet) {
// Handle empty event packets.
if (packet == NULL) {
return;
}
// Calculate needed memory for new event packet.
int32_t eventValid = caerEventPacketHeaderGetEventValid(packet);
int32_t eventNumber = caerEventPacketHeaderGetEventNumber(packet);
// If we have no invalid events, we're already done.
if (eventValid == eventNumber) {
return;
}
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet);
int32_t eventCapacity = caerEventPacketHeaderGetEventCapacity(packet);
// Move all valid events close together. Must check every event for validity!
size_t offset = CAER_EVENT_PACKET_HEADER_SIZE;
CAER_ITERATOR_VALID_START(packet, const void *)
void *dest = ((uint8_t *) packet) + offset;
if (dest != caerIteratorElement) {
memcpy(dest, caerIteratorElement, (size_t) eventSize);
offset += (size_t) eventSize;
}
}
// Reset remaining memory, up to capacity, to zero (all events invalid).
memset(((uint8_t *) packet) + offset, 0, (size_t) ((eventCapacity - eventValid) * eventSize));
// Event capacity remains unchanged, event number shrunk to event valid number.
caerEventPacketHeaderSetEventNumber(packet, eventValid);
}
static inline caerEventPacketHeader caerEventPacketResize(caerEventPacketHeader packet, int32_t newEventCapacity) {
if (packet == NULL || newEventCapacity <= 0) {
return (NULL);
}
// Always clean for consistency with shrink case (side-effects guarantee).
caerEventPacketClean(packet);
int32_t oldEventCapacity = caerEventPacketHeaderGetEventCapacity(packet);
if (oldEventCapacity == newEventCapacity) {
// Nothing to do in this case.
return (packet);
}
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet);
size_t newEventPacketSize = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (newEventCapacity * eventSize);
// Reallocate memory used to hold events.
packet = (caerEventPacketHeader) realloc(packet, newEventPacketSize);
if (packet == NULL) {
caerLogEHO(CAER_LOG_CRITICAL, "Event Packet",
"Failed to reallocate %zu bytes of memory for resizing Event Packet of capacity %" PRIi32
" to new capacity of %" PRIi32 ". Error: %d.",
newEventPacketSize, oldEventCapacity, newEventCapacity, errno);
return (NULL);
}
if (newEventCapacity > oldEventCapacity) {
// Capacity increased: we simply zero out the newly added events.
size_t oldEventPacketSize = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (oldEventCapacity * eventSize);
memset(
((uint8_t *) packet) + oldEventPacketSize, 0, (size_t) ((newEventCapacity - oldEventCapacity) * eventSize));
}
else {
// Capacity decreased: the events were cleaned, so eventValid == eventNumber.
// They also are all together in memory. Thus we can simply keep the current
// eventValid/eventNumber counts if the capacity is still bigger or equal to
// them, or, if new capacity is smaller, we reset them to that value.
int32_t oldEventNumber = caerEventPacketHeaderGetEventNumber(packet);
if (newEventCapacity < oldEventNumber) {
caerEventPacketHeaderSetEventValid(packet, newEventCapacity);
caerEventPacketHeaderSetEventNumber(packet, newEventCapacity);
}
}
// Update capacity header field.
caerEventPacketHeaderSetEventCapacity(packet, newEventCapacity);
return (packet);
}
static inline caerEventPacketHeader caerEventPacketGrow(caerEventPacketHeader packet, int32_t newEventCapacity) {
if (packet == NULL || newEventCapacity <= 0) {
return (NULL);
}
int32_t oldEventCapacity = caerEventPacketHeaderGetEventCapacity(packet);
if (newEventCapacity <= oldEventCapacity) {
caerLogEHO(CAER_LOG_CRITICAL, "Event Packet",
"Called caerEventPacketGrow() with a new capacity value (%" PRIi32
") that is equal or smaller than the old one (%" PRIi32 "). "
"Only strictly growing an event packet is supported!",
newEventCapacity, oldEventCapacity);
return (NULL);
}
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet);
size_t newEventPacketSize = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (newEventCapacity * eventSize);
// Grow memory used to hold events.
packet = (caerEventPacketHeader) realloc(packet, newEventPacketSize);
if (packet == NULL) {
caerLogEHO(CAER_LOG_CRITICAL, "Event Packet",
"Failed to reallocate %zu bytes of memory for growing Event Packet of capacity %" PRIi32
" to new capacity of %" PRIi32 ". Error: %d.",
newEventPacketSize, oldEventCapacity, newEventCapacity, errno);
return (NULL);
}
// Zero out new event memory (all events invalid).
size_t oldEventPacketSize = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (oldEventCapacity * eventSize);
memset(((uint8_t *) packet) + oldEventPacketSize, 0, (size_t) ((newEventCapacity - oldEventCapacity) * eventSize));
// Update capacity header field.
caerEventPacketHeaderSetEventCapacity(packet, newEventCapacity);
return (packet);
}
static inline caerEventPacketHeader caerEventPacketAppend(
caerEventPacketHeader packet, caerEventPacketHeader appendPacket) {
if (packet == NULL) {
return (NULL);
}
// Support appending nothing, the result is the unmodified input.
if (appendPacket == NULL) {
return (packet);
}
// Check that the two packets are of the same type and size, and have the same TSOverflow epoch.
if ((caerEventPacketHeaderGetEventType(packet) != caerEventPacketHeaderGetEventType(appendPacket))
|| (caerEventPacketHeaderGetEventSize(packet) != caerEventPacketHeaderGetEventSize(appendPacket))
|| (caerEventPacketHeaderGetEventTSOverflow(packet) != caerEventPacketHeaderGetEventTSOverflow(appendPacket))) {
return (NULL);
}
int32_t packetEventValid = caerEventPacketHeaderGetEventValid(packet);
int32_t packetEventNumber = caerEventPacketHeaderGetEventNumber(packet);
int32_t packetEventCapacity = caerEventPacketHeaderGetEventCapacity(packet);
int32_t appendPacketEventValid = caerEventPacketHeaderGetEventValid(appendPacket);
int32_t appendPacketEventNumber = caerEventPacketHeaderGetEventNumber(appendPacket);
int32_t appendPacketEventCapacity = caerEventPacketHeaderGetEventCapacity(appendPacket);
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet); // Is the same! Checked above.
size_t newEventPacketSize
= CAER_EVENT_PACKET_HEADER_SIZE + (size_t) ((packetEventCapacity + appendPacketEventCapacity) * eventSize);
// Grow memory used to hold events.
packet = (caerEventPacketHeader) realloc(packet, newEventPacketSize);
if (packet == NULL) {
caerLogEHO(CAER_LOG_CRITICAL, "Event Packet",
"Failed to reallocate %zu bytes of memory for appending Event Packet of capacity %" PRIi32
" to Event Packet of capacity %" PRIi32 ". Error: %d.",
newEventPacketSize, appendPacketEventCapacity, packetEventCapacity, errno);
return (NULL);
}
// Copy appendPacket event memory at start of free space in packet.
memcpy(((uint8_t *) packet) + CAER_EVENT_PACKET_HEADER_SIZE + (packetEventNumber * eventSize),
((uint8_t *) appendPacket) + CAER_EVENT_PACKET_HEADER_SIZE, (size_t) (appendPacketEventNumber * eventSize));
// Zero out remaining event memory (all events invalid).
memset(((uint8_t *) packet) + CAER_EVENT_PACKET_HEADER_SIZE
+ ((packetEventNumber + appendPacketEventNumber) * eventSize),
0,
(size_t) (((packetEventCapacity + appendPacketEventCapacity) - (packetEventNumber + appendPacketEventNumber))
* eventSize));
// Update header fields.
caerEventPacketHeaderSetEventValid(packet, (packetEventValid + appendPacketEventValid));
caerEventPacketHeaderSetEventNumber(packet, (packetEventNumber + appendPacketEventNumber));
caerEventPacketHeaderSetEventCapacity(packet, (packetEventCapacity + appendPacketEventCapacity));
return (packet);
}
static inline caerEventPacketHeader caerEventPacketCopy(caerEventPacketHeaderConst packet) {
// Handle empty event packets.
if (packet == NULL) {
return (NULL);
}
// Calculate needed memory for new event packet.
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet);
int32_t eventNumber = caerEventPacketHeaderGetEventNumber(packet);
int32_t eventCapacity = caerEventPacketHeaderGetEventCapacity(packet);
size_t packetMem = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (eventSize * eventCapacity);
size_t dataMem = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (eventSize * eventNumber);
// Allocate memory for new event packet.
caerEventPacketHeader packetCopy = (caerEventPacketHeader) malloc(packetMem);
if (packetCopy == NULL) {
// Failed to allocate memory.
return (NULL);
}
// Copy the data over.
memcpy(packetCopy, packet, dataMem);
// Zero out the rest of the packet.
memset(((uint8_t *) packetCopy) + dataMem, 0, packetMem - dataMem);
return (packetCopy);
}
static inline caerEventPacketHeader caerEventPacketCopyOnlyEvents(caerEventPacketHeaderConst packet) {
// Handle empty event packets.
if (packet == NULL) {
return (NULL);
}
// Calculate needed memory for new event packet.
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet);
int32_t eventNumber = caerEventPacketHeaderGetEventNumber(packet);
if (eventNumber == 0) {
// No copy possible if result is empty (capacity=0).
return (NULL);
}
size_t packetMem = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (eventSize * eventNumber);
// Allocate memory for new event packet.
caerEventPacketHeader packetCopy = (caerEventPacketHeader) malloc(packetMem);
if (packetCopy == NULL) {
// Failed to allocate memory.
return (NULL);
}
// Copy the data over.
memcpy(packetCopy, packet, packetMem);
// Set the event capacity to the event number, since we only allocated
// memory for that many events.
caerEventPacketHeaderSetEventCapacity(packetCopy, eventNumber);
return (packetCopy);
}
static inline caerEventPacketHeader caerEventPacketCopyOnlyValidEvents(caerEventPacketHeaderConst packet) {
// Handle empty event packets.
if (packet == NULL) {
return (NULL);
}
// Calculate needed memory for new event packet.
int32_t eventSize = caerEventPacketHeaderGetEventSize(packet);
int32_t eventValid = caerEventPacketHeaderGetEventValid(packet);
if (eventValid == 0) {
// No copy possible if result is empty (capacity=0).
return (NULL);
}
size_t packetMem = CAER_EVENT_PACKET_HEADER_SIZE + (size_t) (eventSize * eventValid);
// Allocate memory for new event packet.
caerEventPacketHeader packetCopy = (caerEventPacketHeader) malloc(packetMem);
if (packetCopy == NULL) {
// Failed to allocate memory.
return (NULL);
}
// First copy over the header.
memcpy(packetCopy, packet, CAER_EVENT_PACKET_HEADER_SIZE);
// Copy the data over. Must check every event for validity!
size_t offset = CAER_EVENT_PACKET_HEADER_SIZE;
CAER_ITERATOR_VALID_START(packet, const void *)
memcpy(((uint8_t *) packetCopy) + offset, caerIteratorElement, (size_t) eventSize);
offset += (size_t) eventSize;
}
// Set the event capacity and the event number to the number of
// valid events, since we only copied those.
caerEventPacketHeaderSetEventCapacity(packetCopy, eventValid);
caerEventPacketHeaderSetEventNumber(packetCopy, eventValid);
return (packetCopy);
}
static inline caerEventPacketHeader caerEventPacketAllocate(int32_t eventCapacity, int16_t eventSource,
int32_t tsOverflow, int16_t eventType, int32_t eventSize, int32_t eventTSOffset) {
if ((eventCapacity <= 0) || (eventSource < 0) || (tsOverflow < 0) || (eventType < 0) || (eventSize <= 0)
|| (eventTSOffset < 0)) {
return (NULL);
}
size_t eventPacketSize = CAER_EVENT_PACKET_HEADER_SIZE + ((size_t) eventCapacity * (size_t) eventSize);
// Zero out event memory (all events invalid).
caerEventPacketHeader packet = (caerEventPacketHeader) calloc(1, eventPacketSize);
if (packet == NULL) {
caerLogEHO(CAER_LOG_CRITICAL, "Event Packet",
"Failed to allocate %zu bytes of memory for Event Packet of type %" PRIi16 ", capacity %" PRIi32
" from source %" PRIi16 ". Error: %d.",
eventPacketSize, eventType, eventCapacity, eventSource, errno);
return (NULL);
}
// Fill in header fields.
caerEventPacketHeaderSetEventType(packet, eventType);
caerEventPacketHeaderSetEventSource(packet, eventSource);
caerEventPacketHeaderSetEventSize(packet, eventSize);
caerEventPacketHeaderSetEventTSOffset(packet, eventTSOffset);
caerEventPacketHeaderSetEventTSOverflow(packet, tsOverflow);
caerEventPacketHeaderSetEventCapacity(packet, eventCapacity);
return (packet);
}
#ifdef __cplusplus
}
#endif
#endif /* LIBCAER_EVENTS_COMMON_H_ */