I've written the code below. This code contains two functions swapmem() and swap64().
At the end of this reply I indicate you an idea to solve your problem with the buffer of byte.
Here the code:
#include <stdio.h> #include <stdint.h> #include <inttypes.h> #include <malloc.h> void * swapmem(void *x, size_t len, int retnew); uint64_t swap64(uint64_t k); /** brief swapmem This function swaps the byte into a memory buffer. param x pointer to the buffer to be swapped param len lenght to the buffer to be swapped param retnew If this parameter is 1 the buffer is swapped in a new buffer. The new buffer shall be deallocated by using free() when it's no longer useful. If this parameter is 0 the buffer is swapped in its memory area. return The pointer to the memory area where the bytes has been swapped or NULL if an error occurs. */ void * swapmem(void *x, size_t len, int retnew) { char *b = NULL, app; size_t i; if (x != NULL) { if (retnew) { b = malloc(len); if (b!=NULL) { for(i=0;i<len;i++) { b[i]=*((char *)x+len-1-i); } } } else { b=(char *)x; for(i=0;i<len/2;i++) { app=b[i]; b[i]=b[len-1-i]; b[len-1-i]=app; } } } return b; } uint64_t swap64(uint64_t k) { return ((k << 56) | ((k & 0x000000000000FF00) << 40) | ((k & 0x0000000000FF0000) << 24) | ((k & 0x00000000FF000000) << 8) | ((k & 0x000000FF00000000) >> 8) | ((k & 0x0000FF0000000000) >> 24)| ((k & 0x00FF000000000000) >> 40)| (k >> 56) ); } int main(void) { uint32_t x,*y; uint16_t s,z; uint64_t k,t; x=0xFF567890; /* Dynamic allocation is used to avoid to change the contents of x */ y=(uint32_t *)swapmem(&x,sizeof(x),1); if (y!=NULL) { printf("LE=%08X BE=%08X\n",x,*y); free(y); } /* Dynamic allocation is not used. The contents of z and k will change */ z=s=0x7891; swapmem(&z,sizeof(z),0); printf("LE=%04X BE=%04X\n",s,z); k=t=0x1120324351657389; swapmem(&k,sizeof(k),0); printf("LE=%16"PRIX64" BE=%16"PRIX64"\n",t,k); /* LE64 to BE64 (or viceversa) using shift */ k=swap64(t); printf("LE=%16"PRIX64" BE=%16"PRIX64"\n",t,k); return 0; }
After the program was compiled I had the curiosity to see the assembly code gcc generated. I discovered that the function swap64 is generated as indicated below.
00000000004007a0 <swap64>: 4007a0: 48 89 f8 mov %rdi,%rax 4007a3: 48 0f c8 bswap %rax 4007a6: c3 retq
This result is obtained compiling the code, on a PC with Intel I3 CPU, with the gcc options: -Ofast, or -O3, or -O2, or -Os.
You may solve your problem using something like the swap64() function. A function like the following I've named swap32():
uint32_t swap32(uint32_t k) { return ((k << 24) | ((k & 0x0000FF00) << 8) | ((k & 0x00FF0000) >> 8) | (k >> 24) ); }
You may use it as:
uint32_t j=swap32(*(uint32_t *)ptr);
charvalues are promoted tointbefore arithmetic is done. Note: should be usingunsigned char *anduint32_t.66051on little and big endian machines.valueis stored in the endianess of the machine, not always in little endian.& 0xFFis only necessary for signed values, to strip off the extra bits when a negativecharvalue is sign-extended toint. One reason to useunsigned, as well as dubious shifting into the sign bit.