QDP++
qdp_byteorder.cc
Go to the documentation of this file.
1//
2//
3// Determine the byte order of a platform
4//
5// returns
6// 1 = big-endian (alpha, intel linux, etc.)
7// 2 = little-endian (sun, ibm, hp, etc)
8//
9
10#include <iostream>
11#include <cstdlib>
12#include "qdp_byteorder.h"
13
14namespace QDPUtil
15{
18 {
19 union {
20 int l;
21 char c[sizeof(int)];
22 } u;
23 u.l = 1;
24 return (u.c[sizeof(int) - 1] == 1);
25 }
26
27
29 void byte_swap(void *ptr, size_t size, size_t nmemb)
30 {
31 unsigned int j;
32
33 char char_in[16]; /* characters used in byte swapping */
34
35 char *in_ptr;
36 double *double_ptr; /* Pointer used in the double routines */
37
38 switch (size)
39 {
40 case 4: /* n_uint32_t */
41 {
42 n_uint32_t *w = (n_uint32_t *)ptr;
43 n_uint32_t old, recent;
44
45 for(j=0; j<nmemb; j++)
46 {
47 old = w[j];
48 recent = old >> 24 & 0x000000ff;
49 recent |= old >> 8 & 0x0000ff00;
50 recent |= old << 8 & 0x00ff0000;
51 recent |= old << 24 & 0xff000000;
52 w[j] = recent;
53 }
54 }
55 break;
56
57 case 1: /* n_uint8_t: byte - do nothing */
58 break;
59
60 case 8: /* n_uint64_t */
61 {
62 for(j = 0, double_ptr = (double *) ptr;
63 j < nmemb;
64 j++, double_ptr++)
65 {
66 in_ptr = (char *) double_ptr; /* Set the character pointer to
67 point to the start of the double */
68
69 /*
70 * Assign all the byte variables to a character
71 */
72 char_in[0] = in_ptr[0];
73 char_in[1] = in_ptr[1];
74 char_in[2] = in_ptr[2];
75 char_in[3] = in_ptr[3];
76 char_in[4] = in_ptr[4];
77 char_in[5] = in_ptr[5];
78 char_in[6] = in_ptr[6];
79 char_in[7] = in_ptr[7];
80
81 /*
82 * Now just swap the order
83 */
84 in_ptr[0] = char_in[7];
85 in_ptr[1] = char_in[6];
86 in_ptr[2] = char_in[5];
87 in_ptr[3] = char_in[4];
88 in_ptr[4] = char_in[3];
89 in_ptr[5] = char_in[2];
90 in_ptr[6] = char_in[1];
91 in_ptr[7] = char_in[0];
92 }
93 }
94 break;
95
96 case 16: /* Long Long */
97 {
98 for(j = 0, double_ptr = (double *) ptr;
99 j < nmemb;
100 j++, double_ptr+=2)
101 {
102
103 in_ptr = (char *) double_ptr; /* Set the character pointer to
104 point to the start of the double */
105
106 /*
107 * Assign all the byte variables to a character
108 */
109 char_in[0] = in_ptr[0];
110 char_in[1] = in_ptr[1];
111 char_in[2] = in_ptr[2];
112 char_in[3] = in_ptr[3];
113 char_in[4] = in_ptr[4];
114 char_in[5] = in_ptr[5];
115 char_in[6] = in_ptr[6];
116 char_in[7] = in_ptr[7];
117 char_in[8] = in_ptr[8];
118 char_in[9] = in_ptr[9];
119 char_in[10] = in_ptr[10];
120 char_in[11] = in_ptr[11];
121 char_in[12] = in_ptr[12];
122 char_in[13] = in_ptr[13];
123 char_in[14] = in_ptr[14];
124 char_in[15] = in_ptr[15];
125
126 /*
127 * Now just swap the order
128 */
129 in_ptr[0] = char_in[15];
130 in_ptr[1] = char_in[14];
131 in_ptr[2] = char_in[13];
132 in_ptr[3] = char_in[12];
133 in_ptr[4] = char_in[11];
134 in_ptr[5] = char_in[10];
135 in_ptr[6] = char_in[9];
136 in_ptr[7] = char_in[8];
137
138 in_ptr[8] = char_in[7];
139 in_ptr[9] = char_in[6];
140 in_ptr[10] = char_in[5];
141 in_ptr[11] = char_in[4];
142 in_ptr[12] = char_in[3];
143 in_ptr[13] = char_in[2];
144 in_ptr[14] = char_in[1];
145 in_ptr[15] = char_in[0];
146
147 }
148 }
149 break;
150
151 case 2: /* n_uint16_t */
152 {
153 n_uint16_t *w = (n_uint16_t *)ptr;
154 n_uint16_t old, recent;
155
156 for(j=0; j<nmemb; j++)
157 {
158 old = w[j];
159 recent = old >> 8 & 0x00ff;
160 recent |= old << 8 & 0xff00;
161 w[j] = recent;
162 }
163 }
164 break;
165
166 default:
167 std::cerr << __func__ << ": unsupported word size = " << size << "\n";
168 exit(1);
169 }
170 }
171
172
174 size_t bfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
175 {
176 size_t n;
177
178 n = fread(ptr, size, nmemb, stream);
179
180 if (! big_endian())
181 {
182 /* little-endian */
183 /* Swap */
184 byte_swap(ptr, size, n);
185 }
186
187 return n;
188 }
189
190
192 size_t bfwrite(void *ptr, size_t size, size_t nmemb, FILE *stream)
193 {
194 size_t n;
195
196 if (big_endian())
197 {
198 /* big-endian */
199 /* Write */
200 n = fwrite(ptr, size, nmemb, stream);
201 }
202 else
203 {
204 /* little-endian */
205 /* Swap and write and swap */
206 byte_swap(ptr, size, nmemb);
207 n = fwrite(ptr, size, nmemb, stream);
208 byte_swap(ptr, size, nmemb);
209 }
210
211 return n;
212 }
213
214} // namespace QDPUtil
unsigned int n_uint32_t
void byte_swap(void *ptr, size_t size, size_t nmemb)
Byte-swap an array of data each of size nmemb.
size_t bfread(void *ptr, size_t size, size_t nmemb, FILE *stream)
fread on a binary file written in big-endian order
bool big_endian()
Is the native byte order big endian?
size_t bfwrite(void *ptr, size_t size, size_t nmemb, FILE *stream)
fwrite to a binary file in big-endian order
unsigned short int n_uint16_t
See qdp_crc32.cc for defs and discussion.
Byte manipulation.