Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

endianswap.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 /***************************************************************************
00009  * RCS INFORMATION:
00010  *
00011  *      $RCSfile: endianswap.h,v $
00012  *      $Author: johns $       $Locker:  $             $State: Exp $
00013  *      $Revision: 1.8 $       $Date: 2020/10/21 18:03:15 $
00014  *
00015  ***************************************************************************
00016  * DESCRIPTION:
00017  *   Byte swapping routines used in various plugins
00018  *   There are two versions of each routine, one that's safe to use in
00019  *   all cases (but is slow) and one that is only safe to use on memory 
00020  *   addresses that are aligned to the word size that's being byte-swapped
00021  *   but are much much much faster.  Use the aligned versions of these
00022  *   routines whenever possible.  The 'ndata' length count parameters and
00023  *   internal loops should be safe to use on huge memory arrays on 64-bit
00024  *   machines.
00025  *
00026  ***************************************************************************/
00027 
00028 #ifndef ENDIAN_SWAP_H
00029 #define ENDIAN_SWAP_H
00030 
00031 #include <stddef.h>
00032 
00033 /* works on unaligned 2-byte quantities */
00034 static void swap2_unaligned(void *v, ptrdiff_t ndata) {
00035   ptrdiff_t i;
00036   char * dataptr = (char *) v;
00037   char tmp;
00038 
00039   for (i = 0; i < ndata-1; i += 2) {
00040     tmp = dataptr[i];
00041     dataptr[i] = dataptr[i+1];
00042     dataptr[i+1] = tmp;
00043   }
00044 }
00045 
00046 
00047 /* works on unaligned 4-byte quantities */
00048 static void swap4_unaligned(void *v, ptrdiff_t ndata) {
00049   ptrdiff_t i;
00050   char *dataptr;
00051   char tmp;
00052 
00053   dataptr = (char *) v; 
00054   for (i=0; i<ndata; i++) {
00055     tmp = dataptr[0];
00056     dataptr[0] = dataptr[3];
00057     dataptr[3] = tmp;
00058     tmp = dataptr[1];
00059     dataptr[1] = dataptr[2];
00060     dataptr[2] = tmp;
00061     dataptr += 4;
00062   }
00063 }
00064 
00065 
00066 /* works on unaligned 8-byte quantities */
00067 static void swap8_unaligned(void *v, ptrdiff_t ndata) {
00068   char *data = (char *) v;
00069   ptrdiff_t i;
00070   char byteArray[8];
00071   char *bytePointer;
00072 
00073   for (i=0; i<ndata; i++) {
00074     bytePointer = data + (i<<3);
00075     byteArray[0]  =  *bytePointer;
00076     byteArray[1]  =  *(bytePointer+1);
00077     byteArray[2]  =  *(bytePointer+2);
00078     byteArray[3]  =  *(bytePointer+3);
00079     byteArray[4]  =  *(bytePointer+4);
00080     byteArray[5]  =  *(bytePointer+5);
00081     byteArray[6]  =  *(bytePointer+6);
00082     byteArray[7]  =  *(bytePointer+7);
00083 
00084     *bytePointer     = byteArray[7];
00085     *(bytePointer+1) = byteArray[6];
00086     *(bytePointer+2) = byteArray[5];
00087     *(bytePointer+3) = byteArray[4];
00088     *(bytePointer+4) = byteArray[3];
00089     *(bytePointer+5) = byteArray[2];
00090     *(bytePointer+6) = byteArray[1];
00091     *(bytePointer+7) = byteArray[0];
00092   }
00093 }
00094 
00095 
00096 /* Only works with aligned 2-byte quantities, will cause a bus error */
00097 /* on some platforms if used on unaligned data.                      */
00098 static void swap2_aligned(void *v, ptrdiff_t ndata) {
00099   short *data = (short *) v;
00100   ptrdiff_t i;
00101   short *N; 
00102 
00103   for (i=0; i<ndata; i++) {
00104     N = data + i;
00105     *N=(((*N>>8)&0xff) | ((*N&0xff)<<8));  
00106   }
00107 }
00108 
00109 
00110 /* Only works with aligned 4-byte quantities, will cause a bus error */
00111 /* on some platforms if used on unaligned data.                      */
00112 static void swap4_aligned(void *v, ptrdiff_t ndata) {
00113   int *data = (int *) v;
00114   ptrdiff_t i;
00115   int *N;
00116   for (i=0; i<ndata; i++) {
00117     N = data + i;
00118     *N=(((*N>>24)&0xff) | ((*N&0xff)<<24) | 
00119         ((*N>>8)&0xff00) | ((*N&0xff00)<<8));
00120   }
00121 }
00122 
00123 
00124 /* Only works with aligned 8-byte quantities, will cause a bus error */
00125 /* on some platforms if used on unaligned data.                      */
00126 static void swap8_aligned(void *v, ptrdiff_t ndata) {
00127   /* Use int* internally to prevent bugs caused by some compilers */
00128   /* and hardware that would potentially load data into an FP reg */
00129   /* and hose everything, such as the old "jmemcpy()" bug in NAMD */
00130   int *data = (int *) v;  
00131   ptrdiff_t i;
00132   int *N; 
00133   int t0, t1;
00134 
00135   for (i=0; i<ndata; i++) {
00136     N = data + (i<<1);
00137     t0 = N[0];
00138     t0=(((t0>>24)&0xff) | ((t0&0xff)<<24) | 
00139         ((t0>>8)&0xff00) | ((t0&0xff00)<<8));
00140 
00141     t1 = N[1];
00142     t1=(((t1>>24)&0xff) | ((t1&0xff)<<24) | 
00143         ((t1>>8)&0xff00) | ((t1&0xff00)<<8));
00144 
00145     N[0] = t1; 
00146     N[1] = t0; 
00147   }
00148 }
00149 
00150 #if 0
00151 /* Other implementations that might be faster in some cases */
00152 
00153 /* swaps the endianism of an eight byte word. */
00154 void mdio_swap8(double *i) {
00155         char c;
00156         char *n;
00157         n = (char *) i;
00158         c = n[0];
00159         n[0] = n[7];
00160         n[7] = c;
00161         c = n[1];
00162         n[1] = n[6];
00163         n[6] = c;
00164         c = n[2];
00165         n[2] = n[5];
00166         n[5] = c;
00167         c = n[3];
00168         n[3] = n[4];
00169         n[4] = c;
00170 }
00171 
00172 #endif
00173 
00174 #endif
00175 

Generated on Thu Mar 28 03:08:06 2024 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002