.. _program_listing_file_include_libcaer_events_common.h: Program Listing for File common.h ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``include/libcaer/events/common.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #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_ */