In some cases the license-identification header was missing, so I added that as well. Replaced the remaining headers that specifically identified "Versions 3.13.7 and higher". Makefiles and the build system were deliberately excluded.
242 lines
7.0 KiB
C++
242 lines
7.0 KiB
C++
/*************************************************************************\
|
|
* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne
|
|
* National Laboratory.
|
|
* Copyright (c) 2002 The Regents of the University of California, as
|
|
* Operator of Los Alamos National Laboratory.
|
|
* SPDX-License-Identifier: EPICS
|
|
* EPICS BASE is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
|
|
/*
|
|
* Author Jeffrey O. Hill
|
|
* johill@lanl.gov
|
|
*/
|
|
|
|
#ifndef osdWireFormat
|
|
#define osdWireFormat
|
|
|
|
#ifdef __SUNPRO_CC
|
|
# include <string.h>
|
|
#else
|
|
# include <cstring>
|
|
#endif
|
|
|
|
#include "epicsEndian.h"
|
|
|
|
//
|
|
// The default assumption is that the local floating point format is
|
|
// IEEE and that these routines only need to perform byte swapping
|
|
// as a side effect of copying an aligned operand into an unaligned
|
|
// network byte stream. OS specific code can provide a alternative
|
|
// for this file if that assumption is wrong.
|
|
//
|
|
|
|
//
|
|
// EPICS_CONVERSION_REQUIRED is set if either the byte order
|
|
// or the floating point word order are not exactly big endian.
|
|
// This can be set by hand above for a specific architecture
|
|
// should there be an architecture that is a weird middle endian
|
|
// ieee floating point format that is also big endian integer.
|
|
//
|
|
#if EPICS_BYTE_ORDER != EPICS_ENDIAN_BIG || EPICS_FLOAT_WORD_ORDER != EPICS_BYTE_ORDER
|
|
# if ! defined ( EPICS_CONVERSION_REQUIRED )
|
|
# define EPICS_CONVERSION_REQUIRED
|
|
# endif
|
|
#endif
|
|
|
|
//
|
|
// We still use a big endian wire format for CA consistent with the internet,
|
|
// but inconsistent with the vast majority of CPUs
|
|
//
|
|
|
|
template <>
|
|
inline void WireGet < epicsFloat64 > (
|
|
const epicsUInt8 * pWireSrc, epicsFloat64 & dst )
|
|
{
|
|
// copy through union here
|
|
// a) prevents over-aggressive optimization under strict aliasing rules
|
|
// b) doesnt preclude extra copy operation being optimized away
|
|
union {
|
|
epicsFloat64 _f;
|
|
epicsUInt32 _u[2];
|
|
} tmp;
|
|
# if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
|
|
WireGet ( pWireSrc, tmp._u[1] );
|
|
WireGet ( pWireSrc + 4, tmp._u[0] );
|
|
# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
|
|
WireGet ( pWireSrc, tmp._u[0] );
|
|
WireGet ( pWireSrc + 4, tmp._u[1] );
|
|
# else
|
|
# error unsupported floating point word order
|
|
# endif
|
|
dst = tmp._f;
|
|
}
|
|
|
|
#if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 )
|
|
template <>
|
|
inline void WireGet < epicsOldString > (
|
|
const epicsUInt8 * pWireSrc, epicsOldString & dst )
|
|
{
|
|
memcpy ( dst, pWireSrc, sizeof ( dst ) );
|
|
}
|
|
#else
|
|
inline void WireGet (
|
|
const epicsUInt8 * pWireSrc, epicsOldString & dst )
|
|
{
|
|
memcpy ( dst, pWireSrc, sizeof ( dst ) );
|
|
}
|
|
#endif
|
|
|
|
template <>
|
|
inline void WireSet < epicsFloat64 > (
|
|
const epicsFloat64 & src, epicsUInt8 * pWireDst )
|
|
{
|
|
// copy through union here
|
|
// a) prevents over-aggressive optimization under strict aliasing rules
|
|
// b) doesnt preclude extra copy operation being optimized away
|
|
union {
|
|
epicsFloat64 _f;
|
|
epicsUInt32 _u[2];
|
|
} tmp;
|
|
tmp._f = src;
|
|
# if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
|
|
WireSet ( tmp._u[1], pWireDst );
|
|
WireSet ( tmp._u[0], pWireDst + 4 );
|
|
# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
|
|
WireSet ( tmp._u[0], pWireDst );
|
|
WireSet ( tmp._u[1], pWireDst + 4 );
|
|
# else
|
|
# error unsupported floating point word order
|
|
# endif
|
|
}
|
|
|
|
#if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 )
|
|
template <>
|
|
inline void WireSet < epicsOldString > (
|
|
const epicsOldString & src, epicsUInt8 * pWireDst )
|
|
{
|
|
memcpy ( pWireDst, src, sizeof ( src ) );
|
|
}
|
|
#else
|
|
inline void WireSet (
|
|
const epicsOldString & src, epicsUInt8 * pWireDst )
|
|
{
|
|
memcpy ( pWireDst, src, sizeof ( src ) );
|
|
}
|
|
#endif
|
|
|
|
template <>
|
|
inline void AlignedWireGet < epicsUInt16 > (
|
|
const epicsUInt16 & src, epicsUInt16 & dst )
|
|
{
|
|
# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
|
|
dst = byteSwap ( src );
|
|
# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
|
|
dst = src;
|
|
# else
|
|
# error unsupported endian type
|
|
# endif
|
|
}
|
|
|
|
template <>
|
|
inline void AlignedWireGet < epicsUInt32 > (
|
|
const epicsUInt32 & src, epicsUInt32 & dst )
|
|
{
|
|
# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
|
|
dst = byteSwap ( src );
|
|
# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
|
|
dst = src;
|
|
# else
|
|
# error unsupported endian type
|
|
# endif
|
|
}
|
|
|
|
template <>
|
|
inline void AlignedWireGet < epicsFloat64 > (
|
|
const epicsFloat64 & src, epicsFloat64 & dst )
|
|
{
|
|
// copy through union here
|
|
// a) prevents over-aggressive optimization under strict aliasing rules
|
|
// b) doesnt preclude extra copy operation being optimized away
|
|
union Swapper {
|
|
epicsUInt32 _u[2];
|
|
epicsFloat64 _f;
|
|
};
|
|
# if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER
|
|
dst = src;
|
|
# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
|
|
Swapper tmp;
|
|
tmp._f = src;
|
|
AlignedWireGet ( tmp._u[0], tmp._u[0] );
|
|
AlignedWireGet ( tmp._u[1], tmp._u[1] );
|
|
dst = tmp._f;
|
|
# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
|
|
Swapper srcu, dstu;
|
|
srcu._f = src;
|
|
AlignedWireGet ( srcu._u[1], dstu._u[0] );
|
|
AlignedWireGet ( srcu._u[0], dstu._u[1] );
|
|
dst = dstu._f;
|
|
# else
|
|
# error unsupported floating point word order
|
|
# endif
|
|
}
|
|
|
|
template <>
|
|
inline void AlignedWireSet < epicsUInt16 >
|
|
( const epicsUInt16 & src, epicsUInt16 & dst )
|
|
{
|
|
# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
|
|
dst = byteSwap ( src );
|
|
# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
|
|
dst = src;
|
|
# else
|
|
# error undefined endian type
|
|
# endif
|
|
}
|
|
|
|
template <>
|
|
inline void AlignedWireSet < epicsUInt32 > (
|
|
const epicsUInt32 & src, epicsUInt32 & dst )
|
|
{
|
|
# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
|
|
dst = byteSwap ( src );
|
|
# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
|
|
dst = src;
|
|
# else
|
|
# error undefined endian type
|
|
# endif
|
|
}
|
|
|
|
template <>
|
|
inline void AlignedWireSet < epicsFloat64 > (
|
|
const epicsFloat64 & src, epicsFloat64 & dst )
|
|
{
|
|
// copy through union here
|
|
// a) prevents over-aggressive optimization under strict aliasing rules
|
|
// b) doesnt preclude extra copy operation being optimized away
|
|
union Swapper {
|
|
epicsUInt32 _u[2];
|
|
epicsFloat64 _f;
|
|
};
|
|
# if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER
|
|
dst = src;
|
|
# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
|
|
Swapper tmp;
|
|
tmp._f = src;
|
|
AlignedWireSet ( tmp._u[0], tmp._u[0] );
|
|
AlignedWireSet ( tmp._u[1], tmp._u[1] );
|
|
dst = tmp._f;
|
|
# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
|
|
Swapper srcu, dstu;
|
|
srcu._f = src;
|
|
AlignedWireSet ( srcu._u[1], dstu._u[0] );
|
|
AlignedWireSet ( srcu._u[0], dstu._u[1] );
|
|
dst = dstu._f;
|
|
# else
|
|
# error unsupported floating point word order
|
|
# endif
|
|
}
|
|
|
|
#endif // osdWireFormat
|