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