Files
redAcore/FileCore.cpp
Charl Wentzel 2f81d1fbbe Important Update:
- Library Clean up:
  - Removed all unused C/C++ libraries from source
  - First C/C++ libraries then redA libraries
- Library changes:
  - renamed BufferCore -> CharBufferCore
  - added ItemBufferCore
- CharBufferCore:
  - Derive RollingBuffer & ShiftBuffer from common class CharBuffer
  - CharBuffer is mostly a virtual class (interface)
2017-07-22 17:46:05 +02:00

302 lines
7.7 KiB
C++

/*
* FileCore.cpp
*
* Created on: 1 Jun 2016
* Author: wentzelc
*/
// Standard C/C++ Libraries
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
// redA Libraries
#include "ApplicationCore.h"
#include "FileCore.h"
//---------------------------------------------------------------------------
// Global Vars
//extern char * ProcessName;
//extern CApplication * Application;
//---------------------------------------------------------------------------
CFileCore::CFileCore( const char * pName, const char * pType ) :
CFunctionCore( pName, pType )
{
FirstFile = NULL;
}
//---------------------------------------------------------------------------
CFileCore::~CFileCore()
{
TFileHandle * NextFile = NULL;
// Destroy file specs
while (FirstFile)
{
// Close file if open
CloseFile( FirstFile );
// Destroy file parameters
if (FirstFile->Name)
free( FirstFile->Name );
if (FirstFile->Path)
free( FirstFile->Path );
// Destroy File
NextFile = FirstFile->Next;
delete FirstFile;
FirstFile = NextFile;
}
}
//---------------------------------------------------------------------------
TFileHandle * CFileCore::AddFile( const char * Name, const char * Path, bool Append, bool CreateChannel )
{
TFileHandle ** FileHandle = NULL;
// Validate
if (!Name || !*Name || !Path || !*Path) {
return NULL;
}
// Find File or End of list
FileHandle = &FirstFile;
while (*FileHandle && strcmp( Name, (*FileHandle)->Name )) {
FileHandle = &((*FileHandle)->Next);
}
// Check if found
if (!*FileHandle)
{
// Create new
*FileHandle = (TFileHandle*)calloc( 1, sizeof(TFileHandle) );
// Set name & Path
(*FileHandle)->Name = (char*)malloc( strlen(Name)+1 );
strcpy( (*FileHandle)->Name, Name );
(*FileHandle)->Path = (char*)malloc( strlen(Path)+1 );
strcpy( (*FileHandle)->Path, Path );
}
// Create Channel if necessary
if (CreateChannel) {
AddChannel( Name );
}
// Set Parameters
(*FileHandle)->Append = Append;
(*FileHandle)->FD = NO_FD;
// Return File
return (*FileHandle);
}
//---------------------------------------------------------------------------
bool CFileCore::SetFilePersistence( TFileHandle * FileHandle, bool Persistent, int PersistTimeout )
{
// Validate
if (!FileHandle) {
return false;
}
// Set parameters
FileHandle->Persistent = Persistent;
FileHandle->PersistTimeout = PersistTimeout;
// Open persistent file
if (Persistent && (!PersistTimeout)) {
OpenFile( FileHandle );
SetStartTime( &(FileHandle->PersistTime) );
}
// Close non-persistent file
else if (!Persistent && isOpen(FileHandle)) {
CloseFile( FileHandle );
}
return true;
}
//---------------------------------------------------------------------------
bool CFileCore::OpenFile( TFileHandle * FileHandle )
{
// Validate
if (!FileHandle) {
return false;
}
// Open file if not already open
if (!isOpen( FileHandle ))
{
// GEt file handle
(FileHandle)->FD = open( FileHandle->Path, O_WRONLY | O_CREAT | ((FileHandle->Append)? O_APPEND : O_TRUNC), 0664 );
// Report event
if (isOpen(FileHandle))
{
// Set timer
SetStartTime( &(FileHandle->PersistTime) );
// Report result
if (Log) Log->Message( LogLevel, dlHigh, "%s: File '%s' - Opened", Name, FileHandle->Name );
}
}
// Check if failed
if (!isOpen(FileHandle))
{
// Report result
if (Log) Log->Message( LogLevel, dlHigh, "%s: File '%s' - Could not open (%d) %s", Name, FileHandle->Name, errno, strerror(errno) );
return false;
}
return true;
}
//---------------------------------------------------------------------------
bool CFileCore::CloseFile( TFileHandle * FileHandle )
{
// Validate
if (!FileHandle) {
return false;
}
// Close file if not already open
if (isOpen(FileHandle))
{
// Close file
close( FileHandle->FD );
FileHandle->FD = NO_FD;
// Report result
if (!isOpen(FileHandle)) {
if (Log) Log->Message( LogLevel, dlHigh, "%s: File '%s' - Closed", Name, FileHandle->Name );
} else {
if (Log) Log->Message( LogLevel, dlHigh, "%s: File '%s' - Could not close", Name, FileHandle->Name );
}
}
return true;
}
//---------------------------------------------------------------------------
int CFileCore::ReadFromFD( int FD, char * Data, int MaxLen )
{
int BytesRead = 0;
int TotalRead = 0;
int DataRemain = 0;
// Check if buffer created
if ((FD == -1) || !Data) {
return 0;
}
// Read Data into buffer
DataRemain = (MaxLen == -1)? strlen(Data) : MaxLen;
while (DataRemain)
{
// Read from file descriptor
BytesRead = read( FD, &Data[TotalRead], DataRemain );
if (BytesRead <= 0)
break;
// Update Data Pointers
TotalRead += BytesRead;
DataRemain -= BytesRead;
}
return TotalRead;
}
//---------------------------------------------------------------------------
int CFileCore::WriteToFD( int FD, const char * Data, int Len )
{
int BytesWritten = 0;
int TotalWritten = 0;
int DataRemain = 0;
// Check if buffer created
if ((FD == -1) || !Data) {
return 0;
}
// Read Data into buffer
DataRemain = (Len == -1)? strlen(Data) : Len;
while (DataRemain)
{
// Read from file descriptor
BytesWritten = write( FD, &Data[TotalWritten], DataRemain );
if ((BytesWritten <= 0) && (errno != EAGAIN))
break;
// Update Data Pointers
TotalWritten += BytesWritten;
DataRemain -= BytesWritten;
}
return TotalWritten;
}
//---------------------------------------------------------------------------
// Manual Data Input/Output
int CFileCore::Input( const char * ChannelName, const char * Data, int MaxLen )
{
TFileHandle * FileHandle = NULL;
int BytesWritten = 0;
// Validate
if (!ChannelName || !Data) {
return 0;
}
else if (MaxLen == -1) {
MaxLen = strlen( Data );
};
// Get Channel
if (!(FileHandle = GetFile( ChannelName )))
{
// Log event
if (Log) Log->Message( LogLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel not found", Name, ChannelName );
return 0;
}
// Log event
Log->Output( LogLevel, dlHigh, LogOutput, Data, MaxLen, "%s: Channel '%s' - IN:", Name, ChannelName );
// Open file
if (!OpenFile( FileHandle )) {
return 0;
}
// Handle Incoming data
BytesWritten = WriteToFD( FileHandle->FD, Data, MaxLen );
SetStartTime( &(FileHandle->PersistTime) );
// Return processed bytes
return BytesWritten;
}
//---------------------------------------------------------------------------
bool CFileCore::Process()
{
TFileHandle * FileHandle;
// Close Persistent files not used
FileHandle = FirstFile;
while (FileHandle)
{
if (isOpen(FileHandle) &&
(!FileHandle->Persistent ||
(FileHandle->PersistTimeout && Timeout( FileHandle->PersistTime, FileHandle->PersistTimeout )))) {
CloseFile( FileHandle );
}
// Next
FileHandle = FileHandle->Next;
}
return true;
}
//---------------------------------------------------------------------------