EPICS Base  7.0.6.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
osdWireFormat.h
1 /*************************************************************************\
2 * Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * SPDX-License-Identifier: EPICS
7 * EPICS BASE is distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 
11 /*
12  * Author Jeffrey O. Hill
14  */
15 
16 #ifndef osdWireFormat
17 #define osdWireFormat
18 
19 #ifdef __SUNPRO_CC
20 # include <string.h>
21 #else
22 # include <cstring>
23 #endif
24 
25 #include "epicsEndian.h"
26 
27 //
28 // The default assumption is that the local floating point format is
29 // IEEE and that these routines only need to perform byte swapping
30 // as a side effect of copying an aligned operand into an unaligned
31 // network byte stream. OS specific code can provide a alternative
32 // for this file if that assumption is wrong.
33 //
34 
35 //
36 // EPICS_CONVERSION_REQUIRED is set if either the byte order
37 // or the floating point word order are not exactly big endian.
38 // This can be set by hand above for a specific architecture
39 // should there be an architecture that is a weird middle endian
40 // ieee floating point format that is also big endian integer.
41 //
42 #if EPICS_BYTE_ORDER != EPICS_ENDIAN_BIG || EPICS_FLOAT_WORD_ORDER != EPICS_BYTE_ORDER
43 # if ! defined ( EPICS_CONVERSION_REQUIRED )
44 # define EPICS_CONVERSION_REQUIRED
45 # endif
46 #endif
47 
48 //
49 // We still use a big endian wire format for CA consistent with the internet,
50 // but inconsistent with the vast majority of CPUs
51 //
52 
53 template <>
54 inline void WireGet < epicsFloat64 > (
55  const epicsUInt8 * pWireSrc, epicsFloat64 & dst )
56 {
57  // copy through union here
58  // a) prevents over-aggressive optimization under strict aliasing rules
59  // b) doesnt preclude extra copy operation being optimized away
60  union {
61  epicsFloat64 _f;
62  epicsUInt32 _u[2];
63  } tmp;
64 # if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
65  WireGet ( pWireSrc, tmp._u[1] );
66  WireGet ( pWireSrc + 4, tmp._u[0] );
67 # elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
68  WireGet ( pWireSrc, tmp._u[0] );
69  WireGet ( pWireSrc + 4, tmp._u[1] );
70 # else
71 # error unsupported floating point word order
72 # endif
73  dst = tmp._f;
74 }
75 
76 #if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 )
77 template <>
78 inline void WireGet < epicsOldString > (
79  const epicsUInt8 * pWireSrc, epicsOldString & dst )
80 {
81  memcpy ( dst, pWireSrc, sizeof ( dst ) );
82 }
83 #else
84 inline void WireGet (
85  const epicsUInt8 * pWireSrc, epicsOldString & dst )
86 {
87  memcpy ( dst, pWireSrc, sizeof ( dst ) );
88 }
89 #endif
90 
91 template <>
92 inline void WireSet < epicsFloat64 > (
93  const epicsFloat64 & src, epicsUInt8 * pWireDst )
94 {
95  // copy through union here
96  // a) prevents over-aggressive optimization under strict aliasing rules
97  // b) doesnt preclude extra copy operation being optimized away
98  union {
99  epicsFloat64 _f;
100  epicsUInt32 _u[2];
101  } tmp;
102  tmp._f = src;
103 # if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
104  WireSet ( tmp._u[1], pWireDst );
105  WireSet ( tmp._u[0], pWireDst + 4 );
106 # elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
107  WireSet ( tmp._u[0], pWireDst );
108  WireSet ( tmp._u[1], pWireDst + 4 );
109 # else
110 # error unsupported floating point word order
111 # endif
112 }
113 
114 #if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 )
115 template <>
116 inline void WireSet < epicsOldString > (
117  const epicsOldString & src, epicsUInt8 * pWireDst )
118 {
119  memcpy ( pWireDst, src, sizeof ( src ) );
120 }
121 #else
122 inline void WireSet (
123  const epicsOldString & src, epicsUInt8 * pWireDst )
124 {
125  memcpy ( pWireDst, src, sizeof ( src ) );
126 }
127 #endif
128 
129 template <>
130 inline void AlignedWireGet < epicsUInt16 > (
131  const epicsUInt16 & src, epicsUInt16 & dst )
132 {
133 # if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
134  dst = byteSwap ( src );
135 # elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
136  dst = src;
137 # else
138 # error unsupported endian type
139 # endif
140 }
141 
142 template <>
143 inline void AlignedWireGet < epicsUInt32 > (
144  const epicsUInt32 & src, epicsUInt32 & dst )
145 {
146 # if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
147  dst = byteSwap ( src );
148 # elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
149  dst = src;
150 # else
151 # error unsupported endian type
152 # endif
153 }
154 
155 template <>
156 inline void AlignedWireGet < epicsFloat64 > (
157  const epicsFloat64 & src, epicsFloat64 & dst )
158 {
159  // copy through union here
160  // a) prevents over-aggressive optimization under strict aliasing rules
161  // b) doesnt preclude extra copy operation being optimized away
162  union Swapper {
163  epicsUInt32 _u[2];
164  epicsFloat64 _f;
165  };
166 # if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER
167  dst = src;
168 # elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
169  Swapper tmp;
170  tmp._f = src;
171  AlignedWireGet ( tmp._u[0], tmp._u[0] );
172  AlignedWireGet ( tmp._u[1], tmp._u[1] );
173  dst = tmp._f;
174 # elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
175  Swapper srcu, dstu;
176  srcu._f = src;
177  AlignedWireGet ( srcu._u[1], dstu._u[0] );
178  AlignedWireGet ( srcu._u[0], dstu._u[1] );
179  dst = dstu._f;
180 # else
181 # error unsupported floating point word order
182 # endif
183 }
184 
185 template <>
186 inline void AlignedWireSet < epicsUInt16 >
187  ( const epicsUInt16 & src, epicsUInt16 & dst )
188 {
189 # if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
190  dst = byteSwap ( src );
191 # elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
192  dst = src;
193 # else
194 # error undefined endian type
195 # endif
196 }
197 
198 template <>
199 inline void AlignedWireSet < epicsUInt32 > (
200  const epicsUInt32 & src, epicsUInt32 & dst )
201 {
202 # if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
203  dst = byteSwap ( src );
204 # elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
205  dst = src;
206 # else
207 # error undefined endian type
208 # endif
209 }
210 
211 template <>
212 inline void AlignedWireSet < epicsFloat64 > (
213  const epicsFloat64 & src, epicsFloat64 & dst )
214 {
215  // copy through union here
216  // a) prevents over-aggressive optimization under strict aliasing rules
217  // b) doesnt preclude extra copy operation being optimized away
218  union Swapper {
219  epicsUInt32 _u[2];
220  epicsFloat64 _f;
221  };
222 # if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER
223  dst = src;
224 # elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG
225  Swapper tmp;
226  tmp._f = src;
227  AlignedWireSet ( tmp._u[0], tmp._u[0] );
228  AlignedWireSet ( tmp._u[1], tmp._u[1] );
229  dst = tmp._f;
230 # elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE
231  Swapper srcu, dstu;
232  srcu._f = src;
233  AlignedWireSet ( srcu._u[1], dstu._u[0] );
234  AlignedWireSet ( srcu._u[0], dstu._u[1] );
235  dst = dstu._f;
236 # else
237 # error unsupported floating point word order
238 # endif
239 }
240 
241 #endif // osdWireFormat
char epicsOldString[MAX_STRING_SIZE]
!! Don&#39;t use this - it may vanish in the future !!
Definition: epicsTypes.h:75