/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE Versions 3.13.7 * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ // Author: Jim Kowalkowski // Date: 2/96 // // Revision-Id: anj@aps.anl.gov-20101005192737-disfz3vs0f3fiixd // #define DB_MAPPER_SOURCE 1 #include #include #define epicsExportSharedSymbols #include "gddApps.h" #include "gddAppTable.h" #include "dbMapper.h" // #include "templates/dbMapperTempl.h" // hardcoded in same order as aitConvert.h // no way to detect a string type!!!!!!! extern epicsShareDef const int gddAitToDbr[aitConvertLast+1] = { DBR_STRING, DBR_CHAR, DBR_CHAR, DBR_SHORT, DBR_SHORT, DBR_ENUM, DBR_LONG, DBR_LONG, DBR_FLOAT, DBR_DOUBLE, DBR_STRING, DBR_STRING }; extern epicsShareDef const unsigned gddDbrToAitNElem = sizeof(gddAitToDbr)/sizeof(gddAitToDbr[0]); /* * application type ("app" field) is initialized * at run tim using the "app_name" field. */ epicsShareDef gddDbrToAitTable gddDbrToAit[DBM_N_DBR_TYPES] = { // Atomic { aitEnumFixedString, 0, "value" }, // DBR_STRING { aitEnumInt16, 0, "value" }, // DBR_SHORT { aitEnumFloat32, 0, "value" }, // DBR_FLOAT { aitEnumEnum16, 0, "value" }, // DBR_ENUM { aitEnumInt8, 0, "value" }, // DBR_CHAR { aitEnumInt32, 0, "value" }, // DBR_LONG { aitEnumFloat64, 0, "value" }, // DBR_DOUBLE // Status { aitEnumFixedString, 0, "value" }, // DBR_STS_STRING { aitEnumInt16, 0, "value" }, // DBR_STS_SHORT { aitEnumFloat32, 0, "value" }, // DBR_STS_FLOAT { aitEnumEnum16, 0, "value" }, // DBR_STS_ENUM { aitEnumInt8, 0, "value" }, // DBR_STS_CHAR { aitEnumInt32, 0, "value" }, // DBR_STS_LONG { aitEnumFloat64, 0, "value" }, // DBR_STS_DOUBLE // Time { aitEnumFixedString, 0, "value" }, // DBR_TIME_STRING { aitEnumInt16, 0, "value" }, // DBR_TIME_SHORT { aitEnumFloat32, 0, "value" }, // DBR_TIME_FLOAT { aitEnumEnum16, 0, "value" }, // DBR_TIME_ENUM { aitEnumInt8, 0, "value" }, // DBR_TIME_CHAR { aitEnumInt32, 0, "value" }, // DBR_TIME_LONG { aitEnumFloat64, 0, "value" }, // DBR_TIME_DOUBLE // Graphic { aitEnumFixedString, 0, "value" }, // DBR_GR_STRING { aitEnumInt16, 0, "dbr_gr_short" }, // DBR_GR_SHORT { aitEnumFloat32, 0, "dbr_gr_float" }, // DBR_GR_FLOAT { aitEnumEnum16, 0, "dbr_gr_enum" }, // DBR_GR_ENUM { aitEnumInt8, 0, "dbr_gr_char" }, // DBR_GR_CHAR { aitEnumInt32, 0, "dbr_gr_long" }, // DBR_GR_LONG { aitEnumFloat64, 0, "dbr_gr_double" }, // DBR_GR_DOUBLE // Control { aitEnumFixedString, 0, "value" }, // DBR_CTRL_STRING { aitEnumInt16, 0, "dbr_ctrl_short" }, // DBR_CTRL_SHORT { aitEnumFloat32, 0, "dbr_ctrl_float" }, // DBR_CTRL_FLOAT { aitEnumEnum16, 0, "dbr_ctrl_enum" }, // DBR_CTRL_ENUM { aitEnumInt8, 0, "dbr_ctrl_char" }, // DBR_CTRL_CHAR { aitEnumInt32, 0, "dbr_ctrl_long" }, // DBR_CTRL_LONG { aitEnumFloat64, 0, "dbr_ctrl_double" }, // DBR_CTRL_DOUBLE // Ack { aitEnumUint16, 0, "ackt" }, // DBR_PUT_ACKT { aitEnumUint16, 0, "acks" }, // DBR_PUT_ACKS { aitEnumFixedString, 0, "dbr_stsack_string" }, // DBR_STSACK_STRING // Class { aitEnumFixedString, 0, "class" } // DBR_CLASS_NAME }; #if DBM_N_DBR_TYPES != (LAST_BUFFER_TYPE+1) #error db mapper is out of sync with db_access.h #endif static gddApplicationTypeTable* type_table = NULL; static aitDataFormat local_data_format=aitLocalDataFormat; extern epicsShareDef const unsigned gddAitToDbrNElem = sizeof(gddDbrToAit)/sizeof(gddDbrToAit[0]); // // special gddDestructor guarantees same form of new and delete // class dbMapperFixedStringDestructor: public gddDestructor { virtual void run (void *); }; // I generated a container for each of the important DBR types. This // includes all the control and graphic structures. The others are // not needed become you can get time stamp and status in each gdd. // Currently the containers are built here with c++ code. // string type needs to be written special and not use template // maybe create a template for the string type // the problem is that the value of a string structure is an array, // not just a single element static smartGDDPointer mapStringToGdd(void* v,aitIndex count) { aitFixedString* db = (aitFixedString*)v; aitEnum to_type = gddDbrToAit[DBR_STRING].type; aitUint16 to_app = gddDbrToAit[DBR_STRING].app; if(count<=1) { smartGDDPointer dd = new gddScalar(to_app,to_type); dd->unreference(); dd->put(*db); return dd; } else { smartGDDPointer dd=new gddAtomic(to_app,to_type,1,count); dd->unreference(); aitFixedString* pCopy = new aitFixedString [count]; memcpy (pCopy,db,sizeof(aitFixedString)*count); dd->putRef(db,new dbMapperFixedStringDestructor); return dd; } } static int mapGddToString(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { aitFixedString* db = (aitFixedString*)vd; aitIndex sz = dd.getDataSizeElements(); const void* v = dd.dataVoid(); int status; if (count>sz) { memset (db+sz, '\0', sizeof(*db)*(count-sz)); count = sz; } if(local_data_format==aitLocalDataFormat) { if((aitFixedString*)v!=db) { status = aitConvert(aitEnumFixedString,db, dd.primitiveType(),v,count, &enumStringTable); } else { status = sz*sizeof(aitFixedString); } } else { status = aitConvertToNet(aitEnumFixedString, db,dd.primitiveType(),v,count, &enumStringTable); } return status; } static smartGDDPointer mapShortToGdd(void* v,aitIndex count) { dbr_short_t* sv = (dbr_short_t*)v; if(count>1) { smartGDDPointer dd=new gddAtomic(gddDbrToAit[DBR_SHORT].app, gddDbrToAit[DBR_SHORT].type,1,count); dd->unreference(); dbr_short_t* pCopy = (dbr_short_t*) new char [sizeof(dbr_short_t)*count]; memcpy (pCopy,sv,sizeof(dbr_short_t)*count); dd->putRef(pCopy, new gddDestructor); return dd; } else { smartGDDPointer dd=new gddScalar(gddDbrToAit[DBR_SHORT].app); dd->unreference(); *dd=*sv; return dd; } } static int mapGddToShort(void* vd, aitIndex count, const gdd &dd, const gddEnumStringTable &enumStringTable) { dbr_short_t* sv = (dbr_short_t*)vd; aitIndex sz = dd.getDataSizeElements(); const void * v=dd.dataVoid(); int status; if (count>sz) { memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); count = sz; } if (local_data_format==aitLocalDataFormat) { if((dbr_short_t*)v!=sv) { status = aitConvert(aitEnumInt16,sv, dd.primitiveType(),v,count, &enumStringTable); } else { status = count*sizeof(dbr_short_t); } } else { status = aitConvertToNet(aitEnumInt16,sv, dd.primitiveType(),v,count, &enumStringTable); } return status; } static smartGDDPointer mapFloatToGdd(void* v,aitIndex count) { dbr_float_t* sv = (dbr_float_t*)v; if(count>1) { smartGDDPointer dd=new gddAtomic(gddDbrToAit[DBR_FLOAT].app, gddDbrToAit[DBR_FLOAT].type,1,count); dd->unreference(); dbr_float_t* pCopy = (dbr_float_t*) new char [sizeof(dbr_float_t)*count]; memcpy (pCopy,sv,sizeof(dbr_float_t)*count); dd->putRef(pCopy, new gddDestructor); return dd; } else { smartGDDPointer dd=new gddScalar(gddDbrToAit[DBR_FLOAT].app); dd->unreference(); *dd=*sv; return dd; } } static int mapGddToFloat(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_float_t* sv = (dbr_float_t*)vd; aitIndex sz=dd.getDataSizeElements(); const void * v = dd.dataVoid(); int status; if (count>sz) { memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); count = sz; } if(local_data_format==aitLocalDataFormat) { if((dbr_float_t*)v!=sv) { status = aitConvert(aitEnumFloat32,sv, dd.primitiveType(),v,count, &enumStringTable); } else { status = sz*sizeof(dbr_float_t); } } else { status = aitConvertToNet(aitEnumFloat32,sv, dd.primitiveType(),v,count, &enumStringTable); } return status; } static smartGDDPointer mapEnumToGdd(void* v,aitIndex count) { dbr_enum_t* sv = (dbr_enum_t*)v; smartGDDPointer dd; if(count>1) { dd=new gddAtomic(gddDbrToAit[DBR_ENUM].app, gddDbrToAit[DBR_ENUM].type,1,count); dd->unreference(); dbr_enum_t* pCopy = (dbr_enum_t *) new char [sizeof(dbr_enum_t)*count]; memcpy (pCopy,sv,sizeof(dbr_enum_t)*count); dd->putRef(pCopy, new gddDestructor); } else { dd=new gddScalar(gddDbrToAit[DBR_ENUM].app); dd->unreference(); *dd=*sv; } return dd; } static int mapGddToEnum(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_enum_t* sv = (dbr_enum_t*)vd; aitIndex sz=dd.getDataSizeElements(); const void* v = dd.dataVoid(); int status; if (count>sz) { memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); count = sz; } if(local_data_format==aitLocalDataFormat) { if((dbr_enum_t*)v!=sv) { status = aitConvert(aitEnumEnum16,sv, dd.primitiveType(),v,count, &enumStringTable); } else { status = sizeof(dbr_enum_t)*count; } } else { status = aitConvertToNet(aitEnumEnum16,sv, dd.primitiveType(),v,count, &enumStringTable); } return status; } static smartGDDPointer mapCharToGdd(void* v,aitIndex count) { dbr_char_t* sv = (dbr_char_t*)v; smartGDDPointer dd; if(count>1) { dd=new gddAtomic(gddDbrToAit[DBR_CHAR].app, gddDbrToAit[DBR_CHAR].type,1,count); dd->unreference(); dbr_char_t* pCopy = (dbr_char_t *) new char [sizeof(dbr_char_t)*count]; memcpy (pCopy,sv,sizeof(dbr_char_t)*count); dd->putRef(pCopy, new gddDestructor); } else { dd=new gddScalar(gddDbrToAit[DBR_CHAR].app); dd->unreference(); *dd=*sv; } return dd; } static int mapGddToChar(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_char_t* sv = (dbr_char_t*)vd; aitIndex sz=dd.getDataSizeElements(); const void* v = dd.dataVoid(); int status; if (count>sz) { memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); count = sz; } if (local_data_format==aitLocalDataFormat) { if((dbr_char_t*)v!=sv) { status = aitConvert(aitEnumInt8,sv, dd.primitiveType(),v,count, &enumStringTable); } else { status = sz*sizeof(dbr_char_t); } } else { status = aitConvertToNet(aitEnumInt8,sv, dd.primitiveType(),v,count, &enumStringTable); } return status; } static smartGDDPointer mapLongToGdd(void* v,aitIndex count) { dbr_long_t* sv = (dbr_long_t*)v; smartGDDPointer dd; if(count>1) { dd=new gddAtomic(gddDbrToAit[DBR_LONG].app, gddDbrToAit[DBR_LONG].type,1,count); dd->unreference(); dbr_long_t* pCopy = (dbr_long_t*) new char [sizeof(dbr_long_t)*count]; memcpy (pCopy,sv,sizeof(dbr_long_t)*count); dd->putRef(pCopy, new gddDestructor); } else { dd=new gddScalar(gddDbrToAit[DBR_LONG].app); dd->unreference(); *dd=*sv; } return dd; } static int mapGddToLong(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_long_t* sv = (dbr_long_t*)vd; aitIndex sz=dd.getDataSizeElements(); const void* v = dd.dataVoid(); int status; if (count>sz) { memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); count = sz; } if (local_data_format==aitLocalDataFormat) { if ((dbr_long_t*)v!=sv) { status = aitConvert(aitEnumInt32,sv, dd.primitiveType(),v,count, &enumStringTable); } else { status = count*sizeof(dbr_long_t); } } else { status = aitConvertToNet(aitEnumInt32,sv, dd.primitiveType(),v,count, &enumStringTable); } return status; } static smartGDDPointer mapDoubleToGdd(void* v,aitIndex count) { dbr_double_t* sv = (dbr_double_t*)v; smartGDDPointer dd; if(count>1) { dd=new gddAtomic(gddDbrToAit[DBR_DOUBLE].app, gddDbrToAit[DBR_DOUBLE].type,1,count); dd->unreference(); dbr_double_t* pCopy = (dbr_double_t *) new char [sizeof(dbr_double_t)*count]; memcpy (pCopy,sv,sizeof(dbr_double_t)*count); dd->putRef(pCopy, new gddDestructor); } else { dd=new gddScalar(gddDbrToAit[DBR_DOUBLE].app); dd->unreference(); *dd=*sv; } return dd; } static int mapGddToDouble(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_double_t* sv = (dbr_double_t*)vd; aitIndex sz=dd.getDataSizeElements(); const void* v = dd.dataVoid(); int status; if (count>sz) { memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); count = sz; } if (local_data_format==aitLocalDataFormat) { if ((dbr_double_t*)v!=sv) { status = aitConvert(aitEnumFloat64,sv, dd.primitiveType(),v,count, &enumStringTable); } else { status = count*sizeof(dbr_double_t); } } else { status = aitConvertToNet(aitEnumFloat64,sv, dd.primitiveType(),v,count, &enumStringTable); } return status; } // ******************************************************************** // sts structure mappings // ******************************************************************** static smartGDDPointer mapStsStringToGdd(void* v,aitIndex count) { dbr_sts_string* db = (dbr_sts_string*)v; aitFixedString* dbv = (aitFixedString*)db->value; aitEnum to_type = gddDbrToAit[DBR_STS_STRING].type; aitUint16 to_app = gddDbrToAit[DBR_STS_STRING].app; smartGDDPointer dd; if(count<=1) { dd=new gddScalar(to_app,to_type); dd->unreference(); dd->put(*dbv); } else { dd=new gddAtomic(to_app,to_type,1,count); dd->unreference(); aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; memcpy (pCopy,dbv,sizeof(aitFixedString)*count); dd->putRef(pCopy, new gddDestructor); } dd->setStatSevr(db->status,db->severity); return dd; } static int mapStsGddToString(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_string* db = (dbr_sts_string*)v; aitFixedString* dbv = (aitFixedString*)db->value; dd.getStatSevr(db->status,db->severity); return mapGddToString(dbv, count, dd, enumStringTable); } static smartGDDPointer mapStsShortToGdd(void* v,aitIndex count) { dbr_sts_short* dbv = (dbr_sts_short*)v; smartGDDPointer dd=mapShortToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); return dd; } static int mapStsGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_short* dbv = (dbr_sts_short*)v; dd.getStatSevr(dbv->status,dbv->severity); return mapGddToShort(&dbv->value, count, dd, enumStringTable); } static smartGDDPointer mapStsFloatToGdd(void* v,aitIndex count) { dbr_sts_float* dbv = (dbr_sts_float*)v; smartGDDPointer dd=mapFloatToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); return dd; } static int mapStsGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_float* dbv = (dbr_sts_float*)v; dd.getStatSevr(dbv->status,dbv->severity); return mapGddToFloat(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapStsEnumToGdd(void* v,aitIndex count) { dbr_sts_enum* dbv = (dbr_sts_enum*)v; smartGDDPointer dd=mapEnumToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); return dd; } static int mapStsGddToEnum(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_enum* dbv = (dbr_sts_enum*)v; dd.getStatSevr(dbv->status,dbv->severity); return mapGddToEnum(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapStsCharToGdd(void* v,aitIndex count) { dbr_sts_char* dbv = (dbr_sts_char*)v; smartGDDPointer dd=mapCharToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); return dd; } static int mapStsGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_char* dbv = (dbr_sts_char*)v; dd.getStatSevr(dbv->status,dbv->severity); dbv->RISC_pad = '\0'; // shut up purify return mapGddToChar(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapStsLongToGdd(void* v,aitIndex count) { dbr_sts_long* dbv = (dbr_sts_long*)v; smartGDDPointer dd=mapLongToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); return dd; } static int mapStsGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_long* dbv = (dbr_sts_long*)v; dd.getStatSevr(dbv->status,dbv->severity); return mapGddToLong(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapStsDoubleToGdd(void* v,aitIndex count) { dbr_sts_double* dbv = (dbr_sts_double*)v; smartGDDPointer dd=mapDoubleToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); return dd; } static int mapStsGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_sts_double* dbv = (dbr_sts_double*)v; dd.getStatSevr(dbv->status,dbv->severity); dbv->RISC_pad = 0; // shut up purify return mapGddToDouble(&dbv->value,count,dd, enumStringTable); } // ******************************************************************** // time structure mappings // ******************************************************************** static smartGDDPointer mapTimeStringToGdd(void* v,aitIndex count) { dbr_time_string* db = (dbr_time_string*)v; aitFixedString* dbv = (aitFixedString*)db->value; aitEnum to_type = gddDbrToAit[DBR_TIME_STRING].type; aitUint16 to_app = gddDbrToAit[DBR_TIME_STRING].app; smartGDDPointer dd; if(count<=1) { dd=new gddScalar(to_app,to_type); dd->unreference(); dd->put(*dbv); } else { dd=new gddAtomic(to_app,to_type,1,count); dd->unreference(); aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; memcpy (pCopy,dbv,sizeof(aitFixedString)*count); dd->putRef(pCopy, new gddDestructor); } dd->setStatSevr(db->status,db->severity); dd->setTimeStamp(&db->stamp); return dd; } static int mapTimeGddToString(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_string* db = (dbr_time_string*)v; aitFixedString* dbv = (aitFixedString*)db->value; dd.getStatSevr(db->status,db->severity); dd.getTimeStamp(&db->stamp); return mapGddToString(dbv, count, dd, enumStringTable); } static smartGDDPointer mapTimeShortToGdd(void* v,aitIndex count) { dbr_time_short* dbv = (dbr_time_short*)v; smartGDDPointer dd=mapShortToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); dd->setTimeStamp(&dbv->stamp); return dd; } static int mapTimeGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_short* dbv = (dbr_time_short*)v; dd.getStatSevr(dbv->status,dbv->severity); dd.getTimeStamp(&dbv->stamp); dbv->RISC_pad = 0; // shut up purify return mapGddToShort(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapTimeFloatToGdd(void* v,aitIndex count) { dbr_time_float* dbv = (dbr_time_float*)v; smartGDDPointer dd=mapFloatToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); dd->setTimeStamp(&dbv->stamp); return dd; } static int mapTimeGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_float* dbv = (dbr_time_float*)v; dd.getStatSevr(dbv->status,dbv->severity); dd.getTimeStamp(&dbv->stamp); return mapGddToFloat(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapTimeEnumToGdd(void* v,aitIndex count) { dbr_time_enum* dbv = (dbr_time_enum*)v; smartGDDPointer dd=mapEnumToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); dd->setTimeStamp(&dbv->stamp); return dd; } static int mapTimeGddToEnum(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_enum* dbv = (dbr_time_enum*)v; dd.getStatSevr(dbv->status,dbv->severity); dd.getTimeStamp(&dbv->stamp); dbv->RISC_pad = 0; // shut up purify return mapGddToEnum(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapTimeCharToGdd(void* v,aitIndex count) { dbr_time_char* dbv = (dbr_time_char*)v; smartGDDPointer dd=mapCharToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); dd->setTimeStamp(&dbv->stamp); return dd; } static int mapTimeGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_char* dbv = (dbr_time_char*)v; dd.getStatSevr(dbv->status,dbv->severity); dd.getTimeStamp(&dbv->stamp); dbv->RISC_pad0 = 0; // shut up purify dbv->RISC_pad1 = '\0'; // shut up purify return mapGddToChar(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapTimeLongToGdd(void* v,aitIndex count) { dbr_time_long* dbv = (dbr_time_long*)v; smartGDDPointer dd=mapLongToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); dd->setTimeStamp(&dbv->stamp); return dd; } static int mapTimeGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_long* dbv = (dbr_time_long*)v; dd.getStatSevr(dbv->status,dbv->severity); dd.getTimeStamp(&dbv->stamp); return mapGddToLong(&dbv->value,count,dd, enumStringTable); } static smartGDDPointer mapTimeDoubleToGdd(void* v,aitIndex count) { dbr_time_double* dbv = (dbr_time_double*)v; smartGDDPointer dd=mapDoubleToGdd(&dbv->value,count); dd->setStatSevr(dbv->status,dbv->severity); dd->setTimeStamp(&dbv->stamp); return dd; } static int mapTimeGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_time_double* dbv = (dbr_time_double*)v; dd.getStatSevr(dbv->status,dbv->severity); dd.getTimeStamp(&dbv->stamp); dbv->RISC_pad = 0; // shut up purify return mapGddToDouble(&dbv->value,count,dd, enumStringTable); } // ******************************************************************** // graphic structure mappings // ******************************************************************** // -------------map the short structures---------------- static smartGDDPointer mapGraphicShortToGdd(void* v, aitIndex count) { // must be a container dbr_gr_short* db = (dbr_gr_short*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_SHORT].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_short_value]; aitString* str=NULL; (*dd)[gddAppTypeIndex_dbr_gr_short_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_gr_short_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_short_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_short_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_short_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_short_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_gr_short_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); else vdd.setPrimType(aitEnumInt16); vdd.setBound(0,0,count); dbr_short_t* pCopy = (dbr_short_t*) new char [sizeof(dbr_short_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_short_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static smartGDDPointer mapControlShortToGdd(void* v, aitIndex count) { // must be a container dbr_ctrl_short* db = (dbr_ctrl_short*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_SHORT].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_short_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_ctrl_short_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_ctrl_short_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_controlLow]=db->lower_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_controlHigh]=db->upper_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); else vdd.setPrimType(aitEnumInt16); vdd.setBound(0,0,count); dbr_short_t* pCopy = (dbr_short_t*) new char [sizeof(dbr_short_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_short_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static int mapGraphicGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_gr_short* db = (dbr_gr_short*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_short_value]; dd[gddAppTypeIndex_dbr_gr_short_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_short_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_short_graphicHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmHighWarning]; vdd.getStatSevr(db->status,db->severity); return mapGddToShort(&db->value,count,vdd, enumStringTable); } static int mapControlGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_ctrl_short* db = (dbr_ctrl_short*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_short_value]; dd[gddAppTypeIndex_dbr_ctrl_short_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_short_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_short_graphicHigh]; db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_short_controlLow]; db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_short_controlHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmHighWarning]; vdd.getStatSevr(db->status,db->severity); return mapGddToShort(&db->value,count,vdd, enumStringTable); } // -------------map the float structures---------------- static smartGDDPointer mapGraphicFloatToGdd(void* v, aitIndex count) { // must be a container dbr_gr_float* db = (dbr_gr_float*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_FLOAT].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_float_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_gr_float_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_gr_float_precision]=db->precision; (*dd)[gddAppTypeIndex_dbr_gr_float_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_float_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_float_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_float_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_float_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_gr_float_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumFloat32,1,&count); else vdd.setPrimType(aitEnumFloat32); vdd.setBound(0,0,count); dbr_float_t* pCopy = (dbr_float_t*) new char [sizeof(dbr_float_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_float_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static smartGDDPointer mapControlFloatToGdd(void* v, aitIndex count) { // must be a container dbr_ctrl_float* db = (dbr_ctrl_float*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_FLOAT].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_float_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_ctrl_float_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_ctrl_float_precision]=db->precision; (*dd)[gddAppTypeIndex_dbr_ctrl_float_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_controlLow]=db->lower_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_controlHigh]=db->upper_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumFloat32,1,&count); else vdd.setPrimType(aitEnumFloat32); vdd.setBound(0,0,count); dbr_float_t* pCopy = (dbr_float_t*) new char [sizeof(dbr_float_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_float_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static int mapGraphicGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_gr_float* db = (dbr_gr_float*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_float_value]; dd[gddAppTypeIndex_dbr_gr_float_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->precision=dd[gddAppTypeIndex_dbr_gr_float_precision]; db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_float_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_float_graphicHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmHighWarning]; db->RISC_pad0 = 0; // shut up purify vdd.getStatSevr(db->status,db->severity); return mapGddToFloat(&db->value,count,vdd, enumStringTable); } static int mapControlGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_ctrl_float* db = (dbr_ctrl_float*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_float_value]; dd[gddAppTypeIndex_dbr_ctrl_float_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->precision=dd[gddAppTypeIndex_dbr_ctrl_float_precision]; db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_float_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_float_graphicHigh]; db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_float_controlLow]; db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_float_controlHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmHighWarning]; db->RISC_pad = 0; // shut up purify vdd.getStatSevr(db->status,db->severity); return mapGddToFloat(&db->value,count,vdd, enumStringTable); } // -------------map the enum structures---------------- static smartGDDPointer mapGraphicEnumToGdd(void* v, aitIndex /*count*/) { dbr_gr_enum* db = (dbr_gr_enum*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_ENUM].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_enum_value]; gdd& menu = (*dd)[gddAppTypeIndex_dbr_gr_enum_enums]; aitFixedString* str = menu; //aitFixedString* f = (aitFixedString*)db->strs; aitIndex sz,i; // int i; // old way using aitString menu // for(i=0;ino_str;i++) str[i]=((const char*)&(db->strs[i][0])); if(menu.dataPointer()==NULL || !menu.isAtomic()) { // need to copy the menu chunk from dbr to aitFixedString chunk menu.setDimension(1); sz=db->no_str; str=new aitFixedString[db->no_str]; menu.putRef(str,new dbMapperFixedStringDestructor); } else { if((sz=menu.getDataSizeElements())>(aitIndex)db->no_str) sz=db->no_str; } unsigned minl = epicsMin(sizeof(aitFixedString),sizeof(str[0].fixed_string)) - 1; for (i=0;istrs[i][0]), minl); memset(&str[i].fixed_string[minl], '\0', sizeof(aitFixedString)-minl); } menu.setBound(0,0,sz); // should always be a scaler if(vdd.dimension()) vdd.clear(); vdd=db->value; vdd.setStatSevr(db->status,db->severity); return dd; } static smartGDDPointer mapControlEnumToGdd(void* v, aitIndex /*count*/) { dbr_ctrl_enum* db = (dbr_ctrl_enum*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_ENUM].app); gdd& menu = (*dd)[gddAppTypeIndex_dbr_ctrl_enum_enums]; gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_enum_value]; aitFixedString* str = menu; //aitFixedString* f = (aitFixedString*)db->strs; aitIndex sz,i; // int i; // old way using aitString menu // for(i=0;ino_str;i++) str[i]=((const char*)&(db->strs[i][0])); if(menu.dataPointer()==NULL || !menu.isAtomic()) { // need to copy the menu chunk from dbr to aitFixedString chunk menu.setDimension(1); sz=db->no_str; str=new aitFixedString[db->no_str]; menu.putRef(str,new dbMapperFixedStringDestructor); } else { if((sz=menu.getDataSizeElements())>(aitIndex)db->no_str) sz=db->no_str; } unsigned minl = epicsMin(sizeof(aitFixedString),(size_t)MAX_ENUM_STRING_SIZE) - 1; for (i=0;istrs[i][0]), minl); memset(&str[i].fixed_string[minl], '\0', sizeof(aitFixedString)-minl); } menu.setBound(0,0,sz); // should always be a scaler if(vdd.dimension()) vdd.clear(); vdd=db->value; vdd.setStatSevr(db->status,db->severity); return dd; } static int mapGraphicGddToEnum ( void * v, aitIndex count, const gdd & dd, const gddEnumStringTable & enumStringTable ) { dbr_gr_enum * db = ( dbr_gr_enum * ) v; const gdd & vdd = dd[gddAppTypeIndex_dbr_gr_enum_value]; vdd.getStatSevr ( db->status, db->severity ); unsigned noStr = enumStringTable.numberOfStrings (); if ( noStr < MAX_ENUM_STATES ) { db->no_str = static_cast < dbr_short_t > ( noStr ); } else { db->no_str = MAX_ENUM_STATES; } for ( int i=0; i < db->no_str; i++ ) { enumStringTable.getString ( i, &(db->strs[i][0]), MAX_ENUM_STRING_SIZE ); } for ( int j = db->no_str; j < MAX_ENUM_STATES; j++ ) { db->strs[j][0] = '\0'; } return mapGddToEnum ( &db->value, count, vdd, enumStringTable ); } static int mapControlGddToEnum ( void * v, aitIndex count, const gdd & dd, const gddEnumStringTable & enumStringTable ) { dbr_ctrl_enum* db = ( dbr_ctrl_enum * ) v; const gdd & vdd = dd[gddAppTypeIndex_dbr_ctrl_enum_value]; vdd.getStatSevr ( db->status, db->severity ); unsigned noStr = enumStringTable.numberOfStrings (); if ( noStr < MAX_ENUM_STATES ) { db->no_str = static_cast < dbr_short_t > ( noStr ); } else { db->no_str = MAX_ENUM_STATES; } for ( int i=0; i < db->no_str; i++ ) { enumStringTable.getString ( i, &(db->strs[i][0]), MAX_ENUM_STRING_SIZE ); } for ( int j = db->no_str; j < MAX_ENUM_STATES; j++ ) { db->strs[j][0] = '\0'; } return mapGddToEnum ( &db->value, count, vdd, enumStringTable ); } // -------------map the char structures---------------- static smartGDDPointer mapGraphicCharToGdd(void* v, aitIndex count) { // must be a container dbr_gr_char* db = (dbr_gr_char*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_CHAR].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_char_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_gr_char_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_gr_char_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_char_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_char_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_char_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_char_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_gr_char_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumInt8,1,&count); else vdd.setPrimType(aitEnumInt8); vdd.setBound(0,0,count); dbr_char_t* pCopy = (dbr_char_t *) new char [sizeof(dbr_char_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_char_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static smartGDDPointer mapControlCharToGdd(void* v, aitIndex count) { // must be a container dbr_ctrl_char* db = (dbr_ctrl_char*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_CHAR].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_char_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_ctrl_char_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_ctrl_char_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_controlLow]=db->lower_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_controlHigh]=db->upper_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumInt8,1,&count); else vdd.setPrimType(aitEnumInt8); vdd.setBound(0,0,count); dbr_char_t* pCopy = (dbr_char_t*) new char [sizeof(dbr_char_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_char_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static int mapGraphicGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_gr_char* db = (dbr_gr_char*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_char_value]; dd[gddAppTypeIndex_dbr_gr_char_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_char_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_char_graphicHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmHighWarning]; db->RISC_pad = 0; vdd.getStatSevr(db->status,db->severity); return mapGddToChar(&db->value,count,vdd, enumStringTable); } static int mapControlGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_ctrl_char* db = (dbr_ctrl_char*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_char_value]; dd[gddAppTypeIndex_dbr_ctrl_char_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_char_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_char_graphicHigh]; db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_char_controlLow]; db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_char_controlHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmHighWarning]; db->RISC_pad = '\0'; // shut up purify vdd.getStatSevr(db->status,db->severity); return mapGddToChar(&db->value,count,vdd, enumStringTable); } // -------------map the long structures---------------- static smartGDDPointer mapGraphicLongToGdd(void* v, aitIndex count) { // must be a container dbr_gr_long* db = (dbr_gr_long*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_LONG].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_long_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_gr_long_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_gr_long_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_long_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_long_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_long_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_long_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_gr_long_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumInt32,1,&count); else vdd.setPrimType(aitEnumInt32); vdd.setBound(0,0,count); dbr_long_t* pCopy = (dbr_long_t*) new char [sizeof(dbr_long_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_long_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static smartGDDPointer mapControlLongToGdd(void* v, aitIndex count) { // must be a container dbr_ctrl_long* db = (dbr_ctrl_long*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_LONG].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_long_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_ctrl_long_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_ctrl_long_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_controlLow]=db->lower_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_controlHigh]=db->upper_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumInt32,1,&count); else vdd.setPrimType(aitEnumInt32); vdd.setBound(0,0,count); dbr_long_t* pCopy = (dbr_long_t *)new char [sizeof(dbr_long_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_long_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static int mapGraphicGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_gr_long* db = (dbr_gr_long*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_long_value]; dd[gddAppTypeIndex_dbr_gr_long_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_long_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_long_graphicHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmHighWarning]; vdd.getStatSevr(db->status,db->severity); return mapGddToLong(&db->value,count,vdd, enumStringTable); } static int mapControlGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_ctrl_long* db = (dbr_ctrl_long*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_long_value]; dd[gddAppTypeIndex_dbr_ctrl_long_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_long_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_long_graphicHigh]; db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_long_controlLow]; db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_long_controlHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmHighWarning]; vdd.getStatSevr(db->status,db->severity); return mapGddToLong(&db->value,count,vdd, enumStringTable); } // -------------map the double structures---------------- static smartGDDPointer mapGraphicDoubleToGdd(void* v, aitIndex count) { // must be a container dbr_gr_double* db = (dbr_gr_double*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_DOUBLE].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_double_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_gr_double_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_gr_double_precision]=db->precision; (*dd)[gddAppTypeIndex_dbr_gr_double_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_double_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_gr_double_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_double_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_gr_double_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_gr_double_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumFloat64,1,&count); else vdd.setPrimType(aitEnumFloat64); vdd.setBound(0,0,count); dbr_double_t* pCopy = (dbr_double_t *) new char [sizeof(dbr_double_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_double_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static smartGDDPointer mapControlDoubleToGdd(void* v, aitIndex count) { // must be a container dbr_ctrl_double* db = (dbr_ctrl_double*)v; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_DOUBLE].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_double_value]; aitString* str = NULL; (*dd)[gddAppTypeIndex_dbr_ctrl_double_units].getRef(str); str->copy(db->units); (*dd)[gddAppTypeIndex_dbr_ctrl_double_precision]=db->precision; (*dd)[gddAppTypeIndex_dbr_ctrl_double_graphicLow]=db->lower_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_graphicHigh]=db->upper_disp_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_controlLow]=db->lower_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_controlHigh]=db->upper_ctrl_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmLow]=db->lower_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmHigh]=db->upper_alarm_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmLowWarning]=db->lower_warning_limit; (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmHighWarning]=db->upper_warning_limit; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd=db->value; } else { if(vdd.dimension()!=1) vdd.reset(aitEnumFloat64,1,&count); else vdd.setPrimType(aitEnumFloat64); vdd.setBound(0,0,count); dbr_double_t* pCopy = (dbr_double_t *) new char [sizeof(dbr_double_t)*count]; memcpy (pCopy,&db->value,sizeof(dbr_double_t)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static int mapGraphicGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_gr_double* db = (dbr_gr_double*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_double_value]; dd[gddAppTypeIndex_dbr_gr_double_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->precision=dd[gddAppTypeIndex_dbr_gr_double_precision]; db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_double_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_double_graphicHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmHighWarning]; db->RISC_pad0 = 0; // shut up purify vdd.getStatSevr(db->status,db->severity); return mapGddToDouble(&db->value,count,vdd, enumStringTable); } static int mapControlGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { const aitString* str; dbr_ctrl_double* db = (dbr_ctrl_double*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_double_value]; dd[gddAppTypeIndex_dbr_ctrl_double_units].getRef(str); if(str->string()) { strncpy(db->units,str->string(), sizeof(db->units)); db->units[sizeof(db->units)-1u] = '\0'; } db->precision=dd[gddAppTypeIndex_dbr_ctrl_double_precision]; db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_double_graphicLow]; db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_double_graphicHigh]; db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_double_controlLow]; db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_double_controlHigh]; db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmLow]; db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmHigh]; db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmLowWarning]; db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmHighWarning]; db->RISC_pad0 = '\0'; // shut up purify vdd.getStatSevr(db->status,db->severity); return mapGddToDouble(&db->value,count,vdd, enumStringTable); } static smartGDDPointer mapStsAckStringToGdd(void* v, aitIndex count) { // must be a container dbr_stsack_string* db = (dbr_stsack_string*)v; aitFixedString* dbv = (aitFixedString*)db->value; smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_STSACK_STRING].app); gdd& vdd = (*dd)[gddAppTypeIndex_dbr_stsack_string_value]; (*dd)[gddAppTypeIndex_dbr_stsack_string_ackt]=db->ackt; (*dd)[gddAppTypeIndex_dbr_stsack_string_acks]=db->acks; vdd.setStatSevr(db->status,db->severity); if(count==1) { if(vdd.dimension()) vdd.clear(); vdd.put(*dbv); } else { if(vdd.dimension()!=1) vdd.reset(aitEnumFixedString,1,&count); else vdd.setPrimType(aitEnumFixedString); vdd.setBound(0,0,count); aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; memcpy (pCopy,&db->value,sizeof(aitFixedString)*count); vdd.putRef(pCopy, new gddDestructor); } return dd; } static int mapStsAckGddToString(void* v, aitIndex count, const gdd &dd, const gddEnumStringTable &enumStringTable) { dbr_stsack_string* db = (dbr_stsack_string*)v; const gdd& vdd = dd[gddAppTypeIndex_dbr_stsack_string_value]; db->ackt=dd[gddAppTypeIndex_dbr_stsack_string_ackt]; db->acks=dd[gddAppTypeIndex_dbr_stsack_string_acks]; // Unlike all the others, which are dbr_short_t, status and // severity for a dbr_stsack_string are dbr_ushort_t. Have to // convert. dbr_short_t st,sv; vdd.getStatSevr(st,sv); db->status = (dbr_ushort_t)st; db->severity = (dbr_ushort_t)sv; return mapGddToString (&db->value, count, vdd, enumStringTable); } // -------------map the ack elements -------------------- static smartGDDPointer mapAcktToGdd(void* v,aitIndex count) { dbr_put_ackt_t* sv = (dbr_put_ackt_t*)v; smartGDDPointer dd; // Count should be 1, but leave it general if(count>1) { dd=new gddAtomic(gddDbrToAit[DBR_PUT_ACKT].app, gddDbrToAit[DBR_PUT_ACKT].type,1,count); dd->unreference(); dbr_put_ackt_t* pCopy = (dbr_put_ackt_t*) new char [sizeof(dbr_put_ackt_t)*count]; memcpy (pCopy,sv,sizeof(dbr_put_ackt_t)*count); dd->putRef(pCopy, new gddDestructor); } else { dd=new gddScalar(gddDbrToAit[DBR_PUT_ACKT].app); dd->unreference(); *dd=*sv; } return dd; } static int mapGddToAckt(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { dbr_put_ackt_t* sv = (dbr_put_ackt_t*)vd; aitIndex sz = dd.getDataSizeElements(); const void* v=dd.dataVoid(); int status; // Count should be 1, but leave it general if (count==sz) { if (local_data_format==aitLocalDataFormat) { if((dbr_put_ackt_t*)v!=sv) { status = aitConvert(aitEnumUint16,sv, dd.primitiveType(),v,sz,&enumStringTable); } else { status = sz*sizeof(dbr_put_ackt_t); } } else { status = aitConvertToNet(aitEnumUint16,sv, dd.primitiveType(),v,sz, &enumStringTable); } } else { status = -1; } return status; } static smartGDDPointer mapAcksToGdd(void* v,aitIndex count) { dbr_put_acks_t* sv = (dbr_put_acks_t*)v; smartGDDPointer dd; // Count should be 1, but leave it general if(count>1) { dd=new gddAtomic(gddDbrToAit[DBR_PUT_ACKS].app, gddDbrToAit[DBR_PUT_ACKS].type,1,count); dd->unreference(); dbr_put_acks_t* pCopy = (dbr_put_acks_t*) new char [sizeof(dbr_put_acks_t)*count]; memcpy (pCopy,sv,sizeof(dbr_put_acks_t)*count); dd->putRef(pCopy, new gddDestructor); } else { dd=new gddScalar(gddDbrToAit[DBR_PUT_ACKS].app); dd->unreference(); *dd=*sv; } return dd; } static int mapGddToAcks(void* vd, aitIndex count, const gdd &dd, const gddEnumStringTable &enumStringTable) { dbr_put_acks_t* sv = (dbr_put_acks_t*)vd; aitIndex sz = dd.getDataSizeElements(); const void* v=dd.dataVoid(); int status; // Count should be 1, but leave it general if (count==sz) { if (local_data_format==aitLocalDataFormat) { if((dbr_put_acks_t*)v!=sv) { status = aitConvert(aitEnumUint16,sv, dd.primitiveType(),v,sz, &enumStringTable); } else { status = sz*sizeof(dbr_put_acks_t); } } else { status = aitConvertToNet(aitEnumUint16,sv, dd.primitiveType(),v,sz, &enumStringTable); } } else { status = -1; } return status; } // -------------map the class name element -------------- static smartGDDPointer mapClassNameToGdd(void* v,aitIndex count) { aitFixedString* db = (aitFixedString*)v; aitEnum to_type = gddDbrToAit[DBR_CLASS_NAME].type; aitUint16 to_app = gddDbrToAit[DBR_CLASS_NAME].app; smartGDDPointer dd; // Count should be 1, but leave it general if(count<=1) { dd=new gddScalar(to_app,to_type); dd->unreference(); dd->put(*db); } else { dd=new gddAtomic(to_app,to_type,1,count); dd->unreference(); aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; memcpy (pCopy,db,sizeof(aitFixedString)*count); dd->putRef(pCopy, new gddDestructor); } return dd; } static int mapGddToClassName(void* vd, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) { aitFixedString* db = (aitFixedString*)vd; aitIndex sz = dd.getDataSizeElements(); const void* v = dd.dataVoid(); int status; // Count should be 1, but leave it general if (count<=sz) { if(local_data_format==aitLocalDataFormat) { if((aitFixedString*)v!=db) { status = aitConvert(aitEnumFixedString,db, dd.primitiveType(),v,count, &enumStringTable); } else { status = sz*sizeof(aitFixedString); } } else { status = aitConvertToNet(aitEnumFixedString,db, dd.primitiveType(),v,count, &enumStringTable); } } else { status = -1; } return status; } // ----------------must run this to use mapping functions-------------- epicsShareFunc void gddMakeMapDBR(gddApplicationTypeTable& tt) { gddMakeMapDBR(&tt); } epicsShareFunc void gddMakeMapDBR(gddApplicationTypeTable* tt) { type_table=tt; size_t i; // Storing the DBRxxx type code in the app table will not work // for most of the types. This is because many share the same // app type "value", this includes the normal, sts, and time structures for(i=0;igetApplicationType(gddDbrToAit[i].app_name); tt->storeValue(gddDbrToAit[i].app,i); } } // // dbMapperFixedStringDestructor::run() // // special gddDestructor guarantees same form of new and delete // void dbMapperFixedStringDestructor::run (void *pUntyped) { aitFixedString *ps = (aitFixedString *) pUntyped; delete [] ps; } // An array of one function per DBR structure is provided here so conversions // can take place quickly by knowing the DBR enumerated type. // // C++ will not make a const decl external linkage unless // we explicitly specify extern // extern epicsShareDef const gddDbrMapFuncTable gddMapDbr[DBM_N_DBR_TYPES] = { { mapStringToGdd, mapGddToString }, // DBR_STRING { mapShortToGdd, mapGddToShort }, // DBR_SHORT { mapFloatToGdd, mapGddToFloat }, // DBR_FLOAT { mapEnumToGdd, mapGddToEnum }, // DBR_ENUM { mapCharToGdd, mapGddToChar }, // DBR_CHAR { mapLongToGdd, mapGddToLong }, // DBR_LONG { mapDoubleToGdd, mapGddToDouble }, // DBR_DOUBLE { mapStsStringToGdd, mapStsGddToString }, // DBR_STS_STRING { mapStsShortToGdd, mapStsGddToShort }, // DBR_STS_SHORT { mapStsFloatToGdd, mapStsGddToFloat }, // DBR_STS_FLOAT { mapStsEnumToGdd, mapStsGddToEnum }, // DBR_STS_ENUM { mapStsCharToGdd, mapStsGddToChar }, // DBR_STS_CHAR { mapStsLongToGdd, mapStsGddToLong }, // DBR_STS_LONG { mapStsDoubleToGdd, mapStsGddToDouble }, // DBR_STS_DOUBLE { mapTimeStringToGdd, mapTimeGddToString }, // DBR_TIME_STRING { mapTimeShortToGdd, mapTimeGddToShort }, // DBR_TIME_SHORT { mapTimeFloatToGdd, mapTimeGddToFloat }, // DBR_TIME_FLOAT { mapTimeEnumToGdd, mapTimeGddToEnum }, // DBR_TIME_ENUM { mapTimeCharToGdd, mapTimeGddToChar }, // DBR_TIME_CHAR { mapTimeLongToGdd, mapTimeGddToLong }, // DBR_TIME_LONG { mapTimeDoubleToGdd, mapTimeGddToDouble }, // DBR_TIME_DOUBLE { mapStsStringToGdd, mapStsGddToString }, // DBR_GR_STRING { mapGraphicShortToGdd, mapGraphicGddToShort }, // DBR_GR_SHORT { mapGraphicFloatToGdd, mapGraphicGddToFloat }, // DBR_GR_FLOAT { mapGraphicEnumToGdd, mapGraphicGddToEnum }, // DBR_GR_ENUM { mapGraphicCharToGdd, mapGraphicGddToChar }, // DBR_GR_CHAR { mapGraphicLongToGdd, mapGraphicGddToLong }, // DBR_GR_LONG { mapGraphicDoubleToGdd,mapGraphicGddToDouble }, // DBR_GR_DOUBLE { mapStsStringToGdd, mapStsGddToString }, // DBR_CTRL_STRING { mapControlShortToGdd, mapControlGddToShort }, // DBR_CTRL_SHORT { mapControlFloatToGdd, mapControlGddToFloat }, // DBR_CTRL_FLOAT { mapControlEnumToGdd, mapControlGddToEnum }, // DBR_CTRL_ENUM { mapControlCharToGdd, mapControlGddToChar }, // DBR_CTRL_CHAR { mapControlLongToGdd, mapControlGddToLong }, // DBR_CTRL_LONG { mapControlDoubleToGdd,mapControlGddToDouble }, // DBR_CTRL_DOUBLE { mapAcktToGdd, mapGddToAckt }, // DBR_PUT_ACKT { mapAcksToGdd, mapGddToAcks }, // DBR_PUT_ACKS { mapStsAckStringToGdd, mapStsAckGddToString }, // DBR_STSACK_STRING { mapClassNameToGdd, mapGddToClassName } // DBR_CLASS_NAME }; #if DBM_N_DBR_TYPES != (LAST_BUFFER_TYPE+1) #error db mapper is out of sync with db_access.h #endif extern epicsShareDef const unsigned gddMapDbrNElem = sizeof(gddMapDbr)/sizeof(gddDbrToAit[0]);