From 5f5e89e7cd7c7c3ab23efc29b1da9c99dff60b29 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Mon, 21 Aug 2017 20:51:10 +0200 Subject: [PATCH] Important update: - EventBufferCore: (new) - Defines Events and related functions - Defines Event Buffer - ItemBuffer: - Specify "Keep" parameter for Delete, to override CopyEntries --- CMakeLists.txt | 2 +- EventBufferCore.cpp | 395 ++++++++++++++++++++++++++++++++++++++++++++ EventBufferCore.h | 99 +++++++++++ ItemBufferCore.cpp | 6 +- ItemBufferCore.h | 4 +- SelectableCore.cpp | 4 +- 6 files changed, 502 insertions(+), 8 deletions(-) create mode 100644 EventBufferCore.cpp create mode 100644 EventBufferCore.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 95d176b..b09ddb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ PROJECT(lib_redAcore) ADD_LIBRARY(redAcore TimingCore.cpp DateTimeCore.cpp LogCore.cpp SignalCore.cpp DataTreeCore.cpp JSONparseCore.cpp CharBufferCore.cpp - LiteProtocolCore.cpp ItemBufferCore.cpp + LiteProtocolCore.cpp ItemBufferCore.cpp EventBufferCore.cpp ApplicationCore.cpp FunctionCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp WatchdogCore.cpp DeviceCore.cpp ) diff --git a/EventBufferCore.cpp b/EventBufferCore.cpp new file mode 100644 index 0000000..8f437dd --- /dev/null +++ b/EventBufferCore.cpp @@ -0,0 +1,395 @@ +/* + * EventBufferCore.h + * * + * Created on: 20 Aug 2017 + * Author: wentzelc + */ + +// Standard C/C++ Libraries +#include +#include +#include + +// redA Libraries +#include "EventBufferCore.h" + +//--------------------------------------------------------------------------- + +//***** Function Prototypes *****// + +TEventEntry * CreateEvent() +{ + TEventEntry * Event; + + // Create structure + Event = (TEventEntry *)malloc( sizeof(TEventEntry) ); + + // Set default values + memset( Event, 0x0, sizeof(TEventEntry)); + + // Return empty structure + return Event; +} +//--------------------------------------------------------------------------- + +TEventEntry * CreateEvent( const char * EventType, const char * Parent, const char * DeviceName, const char * ParamName, + long Value, const char * DateTimeStr, const char * SourceName ) +{ + char TextValue[30]; + + // Create text from value + sprintf( TextValue, "%ld", Value ); + + // Create Event + return CreateEvent( EventType, Parent, DeviceName, ParamName, TextValue, DateTimeStr, SourceName ); +} +//--------------------------------------------------------------------------- + +TEventEntry * CreateEvent( const char * EventType, const char * Parent, const char * DeviceName, const char * ParamName, + double Value, const char * DateTimeStr, const char * SourceName ) +{ + char TextValue[30]; + + // Create text from value + sprintf( TextValue, "%lf", Value ); + + // Create Event + return CreateEvent( EventType, Parent, DeviceName, ParamName, TextValue, DateTimeStr, SourceName ); +} +//--------------------------------------------------------------------------- + +TEventEntry * CreateEvent( const char * EventType, const char * Parent, const char * DeviceName, const char * ParamName, + const char * Value, const char * DateTimeStr, const char * SourceName ) +{ + TEventEntry * Event; + + // Check for minimum parameters + if ((!EventType || !EventType[0]) || (!DeviceName || !DeviceName[0]) || + (!DateTimeStr || !DateTimeStr[0]) || (!SourceName || !SourceName[0])) + { + return NULL; + } + + // Create Blank Event Entry + Event = CreateEvent(); + + // Set Event type + Event->EventType = (char*)malloc( sizeof(char)*(strlen(EventType)+1) ); + strcpy( Event->EventType, EventType ); + + // Set Parent Name + if (Parent && Parent[0]) + { + Event->Parent = (char*)malloc( sizeof(char)*(strlen(Parent)+1) ); + strcpy( Event->Parent, Parent ); + } + else + { + Event->Parent = (char*)malloc(1); + Event->Parent[0] = 0; + } + + // Set Device name + Event->DeviceName = (char*)malloc( sizeof(char)*(strlen(DeviceName)+1) ); + strcpy( Event->DeviceName, DeviceName ); + + // Set Param name + if ((!ParamName || !ParamName[0])) + { + Event->ParamName = (char*)malloc(1); + Event->ParamName[0] = 0; + } + else + { + Event->ParamName = (char*)malloc( sizeof(char)*(strlen(ParamName)+1) ); + strcpy( Event->ParamName, ParamName ); + } + + // Set Value + if ((!Value || !Value[0])) + { + Event->Value = (char*)malloc(1); + Event->Value[0] = 0; + } + else + { + Event->Value = (char*)malloc( sizeof(char)*(strlen(Value)+1) ); + strcpy( Event->Value, Value ); + } + + // Set Date and time + strncpy( Event->DateTime, DateTimeStr, 19); + Event->DateTime[19] = 0; + + // Set source + Event->SourceName = (char*)malloc( sizeof(char)*(strlen(SourceName)+1) ); + strcpy( Event->SourceName, SourceName ); + + // Return Event + return Event; +} +//--------------------------------------------------------------------------- + +TEventEntry * CopyEvent( TEventEntry * Event ) +{ + TEventEntry * EventCopy; + + // Check if valid pointer + if (!Event) + return NULL; + + // Create new poitner + EventCopy = (TEventEntry*)malloc(sizeof(TEventEntry)); + + // Copy event no + EventCopy->EventNo = Event->EventNo; + + // Copy pointer content + if (Event->EventType) + { + EventCopy->EventType = (char*)malloc( strlen(Event->EventType)+1 ); + strcpy( EventCopy->EventType, Event->EventType ); + } + else + EventCopy->EventType = NULL; + + if (Event->Parent) + { + EventCopy->Parent = (char*)malloc( strlen(Event->Parent)+1 ); + strcpy( EventCopy->Parent, Event->Parent ); + } + else + EventCopy->Parent = NULL; + + if (Event->DeviceName) + { + EventCopy->DeviceName = (char*)malloc( strlen(Event->DeviceName)+1 ); + strcpy( EventCopy->DeviceName, Event->DeviceName ); + } + else + EventCopy->DeviceName = NULL; + + if (Event->ParamName) + { + EventCopy->ParamName = (char*)malloc( strlen(Event->ParamName)+1 ); + strcpy( EventCopy->ParamName, Event->ParamName ); + } + else + EventCopy->ParamName = NULL; + + if (Event->Value) + { + EventCopy->Value = (char*)malloc( strlen(Event->Value)+1 ); + strcpy( EventCopy->Value, Event->Value ); + } + else + EventCopy->Value = NULL; + + strcpy( EventCopy->DateTime, Event->DateTime ); + + if (Event->SourceName) + { + EventCopy->SourceName = (char*)malloc( strlen(Event->SourceName)+1 ); + strcpy( EventCopy->SourceName, Event->SourceName ); + } + else + EventCopy->SourceName = NULL; + + // Return copy + return EventCopy; +} +//--------------------------------------------------------------------------- + +bool DestroyEvent( TEventEntry ** Event ) +{ + // Check if valid pointer + if (!Event || !*Event) + return false; + + // Destroy pointers + if ((*Event)->EventType) + free( (*Event)->EventType ); + if ((*Event)->Parent) + free( (*Event)->Parent ); + if ((*Event)->DeviceName) + free( (*Event)->DeviceName ); + if ((*Event)->ParamName) + free( (*Event)->ParamName ); + if ((*Event)->Value) + free( (*Event)->Value ); + if ((*Event)->SourceName) + free( (*Event)->SourceName ); + + // Destroy structure + free( *Event ); + *Event = NULL; + + return true; +} +//--------------------------------------------------------------------------- + +CEventBuffer::CEventBuffer( const char * BufferName ) : + CItemBuffer( false ) +{ + // Clear pointers + CurrentEvent = NULL; + PeerBuffer = NULL; + EventCount = 0; + FirstEventType = NULL; + + // Set name + if (!BufferName || !BufferName[0]) + strcpy( Name, "" ); + else if (strlen(BufferName) > 30) + strncpy( Name, BufferName, 30 ); + else + strcpy( Name, BufferName ); +} +//--------------------------------------------------------------------------- + +CEventBuffer::~CEventBuffer() +{ + TBufferItem * NextItem; + TEventType * NextEventType; + + // Free Event List + while (FirstItem) + { + NextItem = FirstItem->NextItem; + DestroyItem( &FirstItem ); + FirstItem = NextItem; + } + + // Free filters + while (FirstEventType) + { + NextEventType = FirstEventType->Next; + free( FirstEventType->Name ); + FirstEventType = NextEventType; + } +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::SetEventFilter( int n, ... ) +{ + va_list EventList; + char * EventName; + TEventType ** EventType; + + // Get end of list + EventType = &FirstEventType; + while (*EventType) + EventType = &((*EventType)->Next); + + // Process Event Types + va_start( EventList, n ); + for (int i = 0; i < n; i++) + { + // Create entry + *EventType = (TEventType*)malloc( sizeof(TEventType) ); + + // Copy name + EventName = va_arg(EventList, char*); + (*EventType)->Name = (char*)malloc( strlen(EventName)+1 ); + strcpy( (*EventType)->Name, EventName ); + + // Next + (*EventType)->Next = NULL; + EventType = &((*EventType)->Next); + } + va_end( EventList ); + + return true; +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::PassEventFilter( TEventEntry * Event ) +{ + TEventType * EventType; + + // Check if valid event + if (!Event) + return false; + + // If not list supplied, then all pass + if (!FirstEventType) + return true; + + // Check event name against list + EventType = FirstEventType; + while (EventType) { + if (!strcasecmp( Event->EventType, EventType->Name )) + return true; + EventType = EventType->Next; + } + return false; +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::SetPeerBuffer( CEventBuffer *pPeerBuffer ) +{ + PeerBuffer = pPeerBuffer; + return true; +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::ClearCurrentEvent() +{ + CurrentEvent = NULL; + return true; +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::AddEvent( TEventEntry * Event, unsigned int EventNo ) +{ + bool result; + TEventEntry * EventCopy = NULL; + + // Validate Event + if (PassEventFilter(Event)) + { + // Save copy of event entry to Buffer + EventCopy = CopyEvent( Event ); + EventCopy->EventNo = (!EventNo)? ++EventCount : EventNo; + result = Push( (void*)EventCopy, sizeof(TEventEntry) ); + } + + // Add to Peer Buffers, or destroy if last peer buffer + if (PeerBuffer) + PeerBuffer->AddEvent( Event ); + else + DestroyEvent( &Event ); + + return result; +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::DestroyEntry( void ** Entry ) +{ + // Destroy event + DestroyEvent( (TEventEntry**)Entry ); + return true; +} +//--------------------------------------------------------------------------- + +TEventEntry * CEventBuffer::GetNextEvent( bool &Error ) +{ + // Return entry as Event entry + Error = false; + CurrentEvent = (TEventEntry*)Peek(); + + return CurrentEvent; +} +//--------------------------------------------------------------------------- + +bool CEventBuffer::ClearLastEvent( bool FreeEvent ) +{ + bool result; + + // Accept Entry as void entry + result = Delete(); + CurrentEvent = NULL; + + return result; +} +//---------------------------------------------------------------------------C diff --git a/EventBufferCore.h b/EventBufferCore.h new file mode 100644 index 0000000..3ce6c0e --- /dev/null +++ b/EventBufferCore.h @@ -0,0 +1,99 @@ +/* + * EventBufferCore.h + * * + * Created on: 20 Aug 2017 + * Author: wentzelc + */ + +#ifndef REDACORE_EVENTBUFFERCORE_H_ +#define REDACORE_EVENTBUFFERCORE_H_ + +//--------------------------------------------------------------------------- + +// Standard C/C++ Libraries +/* none */ + +// redA Libraries +#include "ItemBufferCore.h" + +//--------------------------------------------------------------------------- + +// Prototypes +class CEventBuffer; + +typedef struct SEventEntry TEventEntry; +typedef struct SEventType TEventType; + +//--------------------------------------------------------------------------- + +// Data Structures +struct SEventEntry { + unsigned EventNo; + char * EventType; + char * Parent; + char * DeviceName; + char * ParamName; + char * Value; + char DateTime[20]; + char * SourceName; +}; + +struct SEventType { + char * Name; + TEventType * Next; +}; + +//--------------------------------------------------------------------------- + +// General Event life cycle functions +TEventEntry * CreateEvent(); +TEventEntry * CreateEvent( const char * EventType, const char * Parent, const char * DeviceName, const char * ParamName, + long Value, const char * DateTimeStr, const char * SourceName ); +TEventEntry * CreateEvent( const char * EventType, const char * Parent, const char * DeviceName, const char * ParamName, + double Value, const char * DateTimeStr, const char * SourceName ); +TEventEntry * CreateEvent( const char * EventType, const char * Parent, const char * DeviceName, const char * ParamName, + const char * Value, const char * DateTimeStr, const char * SourceName ); +TEventEntry * CopyEvent( TEventEntry * Event ); +bool DestroyEvent( TEventEntry ** Event ); + +//--------------------------------------------------------------------------- + +// Event buffer abstract object (base class) +class CEventBuffer : protected CItemBuffer +{ + protected: + char Name[31]; + + CEventBuffer * PeerBuffer; + + TEventType * FirstEventType; + + public: + CEventBuffer( const char * BufferName ); + virtual ~CEventBuffer(); + + // Markers + TEventEntry * CurrentEvent; + unsigned int EventCount; + + char * GetName() { return Name; }; + + // Initialisation + bool SetPeerBuffer( CEventBuffer *pPeerBuffer ); + + // Filter List + bool SetEventFilter( int n, ... ); + bool PassEventFilter( TEventEntry * Event ); + + // Buffering + virtual bool AddEvent( TEventEntry * Event, unsigned int EventNo = 0 ); + virtual TEventEntry * GetNextEvent( bool &Error ); + virtual bool ClearCurrentEvent(); + virtual bool ClearLastEvent( bool FreeEvent ); + + virtual bool DestroyEntry( void ** Entry ); +}; +//--------------------------------------------------------------------------- + +#endif /*REDACORE_EVENTBUFFERCORE_H_*/ + diff --git a/ItemBufferCore.cpp b/ItemBufferCore.cpp index b0432ee..b0854e5 100644 --- a/ItemBufferCore.cpp +++ b/ItemBufferCore.cpp @@ -1,5 +1,5 @@ /* - * BufferCore.h + * ItemBufferCore.h * * Created on: 22 July 2017 * Author: wentzelc @@ -149,7 +149,7 @@ void * CItemBuffer::Peek( int * Size ) } //--------------------------------------------------------------------------- -bool CItemBuffer::Delete() +bool CItemBuffer::Delete( bool Keep ) { TBufferItem * BufferItem; @@ -166,7 +166,7 @@ bool CItemBuffer::Delete() LastItem = &FirstItem; // Destroy entry and holder - if (CopyEntries) + if (CopyEntries && !Keep) DestroyEntry( &(BufferItem->Entry) ); free( BufferItem ); diff --git a/ItemBufferCore.h b/ItemBufferCore.h index ff5bf63..0d20843 100644 --- a/ItemBufferCore.h +++ b/ItemBufferCore.h @@ -1,5 +1,5 @@ /* - * BufferCore.h + * ItemBufferCore.h * * Created on: 22 July 2017 * Author: wentzelc @@ -57,7 +57,7 @@ class CItemBuffer bool Push( void * Entry, int Size ); void * Pop( int * Size = NULL ); void * Peek( int * Size = NULL ); - bool Delete(); + bool Delete( bool Keep = false ); void DeleteAll(); // Misc diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 6aff571..cd3fab2 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -108,7 +108,7 @@ bool CSelectableCore::LoadConfigData() sprintf( Path, "Address/%s/Port", Name ); Port = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value } - SetSocketHandle( Handle, ctServer, Address, strlcase(Port), true ); // Assign values + SetSocketHandle( Handle, ctServer, Address, strlcase(Port), true ); // Assign values } else if (!strcasecmp( Type, "TCPclient" )) { @@ -120,7 +120,7 @@ bool CSelectableCore::LoadConfigData() sprintf( Path, "Address/%s/Port", Name ); Port = (char*)DataTree->GetStr( NULL, Path, Port, true ); // Get AddressList Port value } - SetSocketHandle( Handle, ctClient, Address, strlcase(Port), true ); // Assign values + SetSocketHandle( Handle, ctClient, Address, strlcase(Port), true ); // Assign values } else if (!strcasecmp( Type, "ForkPipe" )) { Address = (char*)DataTree->GetStr( TempMember, "Fork/ExecPath", NULL, true ); // Get default value