1 /******************************************************************************* 2 3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: October 2004 8 9 version: Feb 20th 2005 - Asm version removed by Aleksey Bobnev 10 11 authors: Kris, Aleksey Bobnev 12 13 *******************************************************************************/ 14 15 module tango.core.ByteSwap; 16 17 import tango.core.BitManip; 18 19 /******************************************************************************* 20 21 Reverse byte order for specific datum sizes. Note that the 22 byte-swap approach avoids alignment issues, so is probably 23 faster overall than a traditional 'shift' implementation. 24 --- 25 ubyte[] x = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]; 26 27 auto a = x.dup; 28 ByteSwap.swap16(a); 29 assert(a == [cast(ubyte) 0x02, 0x01, 0x04, 0x03, 0x06, 0x05, 0x08, 0x07]); 30 31 auto b = x.dup; 32 ByteSwap.swap32(b); 33 assert(b == [cast(ubyte) 0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05]); 34 35 auto c = x.dup; 36 ByteSwap.swap64(c); 37 assert(c == [cast(ubyte) 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]); 38 --- 39 40 *******************************************************************************/ 41 42 struct ByteSwap 43 { 44 /*********************************************************************** 45 46 Reverses two-byte sequences. Parameter dst imples the 47 number of bytes, which should be a multiple of 2 48 49 ***********************************************************************/ 50 51 final static void swap16 (void[] dst) 52 { 53 swap16 (dst.ptr, dst.length); 54 } 55 56 /*********************************************************************** 57 58 Reverses four-byte sequences. Parameter dst implies the 59 number of bytes, which should be a multiple of 4 60 61 ***********************************************************************/ 62 63 final static void swap32 (void[] dst) 64 { 65 swap32 (dst.ptr, dst.length); 66 } 67 68 /*********************************************************************** 69 70 Reverse eight-byte sequences. Parameter dst implies the 71 number of bytes, which should be a multiple of 8 72 73 ***********************************************************************/ 74 75 final static void swap64 (void[] dst) 76 { 77 swap64 (dst.ptr, dst.length); 78 } 79 80 /*********************************************************************** 81 82 Reverse ten-byte sequences. Parameter dst implies the 83 number of bytes, which should be a multiple of 10 84 85 ***********************************************************************/ 86 87 final static void swap80 (void[] dst) 88 { 89 swap80 (dst.ptr, dst.length); 90 } 91 92 /*********************************************************************** 93 94 Reverses two-byte sequences. Parameter bytes specifies the 95 number of bytes, which should be a multiple of 2 96 97 ***********************************************************************/ 98 99 final static void swap16 (void *dst, size_t bytes) 100 { 101 assert ((bytes & 0x01) is 0); 102 103 auto p = cast(ubyte*) dst; 104 while (bytes) 105 { 106 ubyte b = p[0]; 107 p[0] = p[1]; 108 p[1] = b; 109 110 p += short.sizeof; 111 bytes -= short.sizeof; 112 } 113 } 114 115 /*********************************************************************** 116 117 Reverses four-byte sequences. Parameter bytes specifies the 118 number of bytes, which should be a multiple of 4 119 120 ***********************************************************************/ 121 122 final static void swap32 (void *dst, size_t bytes) 123 { 124 assert ((bytes & 0x03) is 0); 125 126 auto p = cast(uint*) dst; 127 while (bytes) 128 { 129 *p = bswap(*p); 130 ++p; 131 bytes -= int.sizeof; 132 } 133 } 134 135 /*********************************************************************** 136 137 Reverse eight-byte sequences. Parameter bytes specifies the 138 number of bytes, which should be a multiple of 8 139 140 ***********************************************************************/ 141 142 final static void swap64 (void *dst, size_t bytes) 143 { 144 assert ((bytes & 0x07) is 0); 145 146 auto p = cast(uint*) dst; 147 while (bytes) 148 { 149 uint i = p[0]; 150 p[0] = bswap(p[1]); 151 p[1] = bswap(i); 152 153 p += (long.sizeof / int.sizeof); 154 bytes -= long.sizeof; 155 } 156 } 157 158 /*********************************************************************** 159 160 Reverse ten-byte sequences. Parameter bytes specifies the 161 number of bytes, which should be a multiple of 10 162 163 ***********************************************************************/ 164 165 final static void swap80 (void *dst, size_t bytes) 166 { 167 assert ((bytes % 10) is 0); 168 169 auto p = cast(ubyte*) dst; 170 while (bytes) 171 { 172 ubyte b = p[0]; 173 p[0] = p[9]; 174 p[9] = b; 175 176 b = p[1]; 177 p[1] = p[8]; 178 p[8] = b; 179 180 b = p[2]; 181 p[2] = p[7]; 182 p[7] = b; 183 184 b = p[3]; 185 p[3] = p[6]; 186 p[6] = b; 187 188 b = p[4]; 189 p[4] = p[5]; 190 p[5] = b; 191 192 p += 10; 193 bytes -= 10; 194 } 195 } 196 } 197 198 199 200