source: trunk/src/libsrc/util/swap.c @ 3193

Revision 3193, 10.1 KB checked in by paulf, 12 years ago (diff)

made swap functions long int tolerant where in some OS, long can be 8 bytes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1
2/*
3 *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
4 *   CHECKED IT OUT USING THE COMMAND CHECKOUT.
5 *
6 *    $Id$
7 *
8 *    Revision history:
9 *     $Log$
10 *     Revision 1.11  2007/12/16 18:42:19  paulf
11 *     made swap functions long int tolerant where in some OS, long can be 8 bytes
12 *
13 *     Revision 1.10  2005/06/13 18:15:41  dietz
14 *     Changed logging for bad header values in WaveMsg2MakeLocal() to include
15 *     all header values because one never knows which value is bogus.
16 *
17 *     Revision 1.9  2005/06/10 21:41:06  patton
18 *     Modified comment for clarity (at least clear to me).  JMP
19 *
20 *     Revision 1.8  2005/06/10 21:19:30  patton
21 *     Put in more meaningful comment into WaveMsg2MakeLocal to explain to the user
22 *     the case that the tracebuf does not end within 5 samples of the given endtime.
23 *     JMP
24 *
25 *     Revision 1.7  2004/04/13 22:59:38  dietz
26 *     Added WaveMsg2MakeLocal()
27 *
28 *     Revision 1.6  2003/10/20 17:08:06  mark
29 *     Added compiler flags check
30 *
31 *     Revision 1.5  2002/06/18 18:33:55  davidk
32 *     fixed the sanity check of the header in WaveMsgMakeLocal().
33 *     It contained a bug that made it useless.
34 *
35 *     Revision 1.4  2002/06/11 23:08:17  davidk
36 *     Paul Friberg submitted a fix to WaveMsgMakeLocal, that copies the
37 *     TRACE_HEADER to local variables to avoid byte alignment problems
38 *     before examining the header.  (Bug was introduced by most
39 *     recent change by davek that included code which examined the
40 *     contents of the header without 8-byte aligning data.
41 *
42 *     Revision 1.3  2002/03/20 22:13:28  davidk
43 *     Modified WaveMsgMakeLocal():
44 *      Function now converts the header, performs a checksum on the header,
45 *       and then if successful converts the binary data portion of the tracebuf.
46 *      Function now returns -2 if the header checksum conversion fails.
47 *      Function now returns -1 if _INTEL or _SPARC is not defined.
48 *       (Formerly, no conversion was done and success was returned.)
49 *
50 *     Revision 1.2  2000/06/22 17:49:33  kohler
51 *     Modified by WMK to allow in-place swapping of non-byte-alligned data.
52 *
53 *     Revision 1.1  2000/02/14 18:51:48  lucky
54 *     Initial revision
55 *
56 *
57 */
58
59/*
60 * SWAP.C
61 *
62 *  Byte swapping functions
63 */
64 
65/* Make sure one of the platforms is defined properly... */ 
66#ifndef _INTEL
67 #ifndef _SPARC
68  #error _INTEL and _SPARC are both undefined
69 #endif
70#endif
71
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75#include <swap.h>
76
77void SwapShort( short *data )
78{
79   char temp;
80
81   union {
82      char  c[2];
83   } dat;
84
85   memcpy( &dat, data, sizeof(short) );
86   temp     = dat.c[0];
87   dat.c[0] = dat.c[1];
88   dat.c[1] = temp;
89   memcpy( data, &dat, sizeof(short) );
90   return;
91}
92
93void SwapInt( int *data )
94{
95   char temp;
96
97   union {
98      char c[4];
99   } dat;
100
101   memcpy( &dat, data, sizeof(int) );
102   temp     = dat.c[0];
103   dat.c[0] = dat.c[3];
104   dat.c[3] = temp;
105   temp     = dat.c[1];
106   dat.c[1] = dat.c[2];
107   dat.c[2] = temp;
108   memcpy( data, &dat, sizeof(int) );
109   return;
110}
111
112
113void SwapLong( long *data )
114{
115   char temp;
116
117   union {
118      char c[4];
119   } dat;
120
121   if (sizeof(long) == 8) {
122      fprintf(stderr, "FATAL ERROR: SwapLong() assumes 4 byte longs and sizeof(long)=%d\n", sizeof(long));
123      exit(9);
124   }
125
126   memcpy( &dat, data, sizeof(long) );
127   temp     = dat.c[0];
128   dat.c[0] = dat.c[3];
129   dat.c[3] = temp;
130   temp     = dat.c[1];
131   dat.c[1] = dat.c[2];
132   dat.c[2] = temp;
133   memcpy( data, &dat, sizeof(long) );
134   return;
135}
136
137void SwapDouble( double *data )
138{
139   char temp;
140
141   union {
142       char   c[8];
143   } dat;
144
145   memcpy( &dat, data, sizeof(double) );
146   temp     = dat.c[0];
147   dat.c[0] = dat.c[7];
148   dat.c[7] = temp;
149
150   temp     = dat.c[1];
151   dat.c[1] = dat.c[6];
152   dat.c[6] = temp;
153
154   temp     = dat.c[2];
155   dat.c[2] = dat.c[5];
156   dat.c[5] = temp;
157
158   temp     = dat.c[3];
159   dat.c[3] = dat.c[4];
160   dat.c[4] = temp;
161   memcpy( data, &dat, sizeof(double) );
162   return;
163}
164
165/************************ WaveMsgMakeLocal **************************
166*       Byte-swap a universal TYPE_TRACEBUF message in place.       *
167*       Changes the 'datatype' field in the message header          *
168*       Returns -1 if unknown data type.                            *
169*       Returns -1 if _SPARC or _INTEL not defined.                 *
170*       Returns -2 if checksumish calculation of header fails.      *
171*       Elsewise (SUCCESS) returns 0.                               *
172*********************************************************************/
173
174int WaveMsgMakeLocal( TRACE_HEADER* wvmsg )
175{
176  return( WaveMsg2MakeLocal( (TRACE2_HEADER *) wvmsg ) );
177}
178
179
180/************************ WaveMsg2MakeLocal *************************
181*       Byte-swap a universal TYPE_TRACEBUF2 message in place.      *
182*       Changes the 'datatype' field in the message header          *
183*       Returns -1 if unknown data type.                            *
184*       Returns -1 if _SPARC or _INTEL not defined.                 *
185*       Returns -2 if checksumish calculation of header fails.      *
186*       Elsewise (SUCCESS) returns 0.                               *
187*********************************************************************/
188
189int WaveMsg2MakeLocal( TRACE2_HEADER* wvmsg )
190{
191   int    dataSize;  /* flag telling us how many bytes in the data */
192   char   byteOrder;
193   int*   intPtr;
194   short* shortPtr;
195   int    i;
196   int    nsamp;
197   double samprate,starttime,endtime;
198   double tShouldEnd; 
199   double dFudgeFactor;
200
201   /* See what sort of data it carries
202    **********************************/
203   dataSize=0;
204   if ( strcmp(wvmsg->datatype, "s4")==0)
205   {
206        dataSize=4; byteOrder='s';
207   }
208   else if ( strcmp(wvmsg->datatype, "i4")==0)
209   {
210        dataSize=4; byteOrder='i';
211   }
212   else if ( strcmp(wvmsg->datatype, "s2")==0)
213   {
214        dataSize=2; byteOrder='s';
215   }
216   else if ( strcmp(wvmsg->datatype, "i2")==0)
217   {
218        dataSize=2; byteOrder='i';
219   }
220   else
221        return(-1); /* We don't know this message type*/
222
223   /* SWAP the header (if neccessary) */
224#if defined( _SPARC )
225   if (byteOrder =='i')
226   {
227        /* swap the header
228        *****************/
229        SwapInt( &(wvmsg->pinno) );
230        SwapInt( &(wvmsg->nsamp) );
231        SwapDouble( &(wvmsg->starttime) );
232        SwapDouble( &(wvmsg->endtime)   );
233        SwapDouble( &(wvmsg->samprate)  );
234   }
235
236#elif defined( _INTEL )
237   if (byteOrder =='s')
238   {
239        /* swap the header
240        *****************/
241        SwapInt( &(wvmsg->pinno) );
242        SwapInt( &(wvmsg->nsamp) );
243        SwapDouble( &(wvmsg->starttime) );
244        SwapDouble( &(wvmsg->endtime)   );
245        SwapDouble( &(wvmsg->samprate)  );
246   }
247#else
248   printf( "WaveMsg2MakeLocal warning: _INTEL and _SPARC are both undefined." );
249   return(-1);
250#endif
251
252
253/* Perform a CheckSumish kind of calculation on the header
254 * ensure that the tracebuf ends within 5 samples of the given endtime.
255 * DK 2002/03/18
256 *********************************************************************/
257
258/* moved nsamp memcpy to here to avoid byte-alignment with next statement */
259   memcpy( &nsamp,     &wvmsg->nsamp,     sizeof(int)    );
260   memcpy( &samprate,  &wvmsg->samprate,  sizeof(double) );
261   memcpy( &starttime, &wvmsg->starttime, sizeof(double) );
262   memcpy( &endtime,   &wvmsg->endtime,   sizeof(double) );
263
264   tShouldEnd   = starttime + ((nsamp - 1) / samprate);
265   dFudgeFactor = 5.0 / samprate;
266
267/* This is supposed to be a simple sanity check to ensure that the
268 * endtime is within 5 samples of where it should be.  We're not
269 * trying to be judgemental here, we're just trying to ensure that
270 * we protect ourselves from complete garbage, so that we don't segfault
271 * when allocating samples based on a bad nsamp
272 ***********************************************************************/
273   if( endtime < (tShouldEnd-dFudgeFactor) || 
274       endtime > (tShouldEnd+dFudgeFactor)    )
275   {
276      logit("e","WaveMsg2MakeLocal: packet from %s.%s.%s.%s has inconsistent "
277                "header values!\n", wvmsg->sta, wvmsg->chan, wvmsg->net, wvmsg->loc );
278      logit("e","WaveMsg2MakeLocal: header.starttime  : %.4lf\n", starttime  );
279      logit("e","WaveMsg2MakeLocal: header.samplerate : %.1lf\n", samprate   );
280      logit("e","WaveMsg2MakeLocal: header.nsample    : %d\n",    nsamp      );
281      logit("e","WaveMsg2MakeLocal: header.endtime    : %.4lf\n", endtime    );
282      logit("e","WaveMsg2MakeLocal: computed.endtime  : %.4lf\n", tShouldEnd );
283      logit("e","WaveMsg2MakeLocal: header.endtime is not within 5 sample intervals "
284                "of computed.endtime!\n" );
285      return(-2);
286   }
287 
288   /* SWAP the data (if neccessary) */
289#if defined( _SPARC )
290
291   if (byteOrder =='i')
292   {
293   /* Swap the data.  */
294        intPtr=(int*) ((char*)wvmsg + sizeof(TRACE2_HEADER) );
295        shortPtr=(short*) ((char*)wvmsg + sizeof(TRACE2_HEADER) );
296        for( i=0; i<nsamp; i++)
297        {
298                if(dataSize==2) SwapShort( &(shortPtr[i]) );
299                if(dataSize==4) SwapInt(  &(intPtr[i])  );
300        }
301        /* Re-write the data type field in the message
302        **********************************************/
303        if(dataSize==2) strcpy(wvmsg->datatype,"s2");
304        if(dataSize==4) strcpy(wvmsg->datatype,"s4");
305   }
306
307#elif defined( _INTEL )
308
309   if (byteOrder =='s')
310   {
311   /* Swap the data.  */
312        intPtr=(int*) ((char*)wvmsg + sizeof(TRACE2_HEADER) );
313        shortPtr=(short*) ((char*)wvmsg + sizeof(TRACE2_HEADER) );
314        for( i=0; i<nsamp; i++)
315        {
316                if(dataSize==2) SwapShort( &(shortPtr[i]) );
317                if(dataSize==4) SwapInt(  &(intPtr[i])  );
318        }
319        /* Re-write the data type field in the message
320        **********************************************/
321        if(dataSize==2) strcpy(wvmsg->datatype,"i2");
322        if(dataSize==4) strcpy(wvmsg->datatype,"i4");
323   }
324#else
325   printf( "WaveMsg2MakeLocal warning: _INTEL and _SPARC are both undefined." );
326#endif
327
328   return(0);
329}
330
331
332void SwapFloat( float *data )
333{
334   char temp;
335
336   union {
337      char c[4];
338   } dat;
339
340   memcpy( &dat, data, sizeof(float) );
341   temp     = dat.c[0];
342   dat.c[0] = dat.c[3];
343   dat.c[3] = temp;
344   temp     = dat.c[1];
345   dat.c[1] = dat.c[2];
346   dat.c[2] = temp;
347   memcpy( data, &dat, sizeof(float) );
348   return;
349}
350
Note: See TracBrowser for help on using the repository browser.