17 #include <epicsTypes.h>
18 #include <epicsTime.h>
19 #include <epicsThread.h>
20 #include <epicsString.h>
21 #include <epicsTimer.h>
22 #include <epicsMutex.h>
23 #include <epicsEvent.h>
29 #include <epicsGuard.h>
31 #include <epicsExport.h>
40 : file_mod(0), filePath(filePath), lineCount(lineCount), pollingPeriod(pollingPeriod), asynPortDriver(portName,
43 asynInt32Mask | asynFloat64Mask | asynOctetMask | asynDrvUserMask,
44 asynInt32Mask | asynFloat64Mask | asynOctetMask,
50 const char *functionName =
"instetcDriver";
54 if (epicsThreadCreate(
"instetcPoller",
55 epicsThreadPriorityMedium,
56 epicsThreadGetStackSize(epicsThreadStackMedium),
59 printf(
"%s:%s: epicsThreadCreate failure\n",
driverName, functionName);
67 size_t const granularity = 100 *
lineCount;
68 char filePathEx[1024];
71 struct stat stat_struct;
73 memcpy(&now_tm, localtime(&now),
sizeof(
struct tm));
74 if ( 0 == strftime(filePathEx,
sizeof(filePathEx)-1,
filePath.c_str(), &now_tm) )
76 strncpy(filePathEx,
filePath.c_str(),
sizeof(filePathEx)-1);
78 filePathEx[
sizeof(filePathEx)-1] =
'\0';
79 if (stat(filePathEx, &stat_struct) != 0)
83 the_lines = std::string(
"File \"") + filePathEx +
"\" does not exist";
90 if (stat_struct.st_mtime ==
file_mod)
95 std::ifstream source(filePathEx, std::ios_base::binary);
96 source.seekg(0, std::ios_base::end);
97 size_t size =
static_cast<size_t>(source.tellg());
98 std::vector<char> buffer;
100 int newlineCount = 0;
102 && buffer.size() != size
105 buffer.resize(std::min(buffer.size() + granularity, size));
106 source.seekg(-static_cast<std::streamoff>(buffer.size()), std::ios_base::end);
107 source.read(buffer.data(), buffer.size());
108 newlineCount =
static_cast<int>(std::count(buffer.begin(), buffer.end(),
'\n'));
111 std::vector<char>::iterator start = buffer.begin();
114 start = std::find(start, buffer.end(),
'\n') + 1;
118 std::vector<char>::iterator end = std::remove(start, buffer.end(),
'\r');
119 the_lines = std::string(start, end);
129 #define LEN_BUFFER 10024
141 epicsThreadSleep(3.0);
148 setStringParam(
P_Text, text.c_str());
149 callParamCallbacks();
157 static int instetcConfigure(
const char *portName,
const char* logFilePath,
const int lineCount,
const double pollingPeriod)
161 new instetcDriver(portName, logFilePath, lineCount, pollingPeriod);
164 catch(
const std::exception& ex)
166 std::cerr <<
"instetcDriver failed: " << ex.what() << std::endl;
173 static const iocshArg
initArg0 = {
"portName", iocshArgString};
174 static const iocshArg
initArg1 = {
"logFilePath", iocshArgString};
175 static const iocshArg
initArg2 = {
"lineCount", iocshArgInt};
176 static const iocshArg
initArg3 = {
"pollingPeriod", iocshArgDouble};
180 static const iocshFuncDef
initFuncDef = {
"instetcConfigure",
sizeof(
initArgs) /
sizeof(iocshArg*), initArgs};
#define NUM_INSTETC_PARAMS
void pollerThread(const std::string &filePath, int lineCount, double pollingPeriod)
epicsExportRegistrar(instetcRegister)
static const iocshArg initArg1
The path to the file we will monitor.
static void pollerThreadC(void *arg)
static const iocshArg initArg2
The number of log file lines to broadcast.
int getLastLines(std::string &the_lines)
instetcDriver(const char *portName, const char *filePath, const int lineCount, double pollingPeriod)
Constructor for the lvDCOMDriver class.
static const char * driverName
static void instetcRegister(void)
static const iocshFuncDef initFuncDef
static const iocshArg *const initArgs[]
void updateText(const std::string &text)
static void initCallFunc(const iocshArgBuf *args)
static const iocshArg initArg3
The number of seconds between file reads.
static int instetcConfigure(const char *portName, const char *logFilePath, const int lineCount, const double pollingPeriod)
EPICS iocsh callable function to call constructor of lvDCOMInterface().
static const iocshArg initArg0
The name of the asyn driver port we will create.