diff --git a/src/gateway/gatePv.cc b/src/gateway/gatePv.cc index 58eeae2..a064338 100644 --- a/src/gateway/gatePv.cc +++ b/src/gateway/gatePv.cc @@ -1436,7 +1436,7 @@ void gatePvData::eventCB(EVENT_ARGS args) if(pv->active()) { gateDebug1(5,"gatePvData::eventCB() %s PV\n",pv->getStateName()); - if((dd=pv->runEventCB((void *)(args.dbr)))) + if((dd=pv->runEventCB((void *)(args.dbr), args.count))) { #if DEBUG_BEAM printf(" dd=%p needAddRemove=%d\n", @@ -1512,7 +1512,7 @@ void gatePvData::logEventCB(EVENT_ARGS args) if(pv->active()) { gateDebug1(5,"gatePvData::LogEventCB() %s PV\n",pv->getStateName()); - if((dd=pv->runEventCB((void *)(args.dbr)))) + if((dd=pv->runEventCB((void *)(args.dbr), args.count))) { #if DEBUG_BEAM printf(" dd=%p needAddRemove=%d\n", @@ -1623,11 +1623,11 @@ void gatePvData::getCB(EVENT_ARGS args) if(pv->active()) { gateDebug1(5,"gatePvData::getCB() %s PV\n",pv->getStateName()); - if((dd=pv->runDataCB((void *)(args.dbr)))) pv->vc->setPvData(dd); + if((dd=pv->runDataCB((void *)(args.dbr), args.count))) pv->vc->setPvData(dd); if(!global_resources->getCacheMode()) //we must set also value if only ctrl was requested from client { - if((dd=pv->runValueDataCB((void *)(args.dbr)))) pv->vc->setEventData(dd); + if((dd=pv->runValueDataCB((void *)(args.dbr), args.count))) pv->vc->setEventData(dd); if(pv->needAddRemove() && !pv->vc->needPosting()) { @@ -1726,7 +1726,7 @@ void gatePvData::getTimeCB(EVENT_ARGS args) if(pv->active()) { gateDebug1(5,"gatePvData::getTimeCB() %s PV\n",pv->getStateName()); - if((dd=pv->runEventCB((void *)(args.dbr)))) pv->vc->setEventData(dd); + if((dd=pv->runEventCB((void *)(args.dbr), args.count))) pv->vc->setEventData(dd); /* flush async get request */ if(pv->needAddRemove() && !pv->vc->needPosting()) @@ -1796,14 +1796,14 @@ void gatePvData::accessCB(ACCESS_ARGS args) // DBR_CTRL_LONG // DBR_CTRL_SHORT (DBR_CTRL_INT) -gdd* gatePvData::dataStringCB(void * /*dbr*/) +gdd* gatePvData::dataStringCB(void * /*dbr*/, size_t received) { gateDebug0(4,"gatePvData::dataStringCB\n"); // no useful pv_data returned by this function return NULL; } -gdd* gatePvData::dataEnumCB(void * dbr) +gdd* gatePvData::dataEnumCB(void * dbr, size_t received) { gateDebug0(4,"gatePvData::dataEnumCB\n"); int i; @@ -1831,7 +1831,7 @@ gdd* gatePvData::dataEnumCB(void * dbr) return menu; } -gdd* gatePvData::dataDoubleCB(void * dbr) +gdd* gatePvData::dataDoubleCB(void * dbr, size_t received) { gateDebug0(10,"gatePvData::dataDoubleCB\n"); dbr_ctrl_double* ts = (dbr_ctrl_double*)dbr; @@ -1852,7 +1852,7 @@ gdd* gatePvData::dataDoubleCB(void * dbr) return attr; } -gdd* gatePvData::dataShortCB(void *dbr) +gdd* gatePvData::dataShortCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::dataShortCB\n"); dbr_ctrl_short* ts = (dbr_ctrl_short*)dbr; @@ -1873,7 +1873,7 @@ gdd* gatePvData::dataShortCB(void *dbr) return attr; } -gdd* gatePvData::dataFloatCB(void *dbr) +gdd* gatePvData::dataFloatCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::dataFloatCB\n"); dbr_ctrl_float* ts = (dbr_ctrl_float*)dbr; @@ -1894,7 +1894,7 @@ gdd* gatePvData::dataFloatCB(void *dbr) return attr; } -gdd* gatePvData::dataCharCB(void *dbr) +gdd* gatePvData::dataCharCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::dataCharCB\n"); dbr_ctrl_char* ts = (dbr_ctrl_char*)dbr; @@ -1915,7 +1915,7 @@ gdd* gatePvData::dataCharCB(void *dbr) return attr; } -gdd* gatePvData::dataLongCB(void *dbr) +gdd* gatePvData::dataLongCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::dataLongCB\n"); dbr_ctrl_long* ts = (dbr_ctrl_long*)dbr; @@ -1946,7 +1946,7 @@ gdd* gatePvData::dataLongCB(void *dbr) // DBR_TIME_SHORT (DBR_TIME_INT) // DBR_STSACK_STRING (alarm info) -gdd* gatePvData::eventStringCB(void *dbr) +gdd* gatePvData::eventStringCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventStringCB\n"); dbr_time_string* ts = (dbr_time_string*)dbr; @@ -1980,7 +1980,7 @@ gdd* gatePvData::eventStringCB(void *dbr) return value; } -gdd* gatePvData::eventEnumCB(void *dbr) +gdd* gatePvData::eventEnumCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventEnumCB\n"); dbr_time_enum* ts = (dbr_time_enum*)dbr; @@ -2023,13 +2023,20 @@ gdd* gatePvData::eventEnumCB(void *dbr) return value; } -gdd* gatePvData::eventLongCB(void *dbr) +gdd* gatePvData::eventLongCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventLongCB\n"); dbr_time_long* ts = (dbr_time_long*)dbr; aitIndex count = totalElements(); gdd* value; + if (received > count) + { + fprintf(stderr, "%s received %zu elements for array of size %d\n", + pv_name, received, count); + received = count; + } + // DBR_TIME_LONG response // set up the value if(count>1) @@ -2037,7 +2044,8 @@ gdd* gatePvData::eventLongCB(void *dbr) aitInt32 *d,*nd; nd=new aitInt32[count]; d=(aitInt32*)&ts->value; - memcpy(nd,d,count*sizeof(aitInt32)); + memset(nd,0,count*sizeof(aitInt32)); + memcpy(nd,d,received*sizeof(aitInt32)); value=new gddAtomic(GR->appValue,aitEnumInt32,1,&count); value->putRef(nd,new gateIntDestruct()); } @@ -2051,7 +2059,7 @@ gdd* gatePvData::eventLongCB(void *dbr) return value; } -gdd* gatePvData::eventCharCB(void *dbr) +gdd* gatePvData::eventCharCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventCharCB\n"); dbr_time_char* ts = (dbr_time_char*)dbr; @@ -2079,7 +2087,7 @@ gdd* gatePvData::eventCharCB(void *dbr) return value; } -gdd* gatePvData::eventFloatCB(void *dbr) +gdd* gatePvData::eventFloatCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventFloatCB\n"); dbr_time_float* ts = (dbr_time_float*)dbr; @@ -2107,7 +2115,7 @@ gdd* gatePvData::eventFloatCB(void *dbr) return value; } -gdd* gatePvData::eventDoubleCB(void *dbr) +gdd* gatePvData::eventDoubleCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventDoubleCB\n"); dbr_time_double* ts = (dbr_time_double*)dbr; @@ -2135,13 +2143,20 @@ gdd* gatePvData::eventDoubleCB(void *dbr) return value; } -gdd* gatePvData::eventShortCB(void *dbr) +gdd* gatePvData::eventShortCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::eventShortCB\n"); dbr_time_short* ts = (dbr_time_short*)dbr; aitIndex count = totalElements(); gdd* value; + if (received > count) + { + fprintf(stderr, "%s received %zu elements for array of size %d\n", + pv_name, received, count); + received = count; + } + // DBR_TIME_FLOAT response // set up the value if(count>1) @@ -2149,7 +2164,8 @@ gdd* gatePvData::eventShortCB(void *dbr) aitInt16 *d,*nd; nd=new aitInt16[count]; d=(aitInt16*)&(ts->value); - memcpy(nd,d,count*sizeof(aitInt16)); + memset(nd,0,count*sizeof(aitInt16)); + memcpy(nd,d,received*sizeof(aitInt16)); value=new gddAtomic(GR->appValue,aitEnumInt16,1,&count); value->putRef(nd,new gateShortDestruct); } @@ -2185,7 +2201,7 @@ gdd* gatePvData::eventSTSAckStringCB(dbr_stsack_string *ts) // one function for each of the different value type : -gdd* gatePvData::valueDataEnumCB(void *dbr) +gdd* gatePvData::valueDataEnumCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::valueDataEnumCB\n"); dbr_ctrl_enum* ts = (dbr_ctrl_enum*)dbr; @@ -2227,13 +2243,20 @@ gdd* gatePvData::valueDataEnumCB(void *dbr) return value; } -gdd* gatePvData::valueDataLongCB(void *dbr) +gdd* gatePvData::valueDataLongCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::valueDataLongCB\n"); dbr_ctrl_long* ts = (dbr_ctrl_long*)dbr; aitIndex count = totalElements(); gdd* value; + if (received > count) + { + fprintf(stderr, "%s received %zu elements for array of size %d\n", + pv_name, received, count); + received = count; + } + // DBR_CTRL_LONG response // set up the value if(count>1) @@ -2241,7 +2264,8 @@ gdd* gatePvData::valueDataLongCB(void *dbr) aitInt32 *d,*nd; nd=new aitInt32[count]; d=(aitInt32*)&ts->value; - memcpy(nd,d,count*sizeof(aitInt32)); + memset(nd,0,count*sizeof(aitInt32)); + memcpy(nd,d,received*sizeof(aitInt32)); value=new gddAtomic(GR->appValue,aitEnumInt32,1,&count); value->putRef(nd,new gateIntDestruct()); } @@ -2254,7 +2278,7 @@ gdd* gatePvData::valueDataLongCB(void *dbr) return value; } -gdd* gatePvData::valueDataCharCB(void *dbr) +gdd* gatePvData::valueDataCharCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::valueDataCharCB\n"); dbr_ctrl_char* ts = (dbr_ctrl_char*)dbr; @@ -2281,7 +2305,7 @@ gdd* gatePvData::valueDataCharCB(void *dbr) return value; } -gdd* gatePvData::valueDataFloatCB(void *dbr) +gdd* gatePvData::valueDataFloatCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::valueDataFloatCB\n"); dbr_ctrl_float* ts = (dbr_ctrl_float*)dbr; @@ -2308,7 +2332,7 @@ gdd* gatePvData::valueDataFloatCB(void *dbr) return value; } -gdd* gatePvData::valueDataDoubleCB(void *dbr) +gdd* gatePvData::valueDataDoubleCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::valueDataDoubleCB\n"); dbr_ctrl_double* ts = (dbr_ctrl_double*)dbr; @@ -2335,13 +2359,20 @@ gdd* gatePvData::valueDataDoubleCB(void *dbr) return value; } -gdd* gatePvData::valueDataShortCB(void *dbr) +gdd* gatePvData::valueDataShortCB(void *dbr, size_t received) { gateDebug0(10,"gatePvData::valueDataShortCB\n"); dbr_ctrl_short* ts = (dbr_ctrl_short*)dbr; aitIndex count = totalElements(); gdd* value; + if (received > count) + { + fprintf(stderr, "%s received %zu elements for array of size %d\n", + pv_name, received, count); + received = count; + } + // DBR_CTRL_FLOAT response // set up the value if(count>1) @@ -2349,7 +2380,8 @@ gdd* gatePvData::valueDataShortCB(void *dbr) aitInt16 *d,*nd; nd=new aitInt16[count]; d=(aitInt16*)&(ts->value); - memcpy(nd,d,count*sizeof(aitInt16)); + memset(nd,0,count*sizeof(aitInt16)); + memcpy(nd,d,received*sizeof(aitInt16)); value=new gddAtomic(GR->appValue,aitEnumInt16,1,&count); value->putRef(nd,new gateShortDestruct); } diff --git a/src/gateway/gatePv.h b/src/gateway/gatePv.h index ea8280f..040a35c 100644 --- a/src/gateway/gatePv.h +++ b/src/gateway/gatePv.h @@ -105,7 +105,7 @@ public: gatePvData(gateServer*,gateAsEntry*,const char* name); ~gatePvData(void); - typedef gdd* (gatePvData::*gateCallback)(void*); + typedef gdd* (gatePvData::*gateCallback)(void*, size_t received); int active(void) const { return (pv_state==gatePvActive)?1:0; } int inactive(void) const { return (pv_state==gatePvInactive)?1:0; } @@ -205,9 +205,9 @@ private: void setState(gatePvState s) { pv_state=s; } - gdd* runEventCB(void* data) { return (this->*event_func)(data); } - gdd* runDataCB(void* data) { return (this->*data_func)(data); } - gdd* runValueDataCB(void* data) { return (this->*value_data_func)(data); } + gdd* runEventCB(void* data, size_t received) { return (this->*event_func)(data, received); } + gdd* runDataCB(void* data, size_t received) { return (this->*data_func)(data, received); } + gdd* runValueDataCB(void* data, size_t received) { return (this->*value_data_func)(data, received); } tsDLList eio; // pending exist test list tsDLList callback_list; // callback list for puts @@ -255,32 +255,32 @@ private: casEventMask value_log_mask; // Callback functions used in eventCB - gdd* eventStringCB(void*); - gdd* eventEnumCB(void*); - gdd* eventShortCB(void*); - gdd* eventFloatCB(void*); - gdd* eventDoubleCB(void*); - gdd* eventCharCB(void*); - gdd* eventLongCB(void*); + gdd* eventStringCB(void*, size_t received); + gdd* eventEnumCB(void*, size_t received); + gdd* eventShortCB(void*, size_t received); + gdd* eventFloatCB(void*, size_t received); + gdd* eventDoubleCB(void*, size_t received); + gdd* eventCharCB(void*, size_t received); + gdd* eventLongCB(void*, size_t received); gdd* eventSTSAckStringCB(dbr_stsack_string*); // Callback functions used in getCB - gdd* dataStringCB(void*); - gdd* dataEnumCB(void*); - gdd* dataShortCB(void*); - gdd* dataFloatCB(void*); - gdd* dataDoubleCB(void*); - gdd* dataCharCB(void*); - gdd* dataLongCB(void*); + gdd* dataStringCB(void*, size_t received); + gdd* dataEnumCB(void*, size_t received); + gdd* dataShortCB(void*, size_t received); + gdd* dataFloatCB(void*, size_t received); + gdd* dataDoubleCB(void*, size_t received); + gdd* dataCharCB(void*, size_t received); + gdd* dataLongCB(void*, size_t received); // Callback functions used in getCB for value - gdd* valueDataStringCB(void*); - gdd* valueDataEnumCB(void*); - gdd* valueDataShortCB(void*); - gdd* valueDataFloatCB(void*); - gdd* valueDataDoubleCB(void*); - gdd* valueDataCharCB(void*); - gdd* valueDataLongCB(void*); + gdd* valueDataStringCB(void*, size_t received); + gdd* valueDataEnumCB(void*, size_t received); + gdd* valueDataShortCB(void*, size_t received); + gdd* valueDataFloatCB(void*, size_t received); + gdd* valueDataDoubleCB(void*, size_t received); + gdd* valueDataCharCB(void*, size_t received); + gdd* valueDataLongCB(void*, size_t received); public: static void connectCB(CONNECT_ARGS args); // connection callback