1 /***************************************************************************
2  * gswap.c:
3  *
4  * Functions for generalized, in-place byte swapping between LSBF and
5  * MSBF byte orders.
6  *
7  * Some standard integer types are needed, namely uint8_t and
8  * uint32_t, (these are normally declared by including inttypes.h or
9  * stdint.h).  Each function expects it's input to be a void pointer
10  * to a quantity of the appropriate size.
11  *
12  * There are two versions of most routines, one that works on
13  * quantities regardless of alignment (gswapX) and one that works on
14  * memory aligned quantities (gswapXa).  The memory aligned versions
15  * (gswapXa) are much faster than the other versions (gswapX), but the
16  * memory *must* be aligned.
17  *
18  * Written by Chad Trabant,
19  *   IRIS Data Management Center
20  *
21  * Version: 2010.006
22  ***************************************************************************/
23 
24 #include "libmseed.h"
25 
26 /* Swap routines that work on any (aligned or not) quantities */
27 
28 void
ms_gswap2(void * data2)29 ms_gswap2 (void *data2)
30 {
31   uint8_t temp;
32 
33   union {
34     uint8_t c[2];
35   } dat;
36 
37   memcpy (&dat, data2, 2);
38   temp     = dat.c[0];
39   dat.c[0] = dat.c[1];
40   dat.c[1] = temp;
41   memcpy (data2, &dat, 2);
42 }
43 
44 void
ms_gswap3(void * data3)45 ms_gswap3 (void *data3)
46 {
47   uint8_t temp;
48 
49   union {
50     uint8_t c[3];
51   } dat;
52 
53   memcpy (&dat, data3, 3);
54   temp     = dat.c[0];
55   dat.c[0] = dat.c[2];
56   dat.c[2] = temp;
57   memcpy (data3, &dat, 3);
58 }
59 
60 void
ms_gswap4(void * data4)61 ms_gswap4 (void *data4)
62 {
63   uint8_t temp;
64 
65   union {
66     uint8_t c[4];
67   } dat;
68 
69   memcpy (&dat, data4, 4);
70   temp     = dat.c[0];
71   dat.c[0] = dat.c[3];
72   dat.c[3] = temp;
73   temp     = dat.c[1];
74   dat.c[1] = dat.c[2];
75   dat.c[2] = temp;
76   memcpy (data4, &dat, 4);
77 }
78 
79 void
ms_gswap8(void * data8)80 ms_gswap8 (void *data8)
81 {
82   uint8_t temp;
83 
84   union {
85     uint8_t c[8];
86   } dat;
87 
88   memcpy (&dat, data8, 8);
89   temp     = dat.c[0];
90   dat.c[0] = dat.c[7];
91   dat.c[7] = temp;
92 
93   temp     = dat.c[1];
94   dat.c[1] = dat.c[6];
95   dat.c[6] = temp;
96 
97   temp     = dat.c[2];
98   dat.c[2] = dat.c[5];
99   dat.c[5] = temp;
100 
101   temp     = dat.c[3];
102   dat.c[3] = dat.c[4];
103   dat.c[4] = temp;
104   memcpy (data8, &dat, 8);
105 }
106 
107 /* Swap routines that work on memory aligned quantities */
108 
109 void
ms_gswap2a(void * data2)110 ms_gswap2a (void *data2)
111 {
112   uint16_t *data = data2;
113 
114   *data = (((*data >> 8) & 0xff) | ((*data & 0xff) << 8));
115 }
116 
117 void
ms_gswap4a(void * data4)118 ms_gswap4a (void *data4)
119 {
120   uint32_t *data = data4;
121 
122   *data = (((*data >> 24) & 0xff) | ((*data & 0xff) << 24) |
123            ((*data >> 8) & 0xff00) | ((*data & 0xff00) << 8));
124 }
125 
126 void
ms_gswap8a(void * data8)127 ms_gswap8a (void *data8)
128 {
129   uint32_t *data4 = data8;
130   uint32_t h0, h1;
131 
132   h0 = data4[0];
133   h0 = (((h0 >> 24) & 0xff) | ((h0 & 0xff) << 24) |
134         ((h0 >> 8) & 0xff00) | ((h0 & 0xff00) << 8));
135 
136   h1 = data4[1];
137   h1 = (((h1 >> 24) & 0xff) | ((h1 & 0xff) << 24) |
138         ((h1 >> 8) & 0xff00) | ((h1 & 0xff00) << 8));
139 
140   data4[0] = h1;
141   data4[1] = h0;
142 }
143