dbCa: dbCaGet/PutLink dynamic size

dbCaGetLink return actual number of elements w/o zero padding.
dbCaPutLink write only requested number of elements, w/o padding
This commit is contained in:
Michael Davidsaver
2016-01-11 23:01:26 -05:00
parent 44980a1dac
commit d6eea14fd0
3 changed files with 18 additions and 41 deletions

View File

@@ -346,19 +346,16 @@ long dbCaGetLink(struct link *plink,short dbrType, void *pdest,
assert(pca->pgetNative);
status = fConvert(pca->pgetNative, pdest, 0);
} else {
unsigned long ntoreport = *nelements, ntoget;
unsigned long ntoget = *nelements;
struct dbAddr dbAddr;
long (*aConvert)(struct dbAddr *paddr, void *to, long nreq, long nto, long off);
aConvert = dbGetConvertRoutine[newType][dbrType];
assert(pca->pgetNative);
if (ntoreport > pca->nelements)
ntoreport = pca->nelements;
ntoget = ntoreport;
if (ntoget > pca->usedelements)
ntoget = pca->usedelements;
*nelements = ntoreport;
*nelements = ntoget;
memset((void *)&dbAddr, 0, sizeof(dbAddr));
dbAddr.pfield = pca->pgetNative;
@@ -366,12 +363,6 @@ long dbCaGetLink(struct link *plink,short dbrType, void *pdest,
dbAddr.field_size = MAX_STRING_SIZE;
/*Ignore error return*/
aConvert(&dbAddr, pdest, ntoget, ntoget, 0);
if(ntoget<ntoreport) {
/* zero out remainder of buffer */
memset(ntoget*pca->elementSize+(char*)pca->pgetNative,
0,
(ntoreport-ntoget)*pca->elementSize);
}
}
done:
if (pstat) *pstat = pca->stat;
@@ -418,6 +409,7 @@ long dbCaPutLinkCallback(struct link *plink,short dbrType,
if (!pca->pputNative) {
pca->pputNative = dbCalloc(pca->nelements,
dbr_value_size[ca_field_type(pca->chid)]);
pca->putnelements = 0;
/* Fixed and disabled by ANJ, see comment above.
plink->value.pv_link.pvlMask |= pvlOptOutNative;
*/
@@ -439,10 +431,7 @@ long dbCaPutLinkCallback(struct link *plink,short dbrType,
if(nRequest>pca->nelements)
nRequest = pca->nelements;
status = aConvert(&dbAddr, pbuffer, nRequest, pca->nelements, 0);
if(nRequest<pca->nelements) {
long elemsize = dbr_value_size[ca_field_type(pca->chid)];
memset(nRequest*elemsize+(char*)pca->pputNative, 0, (pca->nelements-nRequest)*elemsize);
}
pca->putnelements = nRequest;
}
link_action |= CA_WRITE_NATIVE;
pca->gotOutNative = TRUE;
@@ -767,6 +756,7 @@ static void eventCallback(struct event_handler_args arg)
goto done;
}
assert(arg.dbr);
assert(arg.count<=pca->nelements);
size = arg.count * dbr_value_size[arg.type];
if (arg.type == DBR_TIME_STRING &&
ca_field_type(pca->chid) == DBR_ENUM) {
@@ -988,11 +978,11 @@ static void dbCaTask(void *arg)
assert(pca->pputNative);
if (pca->putType == CA_PUT) {
status = ca_array_put(
pca->dbrType, pca->nelements,
pca->dbrType, pca->putnelements,
pca->chid, pca->pputNative);
} else if (pca->putType==CA_PUT_CALLBACK) {
status = ca_array_put_callback(
pca->dbrType, pca->nelements,
pca->dbrType, pca->putnelements,
pca->chid, pca->pputNative,
putComplete, pca);
} else {

View File

@@ -54,6 +54,7 @@ typedef struct caLink
size_t elementSize; /* size of one element in pgetNative */
unsigned long nelements; /* PVs max array size */
unsigned long usedelements; /* currently used in pgetNative */
unsigned long putnelements; /* currently used in pputNative */
char hasReadAccess;
char hasWriteAccess;
char isConnected;

View File

@@ -294,45 +294,35 @@ static void fillArrayDouble(double *buf, unsigned count, double first)
static void checkArray(const char *msg,
epicsInt32 *buf, epicsInt32 first,
unsigned used, unsigned total)
unsigned used)
{
int match = 1;
unsigned i;
epicsInt32 x, *b;
for(b=buf,x=first,i=0;i<used;i++,x++,b++)
match &= (*b)==x;
for(;i<total;i++,x++,b++)
match &= (*b)==0;
testOk(match, "%s", msg);
if(!match) {
for(b=buf,x=first,i=0;i<used;i++,x++,b++)
if((*b)!=x)
testDiag("%u %u != %u", i, (unsigned)*b, (unsigned)x);
for(;i<total;i++,x++,b++)
if((*b)!=0)
testDiag("%u %u != %u", i, (unsigned)*b, (unsigned)x);
}
}
static void checkArrayDouble(const char *msg,
double *buf, double first,
unsigned used, unsigned total)
unsigned used)
{
int match = 1;
unsigned i;
double x, *b;
for(b=buf,x=first,i=0;i<used;i++,x++,b++)
match &= (*b)==x;
for(;i<total;i++,x++,b++)
match &= (*b)==0;
testOk(match, "%s", msg);
if(!match) {
for(b=buf,x=first,i=0;i<used;i++,x++,b++)
if((*b)!=x)
testDiag("%u %u != %u", i, (unsigned)*b, (unsigned)x);
for(;i<total;i++,x++,b++)
if((*b)!=0)
testDiag("%u %u != %u", i, (unsigned)*b, (unsigned)x);
}
}
@@ -403,7 +393,7 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg)
if(dbGetLink(psrclnk, DBR_LONG, bufsrc, NULL, &nReq)==0) {
testPass("dbGetLink");
testOp("%ld",nReq,==,(long)num);
checkArray("array update", bufsrc, 1, nReq, psrc->nelm);
checkArray("array update", bufsrc, 1, nReq);
} else {
testFail("dbGetLink");
testSkip(2, "dbGetLink fails");
@@ -415,12 +405,8 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg)
putLink(psrclnk, DBR_LONG, bufsrc, psrc->nelm);
dbScanLock((dbCommon*)ptarg);
/* CA links always write the full target array length */
testOp("%ld",(long)ptarg->nord,==,(long)ptarg->nelm);
/* However, if the source length is less, then the target
* is zero filled
*/
checkArray("array update", buftarg, 2, num, ptarg->nelm);
testOp("%ld",(long)ptarg->nord,==,(long)num);
dbScanUnlock((dbCommon*)ptarg);
/* write again to ensure that buffer is completely updated */
@@ -429,8 +415,8 @@ static void testArrayLink(unsigned nsrc, unsigned ntarg)
putLink(psrclnk, DBR_LONG, bufsrc, psrc->nelm);
dbScanLock((dbCommon*)ptarg);
testOp("%ld",(long)ptarg->nord,==,(long)ptarg->nelm);
checkArray("array update", buftarg, 3, num, ptarg->nelm);
testOp("%ld",(long)ptarg->nord,==,(long)num);
checkArray("array update", buftarg, 3, num);
dbScanUnlock((dbCommon*)ptarg);
testIocShutdownOk();
@@ -513,7 +499,7 @@ static void testreTargetTypeChange(void)
dbScanLock((dbCommon*)psrc);
testOp("%ld",(long)psrc->nord,==,(long)5);
checkArrayDouble("array update", bufsrc, 1, 5, psrc->nelm);
checkArrayDouble("array update", bufsrc, 1, 5);
dbScanUnlock((dbCommon*)psrc);
testDiag("Retarget");
@@ -523,7 +509,7 @@ static void testreTargetTypeChange(void)
dbScanLock((dbCommon*)psrc);
testOp("%ld",(long)psrc->nord,==,(long)5);
checkArrayDouble("array update", bufsrc, 2, 5, psrc->nelm);
checkArrayDouble("array update", bufsrc, 2, 5);
dbScanUnlock((dbCommon*)psrc);
testIocShutdownOk();
@@ -583,7 +569,7 @@ static void testCAC(void)
MAIN(dbCaLinkTest)
{
testPlan(91);
testPlan(87);
testNativeLink();
testStringLink();
testCP();