NCEPLIBS-bacio  2.6.0
byteswap.c
Go to the documentation of this file.
1 
17 // no byteswap.h on Apple
18 #ifdef APPLE
19 #include <libkern/OSByteOrder.h>
20 #define bswap_16(x) OSSwapInt16(x)
21 #define bswap_32(x) OSSwapInt32(x)
22 #define bswap_64(x) OSSwapInt64(x)
23 #else
24 #include <byteswap.h>
25 #endif
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 
30 static int send_errors = 1;
40 void
42 {
43  send_errors=flag;
44 }
45 
56 static int
57 simple_swap_32(void *data,size_t len)
58 {
59  size_t i;
60  uint32_t *udata;
61  if ((size_t)data & 0x3)
62  {
63  if (send_errors)
64  fprintf(stderr,"ERROR: pointer to 32-bit integer is not 32-bit aligned (pointer is 0x%llx)\n",(long long)data);
65  return 0;
66  }
67  udata=data;
68  for(i=0;i<len;i++)
69  udata[i]=
70  ( (udata[i]>>24)&0xff ) |
71  ( (udata[i]>>8)&0xff00 ) |
72  ( (udata[i]<<8)&0xff0000 ) |
73  ( (udata[i]<<24)&0xff000000 );
74  return 1;
75 }
76 
87 static int
88 simple_swap_16(void *data,size_t len)
89 {
90  size_t i;
91  uint16_t *udata;
92  if ((size_t)data & 0x1)
93  {
94  if (send_errors)
95  fprintf(stderr,"ERROR: pointer to 16-bit integer is not 16-bit aligned (pointer is 0x%llx)\n",(long long)data);
96  return 0;
97  }
98  udata=data;
99  for(i=0;i<len;i++)
100  udata[i]=
101  ( (udata[i]>>8)&0xff ) |
102  ( (udata[i]<<8)&0xff00 );
103  return 1;
104 }
105 
117 static int
118 macro_swap_64(void *data,size_t len)
119 {
120  size_t i;
121  uint64_t *udata;
122  if ((size_t)data & 0x5)
123  {
124  if (send_errors)
125  fprintf(stderr,"ERROR: pointer to 64-bit integer is not 64-bit aligned (pointer is 0x%llx)\n",(long long)data);
126  return 0;
127  }
128  udata=data;
129  for(i=0;i<len;i++)
130  udata[i]=bswap_64(udata[i]);
131  return 1;
132 }
133 
145 int
146 fast_byteswap(void *data,int bytes,size_t count)
147 {
148  switch(bytes) {
149  case 1: return 1;
150  case 2: return simple_swap_16(data,count);
151  case 4: return simple_swap_32(data,count);
152  case 8: return macro_swap_64(data,count);
153  default: return 0;
154  }
155 }
156 
157 /* Include the C library file for definition/control */
158 #include "clib.h"
159 #include "stdio.h"
160 #include "fast-byteswap.h"
161 
172 void
173 byteswap_(char *data, int *nbyte, int *nnum)
174 {
175  int i, j;
176  char swap[256];
177  int nb = *nbyte;
178  int nn = *nnum;
179  size_t count = *nnum;
180 
181  if (!fast_byteswap(data, nb, count))
182  {
183  fprintf(stderr,"ERROR NOT ALIGNED SLOW CODE USED (nb and count %9d %9lu )\n",nb, count);
184  /* It failed. No data was byteswapped because it is not aligned */
185  for (j = 0; j < nn; j++)
186  {
187  for (i = 0; i < nb; i++)
188  swap[i] = data[j * nb + i];
189  for (i = 0; i < nb; i++)
190  data[j * nb + i] = swap[nb - i - 1];
191  }
192  }
193 }
clib.h
byteswap_
void byteswap_(char *data, int *nbyte, int *nnum)
Byteswap.
Definition: byteswap.c:173
fast_byteswap_errors
void fast_byteswap_errors(int flag)
Set a flag to turn warnings off for non-aligned pointers.
Definition: byteswap.c:41
send_errors
static int send_errors
If non-zero, warn about non-aligned pointers.
Definition: byteswap.c:30
fast-byteswap.h
Header file for byteswap functions.
simple_swap_16
static int simple_swap_16(void *data, size_t len)
Simple single-value loops.
Definition: byteswap.c:88
fast_byteswap
int fast_byteswap(void *data, int bytes, size_t count)
Fast byteswap.
Definition: byteswap.c:146
simple_swap_32
static int simple_swap_32(void *data, size_t len)
Simple single-value loops.
Definition: byteswap.c:57
macro_swap_64
static int macro_swap_64(void *data, size_t len)
Use the GNU macros, which are specialized byteswap ASM instructions.
Definition: byteswap.c:118