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

Revision 1867, 9.8 KB checked in by dietz, 14 years ago (diff)

Changed logging for bad header values in WaveMsg2MakeLocal() to include
all header values because one never knows which value is bogus.

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