Important update:

- EventBufferCore: (new)
  - Defines Events and related functions
  - Defines Event Buffer
- ItemBuffer:
  - Specify "Keep" parameter for Delete, to override CopyEntries
This commit is contained in:
Charl Wentzel
2017-08-21 20:51:10 +02:00
parent 2830b8dd6d
commit 5f5e89e7cd
6 changed files with 502 additions and 8 deletions

View File

@@ -1,5 +1,5 @@
PROJECT(lib_redAcore) PROJECT(lib_redAcore)
ADD_LIBRARY(redAcore TimingCore.cpp DateTimeCore.cpp LogCore.cpp SignalCore.cpp DataTreeCore.cpp JSONparseCore.cpp CharBufferCore.cpp 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 ) ApplicationCore.cpp FunctionCore.cpp FileCore.cpp SelectCore.cpp SelectableCore.cpp WatchdogCore.cpp DeviceCore.cpp )

395
EventBufferCore.cpp Normal file
View File

@@ -0,0 +1,395 @@
/*
* EventBufferCore.h
* *
* Created on: 20 Aug 2017
* Author: wentzelc
*/
// Standard C/C++ Libraries
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
// 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

99
EventBufferCore.h Normal file
View File

@@ -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_*/

View File

@@ -1,5 +1,5 @@
/* /*
* BufferCore.h * ItemBufferCore.h
* *
* Created on: 22 July 2017 * Created on: 22 July 2017
* Author: wentzelc * Author: wentzelc
@@ -149,7 +149,7 @@ void * CItemBuffer::Peek( int * Size )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CItemBuffer::Delete() bool CItemBuffer::Delete( bool Keep )
{ {
TBufferItem * BufferItem; TBufferItem * BufferItem;
@@ -166,7 +166,7 @@ bool CItemBuffer::Delete()
LastItem = &FirstItem; LastItem = &FirstItem;
// Destroy entry and holder // Destroy entry and holder
if (CopyEntries) if (CopyEntries && !Keep)
DestroyEntry( &(BufferItem->Entry) ); DestroyEntry( &(BufferItem->Entry) );
free( BufferItem ); free( BufferItem );

View File

@@ -1,5 +1,5 @@
/* /*
* BufferCore.h * ItemBufferCore.h
* *
* Created on: 22 July 2017 * Created on: 22 July 2017
* Author: wentzelc * Author: wentzelc
@@ -57,7 +57,7 @@ class CItemBuffer
bool Push( void * Entry, int Size ); bool Push( void * Entry, int Size );
void * Pop( int * Size = NULL ); void * Pop( int * Size = NULL );
void * Peek( int * Size = NULL ); void * Peek( int * Size = NULL );
bool Delete(); bool Delete( bool Keep = false );
void DeleteAll(); void DeleteAll();
// Misc // Misc