17 #include <dbExtractArray.h> 18 #include <db_field_log.h> 23 #include <chfPlugin.h> 34 static void *myStructFreeList;
36 static const chfPluginArgDef opts[] = {
43 static void * allocPvt(
void)
53 static void freePvt(
void *pvt)
61 static int parse_ok(
void *pvt)
69 static void freeArray(db_field_log *pfl)
71 if (pfl->type == dbfl_type_ref) {
76 static long wrapArrayIndices(
long *
start,
const long increment,
long *
end,
82 if (*start < 0) *start = 0;
86 if (*end < 0) *end = 0;
87 if (*end >= no_elements) *end = no_elements - 1;
89 if (*end - *start >= 0) len = 1 + (*end - *
start) / increment;
93 static db_field_log* filter(
void* pvt, dbChannel *chan, db_field_log *pfl)
96 struct dbCommon *
prec;
102 long nSource = dbChannelElements(chan);
103 long capacity = nSource;
115 (prset = dbGetRset(&chan->addr)) &&
118 void *pfieldsave = dbChannelField(chan);
119 prec = dbChannelRecord(chan);
122 nTarget = wrapArrayIndices(&start, my->
incr, &end, nSource);
123 pfl->type = dbfl_type_ref;
124 pfl->stat = prec->stat;
125 pfl->sevr = prec->sevr;
126 pfl->time = prec->time;
127 pfl->field_type = dbChannelFieldType(chan);
128 pfl->field_size = dbChannelFieldSize(chan);
129 pfl->no_elements = nTarget;
133 pfl->u.r.dtor = freeArray;
135 offset = (offset +
start) % dbChannelElements(chan);
136 dbExtractArrayFromRec(&chan->addr, pdst, nTarget, capacity,
138 pfl->u.r.field = pdst;
142 dbChannelField(chan) = pfieldsave;
149 nSource = pfl->no_elements;
150 nTarget = wrapArrayIndices(&start, my->
incr, &end, nSource);
151 pfl->no_elements = nTarget;
154 void *psrc = pfl->u.r.field;
159 dbExtractArrayFromBuf(psrc, pdst, pfl->field_size, pfl->field_type,
160 nTarget, nSource, offset, my->
incr);
162 if (pfl->u.r.dtor) pfl->u.r.dtor(pfl);
164 pfl->u.r.dtor = freeArray;
166 pfl->u.r.field = pdst;
173 static void channelRegisterPost(dbChannel *chan,
void *pvt,
174 chPostEventFunc **cb_out,
void **arg_out, db_field_log *probe)
181 if (probe->no_elements <= 1)
return;
183 max = wrapArrayIndices(&start, my->
incr, &end, probe->no_elements);
194 static void channel_report(dbChannel *chan,
void *pvt,
int level,
195 const unsigned short indent)
198 printf(
"%*sArray (arr): start=%d, incr=%d, end=%d\n", indent,
"",
202 static chfPluginIf pif = {
216 static void arrShutdown(
void* ignore)
220 myStructFreeList =
NULL;
223 static void arrInitialize(
void)
225 if (!myStructFreeList)
228 chfPluginRegister(
"arr", &pif, opts);
LIBCOM_API void *epicsStdCall freeListCalloc(void *pvt)
LIBCOM_API void epicsStdCall freeListInitPvt(void **ppvt, int size, int nmalloc)
LIBCOM_API void epicsStdCall freeListCleanup(void *pvt)
LIBCOM_API void epicsStdCall freeListFree(void *pvt, void *pmem)
Extended replacement for the Posix exit and atexit routines.
epicsExportRegistrar(arrInitialize)
#define epicsAtExit(F, A)
Convenience macro to register a function and context value to be run when the process exits...