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