Files
redAcore/FileCore.cpp
Charl Wentzel 5ea05d119e Major update:
- Logging
  - Created LogCore Class
  - Updated LogCore to use file descriptors instead of stdout
  - Add Log object reference to constructors for:
    FunctionCore, SelectCore
  - Use extern Log() object in SignalCore
- SelectableCore
  - Added new connection type: ForkedPipe
    Create pipe, fork process, connect pipe out to child stdin, exec
2016-08-22 12:14:53 +02:00

331 lines
8.3 KiB
C++

/*
* FileCore.cpp
*
* Created on: 1 Jun 2016
* Author: wentzelc
*/
// redA Libraries
#include "FileCore.h"
#include "FunctionCore.h"
#include "TimingCore.h"
#include "LogCore.h"
// Standard C/C++ Libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
//---------------------------------------------------------------------------
// Constants
const float PI = 3.1415927;
//---------------------------------------------------------------------------
CFileCore::CFileCore( const char * Name, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay ) :
CFunctionCore( Name, pLog, pDebugLevel, pOuputDisplay )
{
FirstFile = NULL;
// temp
count = 0;
x = 0;
// temp
}
//---------------------------------------------------------------------------
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 CreateLocalIO )
{
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 IO if necessary
if (CreateLocalIO) {
AddLocalIO( 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 ))
{
// temp
//char FilePath[50];
//sprintf( FilePath, "%s%03d", FileHandle->Path, x++ );
//if (Log) Log->Message( DebugLevel, dlNone, "f: %s", FilePath );
// temp
// 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) );
// temp
count = 0;
// temp
// Report result
if (Log) Log->Message( DebugLevel, dlHigh, "%s: File '%s' - Opened", Name, FileHandle->Name );
}
}
// Check if failed
if (!isOpen(FileHandle))
{
// Report result
if (Log) Log->Message( DebugLevel, 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( DebugLevel, dlHigh, "%s: File '%s' - Closed", Name, FileHandle->Name );
} else {
if (Log) Log->Message( DebugLevel, dlHigh, "%s: File '%s' - Could not close", Name, FileHandle->Name );
}
// temp
if (Log) Log->Message( DebugLevel, dlNone, "%s: File '%s' - Bytes written %d (%d)", Name, FileHandle->Name, count, (count-5038848) );
// temp
}
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 * IOName, const char * Data, int MaxLen )
{
TFileHandle * FileHandle = NULL;
int BytesWritten = 0;
// Validate
if (!IOName || !Data) {
return 0;
}
else if (MaxLen == -1) {
MaxLen = strlen( Data );
};
// Get IO
if (!(FileHandle = GetFile( IOName )))
{
// Log event
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Local IO not found", Name, IOName );
return 0;
}
// Log event
//ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, MaxLen, "%s: Local IO '%s' - IN:", Name, IOName );
// Open file
if (!OpenFile( FileHandle )) {
return 0;
}
// Handle Incoming data
BytesWritten = WriteToFD( FileHandle->FD, Data, MaxLen );
SetStartTime( &(FileHandle->PersistTime) );
// temp
count += BytesWritten;
// temp
// 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;
}
//---------------------------------------------------------------------------