.. _program_listing_file_include_libcaer_events_packetContainer.h: Program Listing for File packetContainer.h ========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/libcaer/events/packetContainer.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef LIBCAER_EVENTS_PACKETCONTAINER_H_ #define LIBCAER_EVENTS_PACKETCONTAINER_H_ #include "common.h" #ifdef __cplusplus extern "C" { #endif PACKED_STRUCT(struct caer_event_packet_container { int64_t lowestEventTimestamp; int64_t highestEventTimestamp; int32_t eventsNumber; int32_t eventsValidNumber; int32_t eventPacketsNumber; caerEventPacketHeader eventPackets[]; }); typedef struct caer_event_packet_container *caerEventPacketContainer; typedef const struct caer_event_packet_container *caerEventPacketContainerConst; static inline caerEventPacketContainer caerEventPacketContainerAllocate(int32_t eventPacketsNumber) { if (eventPacketsNumber <= 0) { return (NULL); } size_t eventPacketContainerSize = sizeof(struct caer_event_packet_container) + ((size_t) eventPacketsNumber * sizeof(caerEventPacketHeader)); caerEventPacketContainer packetContainer = (caerEventPacketContainer) calloc(1, eventPacketContainerSize); if (packetContainer == NULL) { caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Container", "Failed to allocate %zu bytes of memory for Event Packet Container, containing %" PRIi32 " packets. Error: %d.", eventPacketContainerSize, eventPacketsNumber, errno); return (NULL); } // Fill in header fields. Don't care about endianness here, purely internal // memory construct, never meant for inter-system exchange. packetContainer->eventPacketsNumber = eventPacketsNumber; packetContainer->lowestEventTimestamp = -1; packetContainer->highestEventTimestamp = -1; return (packetContainer); } // Forward declaration for use in set operations. static inline void caerEventPacketContainerUpdateStatistics(caerEventPacketContainer container); static inline int32_t caerEventPacketContainerGetEventPacketsNumber(caerEventPacketContainerConst container) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (0); } return (container->eventPacketsNumber); } static inline void caerEventPacketContainerSetEventPacketsNumber( caerEventPacketContainer container, int32_t eventPacketsNumber) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return; } if (eventPacketsNumber < 0) { // Negative numbers (bit 31 set) are not allowed! caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Container", "Called caerEventPacketContainerSetEventPacketsNumber() with negative value!"); return; } container->eventPacketsNumber = eventPacketsNumber; // Always update all the statics on set operation. caerEventPacketContainerUpdateStatistics(container); } static inline caerEventPacketHeader caerEventPacketContainerGetEventPacket( caerEventPacketContainerConst container, int32_t n) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (NULL); } // Check that we're not out of bounds. if (n < 0 || n >= caerEventPacketContainerGetEventPacketsNumber(container)) { caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Container", "Called caerEventPacketContainerGetEventPacket() with invalid event offset %" PRIi32 ", while maximum allowed value is %" PRIi32 ". Negative values are not allowed!", n, caerEventPacketContainerGetEventPacketsNumber(container) - 1); return (NULL); } // Return a pointer to the specified event packet. return (container->eventPackets[n]); } static inline caerEventPacketHeaderConst caerEventPacketContainerGetEventPacketConst( caerEventPacketContainerConst container, int32_t n) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (NULL); } // Check that we're not out of bounds. if (n < 0 || n >= caerEventPacketContainerGetEventPacketsNumber(container)) { caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Container", "Called caerEventPacketContainerGetEventPacketConst() with invalid event offset %" PRIi32 ", while maximum allowed value is %" PRIi32 ". Negative values are not allowed!", n, caerEventPacketContainerGetEventPacketsNumber(container) - 1); return (NULL); } // Return a pointer to the specified event packet. return (container->eventPackets[n]); } static inline void caerEventPacketContainerSetEventPacket( caerEventPacketContainer container, int32_t n, caerEventPacketHeader packetHeader) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return; } // Check that we're not out of bounds. if (n < 0 || n >= caerEventPacketContainerGetEventPacketsNumber(container)) { caerLogEHO(CAER_LOG_CRITICAL, "EventPacket Container", "Called caerEventPacketContainerSetEventPacket() with invalid event offset %" PRIi32 ", while maximum allowed value is %" PRIi32 ". Negative values are not allowed!", n, caerEventPacketContainerGetEventPacketsNumber(container) - 1); return; } // Store the given event packet. container->eventPackets[n] = packetHeader; // Always update all the statics on set operation. caerEventPacketContainerUpdateStatistics(container); } static inline void caerEventPacketContainerFree(caerEventPacketContainer container) { if (container == NULL) { return; } // Free packet container and ensure all subordinate memory is also freed. int32_t eventPacketsNum = caerEventPacketContainerGetEventPacketsNumber(container); for (int32_t i = 0; i < eventPacketsNum; i++) { caerEventPacketHeader packetHeader = caerEventPacketContainerGetEventPacket(container, i); if (packetHeader != NULL) { free(packetHeader); } } free(container); } static inline int64_t caerEventPacketContainerGetLowestEventTimestamp(caerEventPacketContainerConst container) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (-1); } return (container->lowestEventTimestamp); } static inline int64_t caerEventPacketContainerGetHighestEventTimestamp(caerEventPacketContainerConst container) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (-1); } return (container->highestEventTimestamp); } static inline int32_t caerEventPacketContainerGetEventsNumber(caerEventPacketContainerConst container) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (0); } return (container->eventsNumber); } static inline int32_t caerEventPacketContainerGetEventsValidNumber(caerEventPacketContainerConst container) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (0); } return (container->eventsValidNumber); } #define CAER_EVENT_PACKET_CONTAINER_ITERATOR_START(PACKET_CONTAINER) \ if ((PACKET_CONTAINER) != NULL) { \ for (int32_t caerEventPacketContainerIteratorCounter = 0; \ caerEventPacketContainerIteratorCounter \ < caerEventPacketContainerGetEventPacketsNumber(PACKET_CONTAINER); \ caerEventPacketContainerIteratorCounter++) { \ caerEventPacketHeader caerEventPacketContainerIteratorElement \ = caerEventPacketContainerGetEventPacket(PACKET_CONTAINER, caerEventPacketContainerIteratorCounter); \ if (caerEventPacketContainerIteratorElement == NULL) { \ continue; \ } #define CAER_EVENT_PACKET_CONTAINER_CONST_ITERATOR_START(PACKET_CONTAINER) \ if ((PACKET_CONTAINER) != NULL) { \ for (int32_t caerEventPacketContainerIteratorCounter = 0; \ caerEventPacketContainerIteratorCounter \ < caerEventPacketContainerGetEventPacketsNumber(PACKET_CONTAINER); \ caerEventPacketContainerIteratorCounter++) { \ caerEventPacketHeaderConst caerEventPacketContainerIteratorElement \ = caerEventPacketContainerGetEventPacketConst( \ PACKET_CONTAINER, caerEventPacketContainerIteratorCounter); \ if (caerEventPacketContainerIteratorElement == NULL) { \ continue; \ } #define CAER_EVENT_PACKET_CONTAINER_ITERATOR_END \ } \ } static inline void caerEventPacketContainerUpdateStatistics(caerEventPacketContainer container) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return; } int64_t lowestTimestamp = -1; int64_t highestTimestamp = -1; int32_t eventsNumber = 0; int32_t eventsValid = 0; CAER_EVENT_PACKET_CONTAINER_CONST_ITERATOR_START(container) // If packet has no events, skip it, it contributes nothing to statistics. if (caerEventPacketHeaderGetEventNumber(caerEventPacketContainerIteratorElement) == 0) { continue; } // Get timestamps to update lowest/highest tracking. const void *firstEvent = caerGenericEventGetEvent(caerEventPacketContainerIteratorElement, 0); int64_t currLowestEventTimestamp = caerGenericEventGetTimestamp64(firstEvent, caerEventPacketContainerIteratorElement); const void *lastEvent = caerGenericEventGetEvent(caerEventPacketContainerIteratorElement, caerEventPacketHeaderGetEventNumber(caerEventPacketContainerIteratorElement) - 1); int64_t currHighestEventTimestamp = caerGenericEventGetTimestamp64(lastEvent, caerEventPacketContainerIteratorElement); // Update tracked timestamps (or initialize if needed). if ((lowestTimestamp == -1) || (lowestTimestamp > currLowestEventTimestamp)) { lowestTimestamp = currLowestEventTimestamp; } if ((highestTimestamp == -1) || (highestTimestamp < currHighestEventTimestamp)) { highestTimestamp = currHighestEventTimestamp; } eventsNumber += caerEventPacketHeaderGetEventNumber(caerEventPacketContainerIteratorElement); eventsValid += caerEventPacketHeaderGetEventValid(caerEventPacketContainerIteratorElement); CAER_EVENT_PACKET_CONTAINER_ITERATOR_END container->lowestEventTimestamp = lowestTimestamp; container->highestEventTimestamp = highestTimestamp; container->eventsNumber = eventsNumber; container->eventsValidNumber = eventsValid; } static inline caerEventPacketHeader caerEventPacketContainerFindEventPacketByType( caerEventPacketContainerConst container, int16_t typeID) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (NULL); } CAER_EVENT_PACKET_CONTAINER_ITERATOR_START(container) if (caerEventPacketHeaderGetEventType(caerEventPacketContainerIteratorElement) == typeID) { // Found it, return it. return (caerEventPacketContainerIteratorElement); } CAER_EVENT_PACKET_CONTAINER_ITERATOR_END // Found nothing, return nothing. return (NULL); } static inline caerEventPacketHeaderConst caerEventPacketContainerFindEventPacketByTypeConst( caerEventPacketContainerConst container, int16_t typeID) { // Non-existing (empty) containers have no valid packets in them! if (container == NULL) { return (NULL); } CAER_EVENT_PACKET_CONTAINER_CONST_ITERATOR_START(container) if (caerEventPacketHeaderGetEventType(caerEventPacketContainerIteratorElement) == typeID) { // Found it, return it. return (caerEventPacketContainerIteratorElement); } CAER_EVENT_PACKET_CONTAINER_ITERATOR_END // Found nothing, return nothing. return (NULL); } static inline caerEventPacketContainer caerEventPacketContainerCopyAllEvents(caerEventPacketContainerConst container) { if (container == NULL) { return (NULL); } caerEventPacketContainer newContainer = caerEventPacketContainerAllocate(caerEventPacketContainerGetEventPacketsNumber(container)); if (newContainer == NULL) { return (NULL); } CAER_EVENT_PACKET_CONTAINER_CONST_ITERATOR_START(container) caerEventPacketContainerSetEventPacket(newContainer, caerEventPacketContainerIteratorCounter, caerEventPacketCopyOnlyEvents(caerEventPacketContainerIteratorElement)); CAER_EVENT_PACKET_CONTAINER_ITERATOR_END return (newContainer); } static inline caerEventPacketContainer caerEventPacketContainerCopyValidEvents( caerEventPacketContainerConst container) { if (container == NULL) { return (NULL); } caerEventPacketContainer newContainer = caerEventPacketContainerAllocate(caerEventPacketContainerGetEventPacketsNumber(container)); if (newContainer == NULL) { return (NULL); } CAER_EVENT_PACKET_CONTAINER_CONST_ITERATOR_START(container) caerEventPacketContainerSetEventPacket(newContainer, caerEventPacketContainerIteratorCounter, caerEventPacketCopyOnlyValidEvents(caerEventPacketContainerIteratorElement)); CAER_EVENT_PACKET_CONTAINER_ITERATOR_END return (newContainer); } #ifdef __cplusplus } #endif #endif /* LIBCAER_EVENTS_PACKETCONTAINER_H_ */