Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : University of Illinois Open Source License 3 : Copyright 2003 Theoretical and Computational Biophysics Group, 4 : All rights reserved. 5 : 6 : Developed by: Theoretical and Computational Biophysics Group 7 : University of Illinois at Urbana-Champaign 8 : http://www.ks.uiuc.edu/ 9 : 10 : Permission is hereby granted, free of charge, to any person obtaining a copy of 11 : this software and associated documentation files (the Software), to deal with 12 : the Software without restriction, including without limitation the rights to 13 : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 14 : of the Software, and to permit persons to whom the Software is furnished to 15 : do so, subject to the following conditions: 16 : 17 : Redistributions of source code must retain the above copyright notice, 18 : this list of conditions and the following disclaimers. 19 : 20 : Redistributions in binary form must reproduce the above copyright notice, 21 : this list of conditions and the following disclaimers in the documentation 22 : and/or other materials provided with the distribution. 23 : 24 : Neither the names of Theoretical and Computational Biophysics Group, 25 : University of Illinois at Urbana-Champaign, nor the names of its contributors 26 : may be used to endorse or promote products derived from this Software without 27 : specific prior written permission. 28 : 29 : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 32 : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 33 : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 34 : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 35 : OTHER DEALINGS WITH THE SOFTWARE. 36 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 37 : #ifndef __PLUMED_molfile_endianswap_h 38 : #define __PLUMED_molfile_endianswap_h 39 : namespace PLMD{ 40 : namespace molfile{ 41 : /*************************************************************************** 42 : *cr 43 : *cr (C) Copyright 1995-2016 The Board of Trustees of the 44 : *cr University of Illinois 45 : *cr All Rights Reserved 46 : *cr 47 : ***************************************************************************/ 48 : /*************************************************************************** 49 : * RCS INFORMATION: 50 : * 51 : * $RCSfile: endianswap.h,v $ 52 : * $Author: johns $ $Locker: $ $State: Exp $ 53 : * $Revision: 1.8 $ $Date: 2020/10/21 18:03:15 $ 54 : * 55 : *************************************************************************** 56 : * DESCRIPTION: 57 : * Byte swapping routines used in various plugins 58 : * There are two versions of each routine, one that's safe to use in 59 : * all cases (but is slow) and one that is only safe to use on memory 60 : * addresses that are aligned to the word size that's being byte-swapped 61 : * but are much much much faster. Use the aligned versions of these 62 : * routines whenever possible. The 'ndata' length count parameters and 63 : * internal loops should be safe to use on huge memory arrays on 64-bit 64 : * machines. 65 : * 66 : ***************************************************************************/ 67 : 68 : #ifndef ENDIAN_SWAP_H 69 : #define ENDIAN_SWAP_H 70 : 71 : #include <stddef.h> 72 : 73 : /* works on unaligned 2-byte quantities */ 74 : static void swap2_unaligned(void *v, ptrdiff_t ndata) { 75 : ptrdiff_t i; 76 : char * dataptr = (char *) v; 77 : char tmp; 78 : 79 : for (i = 0; i < ndata-1; i += 2) { 80 : tmp = dataptr[i]; 81 : dataptr[i] = dataptr[i+1]; 82 : dataptr[i+1] = tmp; 83 : } 84 : } 85 : 86 : 87 : /* works on unaligned 4-byte quantities */ 88 0 : static void swap4_unaligned(void *v, ptrdiff_t ndata) { 89 : ptrdiff_t i; 90 : char *dataptr; 91 : char tmp; 92 : 93 : dataptr = (char *) v; 94 0 : for (i=0; i<ndata; i++) { 95 0 : tmp = dataptr[0]; 96 0 : dataptr[0] = dataptr[3]; 97 0 : dataptr[3] = tmp; 98 0 : tmp = dataptr[1]; 99 0 : dataptr[1] = dataptr[2]; 100 0 : dataptr[2] = tmp; 101 0 : dataptr += 4; 102 : } 103 0 : } 104 : 105 : 106 : /* works on unaligned 8-byte quantities */ 107 0 : static void swap8_unaligned(void *v, ptrdiff_t ndata) { 108 : char *data = (char *) v; 109 : ptrdiff_t i; 110 : char byteArray[8]; 111 : char *bytePointer; 112 : 113 0 : for (i=0; i<ndata; i++) { 114 0 : bytePointer = data + (i<<3); 115 0 : byteArray[0] = *bytePointer; 116 0 : byteArray[1] = *(bytePointer+1); 117 0 : byteArray[2] = *(bytePointer+2); 118 0 : byteArray[3] = *(bytePointer+3); 119 0 : byteArray[4] = *(bytePointer+4); 120 0 : byteArray[5] = *(bytePointer+5); 121 0 : byteArray[6] = *(bytePointer+6); 122 0 : byteArray[7] = *(bytePointer+7); 123 : 124 0 : *bytePointer = byteArray[7]; 125 0 : *(bytePointer+1) = byteArray[6]; 126 0 : *(bytePointer+2) = byteArray[5]; 127 0 : *(bytePointer+3) = byteArray[4]; 128 0 : *(bytePointer+4) = byteArray[3]; 129 0 : *(bytePointer+5) = byteArray[2]; 130 0 : *(bytePointer+6) = byteArray[1]; 131 0 : *(bytePointer+7) = byteArray[0]; 132 : } 133 0 : } 134 : 135 : 136 : /* Only works with aligned 2-byte quantities, will cause a bus error */ 137 : /* on some platforms if used on unaligned data. */ 138 : static void swap2_aligned(void *v, ptrdiff_t ndata) { 139 : short *data = (short *) v; 140 : ptrdiff_t i; 141 : short *N; 142 : 143 : for (i=0; i<ndata; i++) { 144 : N = data + i; 145 : *N=(((*N>>8)&0xff) | ((*N&0xff)<<8)); 146 : } 147 : } 148 : 149 : 150 : /* Only works with aligned 4-byte quantities, will cause a bus error */ 151 : /* on some platforms if used on unaligned data. */ 152 1461240 : static void swap4_aligned(void *v, ptrdiff_t ndata) { 153 : int *data = (int *) v; 154 : ptrdiff_t i; 155 : int *N; 156 2922480 : for (i=0; i<ndata; i++) { 157 1461240 : N = data + i; 158 1461240 : *N=(((*N>>24)&0xff) | ((*N&0xff)<<24) | 159 1461240 : ((*N>>8)&0xff00) | ((*N&0xff00)<<8)); 160 : } 161 1461240 : } 162 : 163 : 164 : /* Only works with aligned 8-byte quantities, will cause a bus error */ 165 : /* on some platforms if used on unaligned data. */ 166 0 : static void swap8_aligned(void *v, ptrdiff_t ndata) { 167 : /* Use int* internally to prevent bugs caused by some compilers */ 168 : /* and hardware that would potentially load data into an FP reg */ 169 : /* and hose everything, such as the old "jmemcpy()" bug in NAMD */ 170 : int *data = (int *) v; 171 : ptrdiff_t i; 172 : int *N; 173 : int t0, t1; 174 : 175 0 : for (i=0; i<ndata; i++) { 176 0 : N = data + (i<<1); 177 0 : t0 = N[0]; 178 0 : t0=(((t0>>24)&0xff) | ((t0&0xff)<<24) | 179 0 : ((t0>>8)&0xff00) | ((t0&0xff00)<<8)); 180 : 181 0 : t1 = N[1]; 182 0 : t1=(((t1>>24)&0xff) | ((t1&0xff)<<24) | 183 0 : ((t1>>8)&0xff00) | ((t1&0xff00)<<8)); 184 : 185 0 : N[0] = t1; 186 0 : N[1] = t0; 187 : } 188 0 : } 189 : 190 : #if 0 191 : /* Other implementations that might be faster in some cases */ 192 : 193 : /* swaps the endianism of an eight byte word. */ 194 : void mdio_swap8(double *i) { 195 : char c; 196 : char *n; 197 : n = (char *) i; 198 : c = n[0]; 199 : n[0] = n[7]; 200 : n[7] = c; 201 : c = n[1]; 202 : n[1] = n[6]; 203 : n[6] = c; 204 : c = n[2]; 205 : n[2] = n[5]; 206 : n[5] = c; 207 : c = n[3]; 208 : n[3] = n[4]; 209 : n[4] = c; 210 : } 211 : 212 : #endif 213 : 214 : #endif 215 : } 216 : } 217 : #endif