/* * 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 #include #include #include #include #include #include //--------------------------------------------------------------------------- // Constants const float PI = 3.1415927; //--------------------------------------------------------------------------- CFileCore::CFileCore( const char * Name, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay ) : CFunctionCore( Name, pLog, pDebugLevel, pOuputDisplay ) { 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( 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 ); } } 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( DebugLevel, dlHigh, "%s: Channel '%s' - Input rejected, Channel not found", Name, ChannelName ); return 0; } // Log event Log->Output( DebugLevel, dlHigh, OutputDisplay, 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; } //---------------------------------------------------------------------------