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.7 $       $Date: 2016/11/28 05:01:53 $
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 /* works on unaligned 2-byte quantities */
00032 static void swap2_unaligned(void *v, long ndata) {
00033   long i;
00034   char * dataptr = (char *) v;
00035   char tmp;
00036 
00037   for (i = 0; i < ndata-1; i += 2) {
00038     tmp = dataptr[i];
00039     dataptr[i] = dataptr[i+1];
00040     dataptr[i+1] = tmp;
00041   }
00042 }
00043 
00044 
00045 /* works on unaligned 4-byte quantities */
00046 static void swap4_unaligned(void *v, long ndata) {
00047   long i;
00048   char *dataptr;
00049   char tmp;
00050 
00051   dataptr = (char *) v; 
00052   for (i=0; i<ndata; i++) {
00053     tmp = dataptr[0];
00054     dataptr[0] = dataptr[3];
00055     dataptr[3] = tmp;
00056     tmp = dataptr[1];
00057     dataptr[1] = dataptr[2];
00058     dataptr[2] = tmp;
00059     dataptr += 4;
00060   }
00061 }
00062 
00063 
00064 /* works on unaligned 8-byte quantities */
00065 static void swap8_unaligned(void *v, long ndata) {
00066   char *data = (char *) v;
00067   long i;
00068   char byteArray[8];
00069   char *bytePointer;
00070 
00071   for (i=0; i<ndata; i++) {
00072     bytePointer = data + (i<<3);
00073     byteArray[0]  =  *bytePointer;
00074     byteArray[1]  =  *(bytePointer+1);
00075     byteArray[2]  =  *(bytePointer+2);
00076     byteArray[3]  =  *(bytePointer+3);
00077     byteArray[4]  =  *(bytePointer+4);
00078     byteArray[5]  =  *(bytePointer+5);
00079     byteArray[6]  =  *(bytePointer+6);
00080     byteArray[7]  =  *(bytePointer+7);
00081 
00082     *bytePointer     = byteArray[7];
00083     *(bytePointer+1) = byteArray[6];
00084     *(bytePointer+2) = byteArray[5];
00085     *(bytePointer+3) = byteArray[4];
00086     *(bytePointer+4) = byteArray[3];
00087     *(bytePointer+5) = byteArray[2];
00088     *(bytePointer+6) = byteArray[1];
00089     *(bytePointer+7) = byteArray[0];
00090   }
00091 }
00092 
00093 
00094 /* Only works with aligned 2-byte quantities, will cause a bus error */
00095 /* on some platforms if used on unaligned data.                      */
00096 static void swap2_aligned(void *v, long ndata) {
00097   short *data = (short *) v;
00098   long i;
00099   short *N; 
00100 
00101   for (i=0; i<ndata; i++) {
00102     N = data + i;
00103     *N=(((*N>>8)&0xff) | ((*N&0xff)<<8));  
00104   }
00105 }
00106 
00107 
00108 /* Only works with aligned 4-byte quantities, will cause a bus error */
00109 /* on some platforms if used on unaligned data.                      */
00110 static void swap4_aligned(void *v, long ndata) {
00111   int *data = (int *) v;
00112   long i;
00113   int *N;
00114   for (i=0; i<ndata; i++) {
00115     N = data + i;
00116     *N=(((*N>>24)&0xff) | ((*N&0xff)<<24) | 
00117         ((*N>>8)&0xff00) | ((*N&0xff00)<<8));
00118   }
00119 }
00120 
00121 
00122 /* Only works with aligned 8-byte quantities, will cause a bus error */
00123 /* on some platforms if used on unaligned data.                      */
00124 static void swap8_aligned(void *v, long ndata) {
00125   /* Use int* internally to prevent bugs caused by some compilers */
00126   /* and hardware that would potentially load data into an FP reg */
00127   /* and hose everything, such as the old "jmemcpy()" bug in NAMD */
00128   int *data = (int *) v;  
00129   long i;
00130   int *N; 
00131   int t0, t1;
00132 
00133   for (i=0; i<ndata; i++) {
00134     N = data + (i<<1);
00135     t0 = N[0];
00136     t0=(((t0>>24)&0xff) | ((t0&0xff)<<24) | 
00137         ((t0>>8)&0xff00) | ((t0&0xff00)<<8));
00138 
00139     t1 = N[1];
00140     t1=(((t1>>24)&0xff) | ((t1&0xff)<<24) | 
00141         ((t1>>8)&0xff00) | ((t1&0xff00)<<8));
00142 
00143     N[0] = t1; 
00144     N[1] = t0; 
00145   }
00146 }
00147 
00148 #if 0
00149 /* Other implementations that might be faster in some cases */
00150 
00151 /* swaps the endianism of an eight byte word. */
00152 void mdio_swap8(double *i) {
00153         char c;
00154         char *n;
00155         n = (char *) i;
00156         c = n[0];
00157         n[0] = n[7];
00158         n[7] = c;
00159         c = n[1];
00160         n[1] = n[6];
00161         n[6] = c;
00162         c = n[2];
00163         n[2] = n[5];
00164         n[5] = c;
00165         c = n[3];
00166         n[3] = n[4];
00167         n[4] = c;
00168 }
00169 
00170 #endif
00171 
00172 #endif
00173 

Generated on Tue Aug 11 03:06:30 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002