diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index 226e74a16..bf1a15312 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -459,7 +459,7 @@ cacChannel & cac::createChannel ( if ( ! this->pudpiiu ) { this->pudpiiu = new udpiiu ( - this->timerQueue, this->cbMutex, + guard, this->timerQueue, this->cbMutex, this->mutex, this->notify, *this ); } @@ -615,14 +615,6 @@ int cac::printf ( epicsGuard < epicsMutex > & callbackControl, return status; } -void cac::writeRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, unsigned type, - arrayElementCount nElem, const void * pValue ) -{ - guard.assertIdenticalMutex ( this->mutex ); - chan.getPIIU(guard)->writeRequest ( guard, chan, type, nElem, pValue ); -} - netWriteNotifyIO & cac::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, nciu & chan, privateInterfaceForIO & icni, unsigned type, arrayElementCount nElem, const void * pValue, cacWriteNotify & notifyIn ) @@ -794,20 +786,6 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu, caStatus = ECA_NORMAL; } - /* - * convert the data buffer from net - * format to host format - */ -# ifdef CONVERSION_REQUIRED - if ( hdr.m_dataType < NELEMENTS ( cac_dbr_cvrt ) ) { - ( *cac_dbr_cvrt[ hdr.m_dataType ] ) ( - pMsgBdy, pMsgBdy, false, hdr.m_count); - } - else { - caStatus = ECA_BADTYPE; - } -# endif - baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available ); // // The IO destroy routines take the call back mutex @@ -823,6 +801,14 @@ bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu, // this does *not* assign a new resource id this->ioTable.add ( *pmiu ); } + if ( caStatus == ECA_NORMAL ) { + /* + * convert the data buffer from net + * format to host format + */ + caStatus = caNetConvert ( + hdr.m_dataType, pMsgBdy, pMsgBdy, false, hdr.m_count ); + } if ( caStatus == ECA_NORMAL ) { pmiu->completion ( guard, *this, hdr.m_dataType, hdr.m_count, pMsgBdy ); @@ -862,19 +848,6 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu, caStatus = ECA_NORMAL; } - /* - * convert the data buffer from net format to host format - */ -# ifdef CONVERSION_REQUIRED - if ( hdr.m_dataType < NELEMENTS ( cac_dbr_cvrt ) ) { - ( *cac_dbr_cvrt [ hdr.m_dataType ] )( - pMsgBdy, pMsgBdy, false, hdr.m_count); - } - else { - caStatus = epicsHTON32 ( ECA_BADTYPE ); - } -# endif - // // The IO destroy routines take the call back mutex // when uninstalling and deleting the baseNMIU so there is @@ -883,6 +856,13 @@ bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu, // baseNMIU * pmiu = this->ioTable.lookup ( hdr.m_available ); if ( pmiu ) { + /* + * convert the data buffer from net format to host format + */ + if ( caStatus == ECA_NORMAL ) { + caStatus = caNetConvert ( + hdr.m_dataType, pMsgBdy, pMsgBdy, false, hdr.m_count ); + } if ( caStatus == ECA_NORMAL ) { pmiu->completion ( guard, *this, hdr.m_dataType, hdr.m_count, pMsgBdy ); @@ -1004,12 +984,12 @@ bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu, return false; } caHdrLargeArray req; - req.m_cmmd = epicsNTOH16 ( pReq->m_cmmd ); - req.m_postsize = epicsNTOH16 ( pReq->m_postsize ); - req.m_dataType = epicsNTOH16 ( pReq->m_dataType ); - req.m_count = epicsNTOH16 ( pReq->m_count ); - req.m_cid = epicsNTOH32 ( pReq->m_cid ); - req.m_available = epicsNTOH32 ( pReq->m_available ); + req.m_cmmd = AlignedWireRef < const epicsUInt16 > ( pReq->m_cmmd ); + req.m_postsize = AlignedWireRef < const epicsUInt16 > ( pReq->m_postsize ); + req.m_dataType = AlignedWireRef < const epicsUInt16 > ( pReq->m_dataType ); + req.m_count = AlignedWireRef < const epicsUInt16 > ( pReq->m_count ); + req.m_cid = AlignedWireRef < const epicsUInt32 > ( pReq->m_cid ); + req.m_available = AlignedWireRef < const epicsUInt32 > ( pReq->m_available ); const ca_uint32_t * pLW = reinterpret_cast < const ca_uint32_t * > ( pReq + 1 ); if ( req.m_postsize == 0xffff ) { static const unsigned annexSize = @@ -1018,8 +998,8 @@ bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu, if ( hdr.m_postsize < bytesSoFar ) { return false; } - req.m_postsize = epicsNTOH32 ( pLW[0] ); - req.m_count = epicsNTOH32 ( pLW[1] ); + req.m_postsize = AlignedWireRef < const epicsUInt32 > ( pLW[0] ); + req.m_count = AlignedWireRef < const epicsUInt32 > ( pLW[1] ); pLW += 2u; } diff --git a/src/ca/casw.cpp b/src/ca/casw.cpp index 4b4ccda75..d8334b8ca 100644 --- a/src/ca/casw.cpp +++ b/src/ca/casw.cpp @@ -117,8 +117,8 @@ int main ( int argc, char ** argv ) memset ( (char *) &addr, 0 , sizeof (addr) ); addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = epicsHTON32 ( INADDR_ANY ); - addr.ia.sin_port = epicsHTON16 ( 0 ); // any port + addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); + addr.ia.sin_port = htons ( 0 ); // any port status = bind ( sock, &addr.sa, sizeof (addr) ); if ( status < 0 ) { char sockErrBuf[64]; @@ -151,7 +151,8 @@ int main ( int argc, char ** argv ) &addr.sa, &addrSize ); if ( status >= static_cast ( sizeof ( *pCurMsg ) ) ) { pCurMsg = reinterpret_cast < caHdr * > ( buf ); - if ( epicsHTON16 ( pCurMsg->m_cmmd ) == REPEATER_CONFIRM ) { + epicsUInt16 cmmd = AlignedWireRef < const epicsUInt16 > ( pCurMsg->m_cmmd ); + if ( cmmd == REPEATER_CONFIRM ) { break; } } @@ -199,13 +200,15 @@ int main ( int argc, char ** argv ) unsigned byteCount = static_cast ( status ); pCurMsg = reinterpret_cast < const caHdr * > ( ( pCurBuf = buf ) ); while ( byteCount ) { - size_t msgSize = epicsNTOH32 ( pCurMsg->m_postsize ) + sizeof (*pCurMsg) ; + AlignedWireRef < const epicsUInt16 > pstSize ( pCurMsg->m_postsize ); + size_t msgSize = pstSize + sizeof ( *pCurMsg ) ; if ( msgSize > byteCount ) { errlogPrintf ( "CASW: udp input protocol violation\n" ); break; } - if ( epicsNTOH16 ( pCurMsg->m_cmmd ) == CA_PROTO_RSRV_IS_UP ) { + epicsUInt16 cmmd = AlignedWireRef < const epicsUInt16 > ( pCurMsg->m_cmmd ); + if ( cmmd == CA_PROTO_RSRV_IS_UP ) { bool anomaly = false; epicsTime previousTime; struct sockaddr_in ina; @@ -216,12 +219,12 @@ int main ( int argc, char ** argv ) * * old servers: * 1) set this field to one of the ip addresses of the host _or_ - * 2) set this field to epicsHTON32(INADDR_ANY) + * 2) set this field to INADDR_ANY * new servers: - * always set this field to epicsHTON32(INADDR_ANY) + * always set this field to INADDR_ANY * * clients always assume that if this - * field is set to something that isnt epicsHTON32(INADDR_ANY) + * field is set to something that isnt INADDR_ANY * then it is the overriding IP address of the server. */ ina.sin_family = AF_INET; @@ -235,7 +238,7 @@ int main ( int argc, char ** argv ) * old servers dont supply this and the * default port must be assumed */ - ina.sin_port = epicsNTOH16 ( serverPort ); + ina.sin_port = htons ( serverPort ); } ca_uint32_t beaconNumber = ntohl ( pCurMsg->m_cid ); diff --git a/src/ca/comBuf.cpp b/src/ca/comBuf.cpp index eddd5e7bd..b377a269b 100644 --- a/src/ca/comBuf.cpp +++ b/src/ca/comBuf.cpp @@ -139,7 +139,7 @@ unsigned comBuf::push ( const epicsFloat32 * pValue, unsigned nElem ) } for ( unsigned i = 0u; i < nElem; i++ ) { // allow native floating point formats to be converted to IEEE - osiConvertToWireFormat ( pValue[i], &this->buf[index] ); + WireSetFloat32 ( pValue[i], &this->buf[index] ); index += sizeof ( *pValue ); } this->nextWriteIndex = index; @@ -156,7 +156,7 @@ unsigned comBuf::push ( const epicsFloat64 * pValue, unsigned nElem ) } for ( unsigned i = 0u; i < nElem; i++ ) { // allow native floating point formats to be converted to IEEE - osiConvertToWireFormat ( pValue[i], &this->buf[index] ); + WireSetFloat64 ( pValue[i], &this->buf[index] ); index += sizeof ( *pValue ); } this->nextWriteIndex = index; diff --git a/src/ca/comBuf.h b/src/ca/comBuf.h index 2269318df..bfa37597b 100644 --- a/src/ca/comBuf.h +++ b/src/ca/comBuf.h @@ -293,7 +293,7 @@ inline bool comBuf::push ( const epicsFloat32 & value ) return false; } // allow native floating point formats to be converted to IEEE - osiConvertToWireFormat ( value, & this->buf[index] ); + WireSetFloat32 ( value, & this->buf[index] ); this->nextWriteIndex = index + sizeof ( value ); return true; } @@ -306,7 +306,7 @@ inline bool comBuf::push ( const epicsFloat64 & value ) return false; } // allow native floating point formats to be converted to IEEE - osiConvertToWireFormat ( value, & this->buf[index] ); + WireSetFloat64 ( value, & this->buf[index] ); this->nextWriteIndex = index + sizeof ( value ); return true; } diff --git a/src/ca/comQueRecv.h b/src/ca/comQueRecv.h index 6ce9ce8a7..7f3153d8d 100644 --- a/src/ca/comQueRecv.h +++ b/src/ca/comQueRecv.h @@ -78,30 +78,34 @@ inline epicsInt32 comQueRecv::popInt32 () return static_cast < epicsInt32 > ( this->popUInt32() ); } -// this needs to be optimized, but since it is currently not used ... +// this has been optimized to aligned convert, maybe more could be done, +// but since it is currently not used ... inline epicsFloat32 comQueRecv::popFloat32 () { - epicsFloat32 tmp; - epicsUInt8 wire[ sizeof ( tmp ) ]; + union { + epicsUInt8 _wire[ sizeof ( epicsFloat32 ) ]; + epicsFloat32 _fp; + } tmp; // optimizer will unroll this loop - for ( unsigned i = 0u; i < sizeof ( tmp ); i++ ) { - wire[i] = this->popUInt8 (); + for ( unsigned i = 0u; i < sizeof ( tmp._wire ); i++ ) { + tmp._wire[i] = this->popUInt8 (); } - osiConvertFromWireFormat ( tmp, wire ); - return tmp; + return AlignedWireRef < epicsFloat32 > ( tmp._fp ); } -// this needs to be optimized, but since it is currently not used ... +// this has been optimized to aligned convert, maybe more could be done, +// but since it is currently not used ... inline epicsFloat64 comQueRecv::popFloat64 () { - epicsFloat64 tmp; - epicsUInt8 wire[ sizeof ( tmp ) ]; + union { + epicsUInt8 _wire[ sizeof ( epicsFloat64 ) ]; + epicsFloat64 _fp; + } tmp; // optimizer will unroll this loop - for ( unsigned i = 0u; i < sizeof ( tmp ); i++ ) { - wire[i] = this->popUInt8 (); + for ( unsigned i = 0u; i < sizeof ( tmp._wire ); i++ ) { + tmp._wire[i] = this->popUInt8 (); } - osiConvertFromWireFormat ( tmp, wire ); - return tmp; + return AlignedWireRef < epicsFloat64 > ( tmp._fp ); } #endif // ifndef comQueRecvh diff --git a/src/ca/convert.cpp b/src/ca/convert.cpp index 164c92497..e4d4c0640 100644 --- a/src/ca/convert.cpp +++ b/src/ca/convert.cpp @@ -28,23 +28,74 @@ #include "osiSock.h" #include "osiWireFormat.h" -#include "iocinf.h" -#include "caProto.h" - -typedef unsigned long arrayElementCount; - #define epicsExportSharedSymbols #include "net_convert.h" - -#if defined(VMS) -#include -#include -#endif +#include "iocinf.h" +#include "caProto.h" +#include "caerr.h" /* * NOOP if this isnt required */ -#ifdef CONVERSION_REQUIRED +#ifdef EPICS_CONVERSION_REQUIRED + +/* + * if hton is true then it is a host to network conversion + * otherwise vise-versa + * + * net format: big endian and IEEE float + */ +typedef void ( * CACVRTFUNCPTR ) ( + const void *pSrc, void *pDest, int hton, arrayElementCount count ); + +inline void dbr_htond ( + const dbr_double_t * pHost, dbr_double_t * pNet ) +{ + AlignedWireRef < epicsFloat64 > tmp ( *pNet ); + tmp = *pHost; +} +inline void dbr_ntohd ( + const dbr_double_t * pNet, dbr_double_t * pHost ) +{ + *pHost = AlignedWireRef < const epicsFloat64 > ( *pNet ); +} +inline void dbr_htonf ( + const dbr_float_t * pHost, dbr_float_t * pNet ) +{ + AlignedWireRef < epicsFloat32 > tmp ( *pNet ); + tmp = *pHost; +} +inline void dbr_ntohf ( + const dbr_float_t * pNet, dbr_float_t * pHost ) +{ + *pHost = AlignedWireRef < const epicsFloat32 > ( *pNet ); +} + +inline epicsUInt16 dbr_ntohs( const epicsUInt16 & net ) +{ + return AlignedWireRef < const epicsUInt16 > ( net ); +} + +inline epicsUInt16 dbr_htons ( const epicsUInt16 & host ) +{ + epicsUInt16 tmp; + AlignedWireRef < epicsUInt16 > awr ( tmp ); + awr = host; + return tmp; +} + +inline epicsUInt32 dbr_ntohl( const epicsUInt32 & net ) +{ + return AlignedWireRef < const epicsUInt32 > ( net ); +} + +inline epicsUInt32 dbr_htonl ( const epicsUInt32 & host ) +{ + epicsUInt32 tmp; + AlignedWireRef < epicsUInt32 > awr ( tmp ); + awr = host; + return tmp; +} /* * if hton is true then it is a host to network conversion @@ -54,11 +105,6 @@ typedef unsigned long arrayElementCount; * */ -#define dbr_ntohs(A) (epicsNTOH16(A)) -#define dbr_ntohl(A) (epicsNTOH32(A)) -#define dbr_htons(A) (epicsHTON16(A)) -#define dbr_htonl(A) (epicsHTON32(A)) - /* * CVRT_STRING() */ @@ -75,7 +121,7 @@ arrayElementCount num /* number of values */ /* convert "in place" -> nothing to do */ if (s == d) return; - memcpy(pDest, pSrc, num*MAX_STRING_SIZE); + memcpy ( pDest, pSrc, num*MAX_STRING_SIZE ); } /* @@ -84,21 +130,22 @@ arrayElementCount num /* number of values */ static void cvrt_short( const void *s, /* source */ void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ +int encode, /* cvrt HOST to NET if T */ arrayElementCount num /* number of values */ ) { dbr_short_t *pSrc = (dbr_short_t *) s; dbr_short_t *pDest = (dbr_short_t *) d; - arrayElementCount i; - for(i=0; i nothing to do */ if (s == d) return; - for(i=0; ivalue, pSrc->value, (MAX_STRING_SIZE * num)); + memcpy ( pDest->value, pSrc->value, (MAX_STRING_SIZE * num) ); } @@ -1330,380 +1368,8 @@ arrayElementCount num /* number of values */ memcpy(pDest->value, pSrc->value, (MAX_STRING_SIZE * num)); } -#if defined(CA_FLOAT_MIT) -/************************************************************************/ -/* double convert */ -/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */ -/************************************************************************/ - -/* (this includes mapping of fringe reals to zero or infinity) */ -/* (byte swaps included in conversion */ - -struct ieeedbl { - unsigned int mant2 : 32; - unsigned int mant1 : 20; - unsigned int exp : 11; - unsigned int sign : 1; -}; - -#define IEEE_DBL_SB 1023 - -/* Conversion Range */ -/* -1022exp) < (DBLEXPMINMIT+MIT_DBL_SB) ){ - pIEEE->mant1 = 0; - pIEEE->mant2 = 0; - pIEEE->exp = 0; - pIEEE->sign = 0; - } - else{ - pIEEE->exp = ((int)pMIT->exp)+(IEEE_DBL_SB-MIT_DBL_SB); - pIEEE->mant1 = (pMIT->mant1<<13) | (pMIT->mant2>>3); - pIEEE->mant2 = (pMIT->mant2<<29) | (pMIT->mant3<<13) | - (pMIT->mant4>>3); - pIEEE->sign = pMIT->sign; - } - - /* - * byte swap to net order - */ - ptmp = (ca_uint32_t *) pNet; - tmp = dbr_htonl(ptmp[0]); - ptmp[0] = dbr_htonl(ptmp[1]); - ptmp[1] = tmp; -#endif -} - -/* - * Converts IEEE double precision to VMS D or G floating point - * (D floating is the VAX C default, G floating is the Alpha C default) - * - * sign must be forced to zero if the exponent is zero to prevent a reserved - * operand fault- joh 9-13-90 - */ -void dbr_ntohd(dbr_double_t *pNet, dbr_double_t *pHost) -{ -#if defined(VMS) -# if defined(__G_FLOAT) && (__G_FLOAT == 1) - cvt$convert_float(pNet , CVT$K_IEEE_T, - pHost, CVT$K_VAX_G , - CVT$M_BIG_ENDIAN); -# else - cvt$convert_float(pNet , CVT$K_IEEE_T, - pHost, CVT$K_VAX_D , - CVT$M_BIG_ENDIAN); -# endif -#else - struct ieeedbl copyin; - struct mitdbl *pMIT; - struct ieeedbl *pIEEE; - ca_uint32_t *ptmp; - ca_uint32_t tmp; - - pIEEE = (struct ieeedbl *)pNet; - pMIT = (struct mitdbl *)pHost; - - /* - * Use internal buffer so the src and dest ptr - * can be identical - */ - copyin = *pIEEE; - pIEEE = ©in; - - /* - * Byte swap from net order to host order - */ - ptmp = (ca_uint32_t *) pIEEE; - tmp = dbr_htonl(ptmp[0]); - ptmp[0] = dbr_htonl(ptmp[1]); - ptmp[1] = tmp; - - if( ((int)pIEEE->exp) > (DBLEXPMAXMIT + IEEE_DBL_SB) ){ - pMIT->sign = pIEEE->sign; - pMIT->exp = DBLEXPMAXMIT + MIT_DBL_SB; - pMIT->mant1 = ~0; - pMIT->mant2 = ~0; - pMIT->mant3 = ~0; - pMIT->mant4 = ~0; - } - else if( ((int)pIEEE->exp) < (DBLEXPMINMIT + IEEE_DBL_SB) ){ - pMIT->sign = 0; - pMIT->exp = 0; - pMIT->mant1 = 0; - pMIT->mant2 = 0; - pMIT->mant3 = 0; - pMIT->mant4 = 0; - } - else{ - pMIT->sign = pIEEE->sign; - pMIT->exp = ((int)pIEEE->exp)+(MIT_DBL_SB-IEEE_DBL_SB); - pMIT->mant1 = pIEEE->mant1>>13; - pMIT->mant2 = (pIEEE->mant1<<3) | (pIEEE->mant2>>29); - pMIT->mant3 = pIEEE->mant2>>13; - pMIT->mant4 = pIEEE->mant2<<3; - } -#endif -} - -/************************************************************************/ -/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */ -/************************************************************************/ - -struct ieeeflt{ - unsigned mant :23; - unsigned exp :8; - unsigned sign :1; -}; - -/* Exponent sign bias */ -#define IEEE_SB 127 - -/* Conversion Range */ -/* -126sign; - - if( ((int)pMIT->exp) < EXPMINIEEE + MIT_SB){ - exp = 0; - mant = 0; - sign = 0; - } - else{ - exp = ((int)pMIT->exp)-MIT_SB+IEEE_SB; - mant = (pMIT->mant1<<16) | pMIT->mant2; - } - pIEEE->mant = mant; - pIEEE->exp = exp; - pIEEE->sign = sign; - *(ca_uint32_t *)pIEEE = dbr_htonl(*(ca_uint32_t *)pIEEE); -#endif -} - - -/* - * sign must be forced to zero if the exponent is zero to prevent a reserved - * operand fault- joh 9-13-90 - * - * Uses internal buffer so the src and dest ptr - * can be identical - */ -void dbr_ntohf(dbr_float_t *pNet, dbr_float_t *pHost) -{ -#if defined(VMS) - cvt$convert_float(pNet , CVT$K_IEEE_S, - pHost, CVT$K_VAX_F , - CVT$M_BIG_ENDIAN); -#else - struct mitflt *pMIT = (struct mitflt *) pHost; - struct ieeeflt *pIEEE = (struct ieeeflt *) pNet; - long exp,mant2,mant1,sign; - - *(ca_uint32_t *)pIEEE = dbr_ntohl(*(ca_uint32_t *)pIEEE); - if( ((int)pIEEE->exp) > EXPMAXMIT + IEEE_SB){ - sign = pIEEE->sign; - exp = EXPMAXMIT + MIT_SB; - mant2 = ~0; - mant1 = ~0; - } - else if( pIEEE->exp == 0){ - sign = 0; - exp = 0; - mant2 = 0; - mant1 = 0; - } - else{ - sign = pIEEE->sign; - exp = pIEEE->exp+MIT_SB-IEEE_SB; - mant2 = pIEEE->mant; - mant1 = pIEEE->mant>>(unsigned)16; - } - pMIT->exp = exp; - pMIT->mant2 = mant2; - pMIT->mant1 = mant1; - pMIT->sign = sign; -#endif -} - - -#endif /*CA_FLOAT_MIT*/ - -#if defined(CA_FLOAT_IEEE) - -/* - * dbr_htond () - * performs only byte swapping - */ -void dbr_htond (dbr_double_t *IEEEhost, dbr_double_t *IEEEnet) -{ -#ifdef CA_LITTLE_ENDIAN - ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost; - ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet; - - /* - * byte swap to net order - * (assume that src and dest ptrs - * may be identical) - */ -#ifndef _armv4l_ - /* pure little endian */ - ca_uint32_t tmp = pHost[0]; - pNet[0] = dbr_htonl (pHost[1]); - pNet[1] = dbr_htonl (tmp); -#else - /* impure little endian, compatible with archaic ARM FP hardware */ - pNet[0] = dbr_htonl (pHost[0]); - pNet[1] = dbr_htonl (pHost[1]); -#endif - -#else - *IEEEnet = *IEEEhost; -#endif -} - -/* - * dbr_ntohd () - * performs only byte swapping - */ -void dbr_ntohd (dbr_double_t *IEEEnet, dbr_double_t *IEEEhost) -{ -#ifdef CA_LITTLE_ENDIAN - ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost; - ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet; - - /* - * byte swap to net order - * (assume that src and dest ptrs - * may be identical) - */ -#ifndef _armv4l_ - /* pure little endian */ - ca_uint32_t tmp = pNet[0]; - pHost[0] = dbr_ntohl (pNet[1]); - pHost[1] = dbr_ntohl (tmp); -#else - /* impure little endian, compatible with archaic ARM FP hardware */ - pHost[0] = dbr_ntohl (pNet[0]); - pHost[1] = dbr_ntohl (pNet[1]); -#endif - -#else - *IEEEhost = *IEEEnet; -#endif -} - -/* - * dbr_ntohf () - * performs only byte swapping - */ -void dbr_ntohf (dbr_float_t *IEEEnet, dbr_float_t *IEEEhost) -{ - ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost; - ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet; - - *pHost = dbr_ntohl (*pNet); -} - -/* - * dbr_htonf () - * performs only byte swapping - */ -void dbr_htonf (dbr_float_t *IEEEhost, dbr_float_t *IEEEnet) -{ - ca_uint32_t *pHost = (ca_uint32_t *) IEEEhost; - ca_uint32_t *pNet = (ca_uint32_t *) IEEEnet; - - *pNet = dbr_htonl (*pHost); -} - -#endif /* IEEE float and little endian */ - /* cvrt is (array of) (pointer to) (function returning) int */ -epicsShareDef CACVRTFUNC *cac_dbr_cvrt[] = { +static CACVRTFUNCPTR cac_dbr_cvrt[] = { cvrt_string, cvrt_short, cvrt_float, @@ -1750,5 +1416,24 @@ epicsShareDef CACVRTFUNC *cac_dbr_cvrt[] = { cvrt_string }; -#endif /* CONVERSION_REQUIRED */ +#endif /* EPICS_CONVERSION_REQUIRED */ + +int caNetConvert ( unsigned type, const void *pSrc, void *pDest, + int hton, arrayElementCount count ) +{ +# ifdef EPICS_CONVERSION_REQUIRED + if ( type >= NELEMENTS ( cac_dbr_cvrt ) ) { + return ECA_BADTYPE; + } + ( * cac_dbr_cvrt [ type ] ) ( pSrc, pDest, hton, count ); +# else + if ( INVALID_DB_REQ ( type ) ) { + return ECA_BADTYPE; + } + if ( pSrc != pDest ) { + memcpy ( pDest, pSrc, count ); + } +# endif + return ECA_NORMAL; +} diff --git a/src/ca/net_convert.h b/src/ca/net_convert.h index 733ff16a0..bee51c0c4 100644 --- a/src/ca/net_convert.h +++ b/src/ca/net_convert.h @@ -23,99 +23,11 @@ extern "C" { #endif -/* - * Here are the definitions for architecture dependent byte ordering - * and floating point format - */ -#if defined (_M_IX86) || defined (_X86_) || defined (__i386__) || defined(_armv4l_) || defined (_X86_64_) -# define CA_FLOAT_IEEE -# define CA_LITTLE_ENDIAN -#elif defined (VAX) -# define CA_FLOAT_MIT -# define CA_LITTLE_ENDIAN -#elif ( defined (__ALPHA) || defined (__alpha) ) && ( defined (VMS) || defined (__VMS) ) -# define CA_FLOAT_MIT -# define CA_LITTLE_ENDIAN -#elif ( defined (__ALPHA) || defined (__alpha) ) && defined (UNIX) -# define CA_FLOAT_IEEE -# define CA_LITTLE_ENDIAN -#else -# define CA_FLOAT_IEEE -# define CA_BIG_ENDIAN -#endif +typedef unsigned long arrayElementCount; -/* - * some architecture sanity checks - */ -#if defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN) -# error defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN) -#endif -#if !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN) -# error !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN) -#endif -#if defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT) -# error defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT) -#endif -#if !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT) -# error !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT) -#endif - -/* - * CONVERSION_REQUIRED is set if either the byte order - * or the floating point does not match - */ -#if !defined(CA_FLOAT_IEEE) || !defined(CA_BIG_ENDIAN) -# define CONVERSION_REQUIRED -#endif - -/* - * if hton is true then it is a host to network conversion - * otherwise vise-versa - * - * net format: big endian and IEEE float - */ - -typedef void CACVRTFUNC (const void *pSrc, void *pDest, - int hton, arrayElementCount count); - -#ifdef CONVERSION_REQUIRED -/* cvrt is (array of) (pointer to) (function returning) int */ -epicsShareExtern CACVRTFUNC *cac_dbr_cvrt[LAST_BUFFER_TYPE+1]; -#endif - -#if defined(CA_FLOAT_IEEE) && !defined(CA_LITTLE_ENDIAN) -# ifdef _cplusplus - inline void dbr_htond ( dbr_double_t *IEEEhost, dbr_double_t *IEEEnet ) - { - *IEEEnet = *IEEEhost; - } - inline void dbr_ntohd ( dbr_double_t *IEEEnet, dbr_double_t *IEEEhost ) - { - *IEEEhost = *IEEEnet; - } - inline void dbr_htonf ( dbr_float_t *IEEEhost, dbr_float_t *IEEEnet ) - { - *IEEEnet = *IEEEhost; - } - inline void dbr_ntohf ( dbr_float_t *IEEEnet, dbr_float_t *IEEEhost ) - { - *IEEEhost = *IEEEnet; - } -# else - /* - * for rsrv - */ - #define dbr_htond(IEEEhost, IEEEnet) (*IEEEnet = *IEEEhost) - #define dbr_ntohd(IEEEnet, IEEEhost) (*IEEEhost = *IEEEnet) - #define dbr_htonf(IEEEhost, IEEEnet) (*IEEEnet = *IEEEhost) - #define dbr_ntohf(IEEEnet, IEEEhost) (*IEEEhost = *IEEEnet) -# endif -#else - epicsShareFunc void dbr_htond ( dbr_double_t *pHost, dbr_double_t *pNet ); - epicsShareFunc void dbr_ntohd ( dbr_double_t *pNet, dbr_double_t *pHost ); - epicsShareFunc void dbr_htonf ( dbr_float_t *pHost, dbr_float_t *pNet ); - epicsShareFunc void dbr_ntohf ( dbr_float_t *pNet, dbr_float_t *pHost ); -#endif +epicsShareFunc int caNetConvert ( + unsigned type, const void *pSrc, void *pDest, + int hton, arrayElementCount count ); #ifdef __cplusplus }