| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 | /******************************************************************************* copyright: Copyright (c) 2004 Kris Bell. All rights reserved license: BSD style: $(LICENSE) version: Initial release: October 2004 version: Feb 20th 2005 - Asm version removed by Aleksey Bobnev authors: Kris, Aleksey Bobnev *******************************************************************************/ module tango.core.ByteSwap; import tango.core.BitManip; /******************************************************************************* Reverse byte order for specific datum sizes. Note that the byte-swap approach avoids alignment issues, so is probably faster overall than a traditional 'shift' implementation. --- ubyte[] x = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]; auto a = x.dup; ByteSwap.swap16(a); assert(a == [cast(ubyte) 0x02, 0x01, 0x04, 0x03, 0x06, 0x05, 0x08, 0x07]); auto b = x.dup; ByteSwap.swap32(b); assert(b == [cast(ubyte) 0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05]); auto c = x.dup; ByteSwap.swap64(c); assert(c == [cast(ubyte) 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01]); --- *******************************************************************************/ struct ByteSwap { /*********************************************************************** Reverses two-byte sequences. Parameter dst imples the number of bytes, which should be a multiple of 2 ***********************************************************************/ final static void swap16 (void[] dst) { swap16 (dst.ptr, dst.length); } /*********************************************************************** Reverses four-byte sequences. Parameter dst implies the number of bytes, which should be a multiple of 4 ***********************************************************************/ final static void swap32 (void[] dst) { swap32 (dst.ptr, dst.length); } /*********************************************************************** Reverse eight-byte sequences. Parameter dst implies the number of bytes, which should be a multiple of 8 ***********************************************************************/ final static void swap64 (void[] dst) { swap64 (dst.ptr, dst.length); } /*********************************************************************** Reverse ten-byte sequences. Parameter dst implies the number of bytes, which should be a multiple of 10 ***********************************************************************/ final static void swap80 (void[] dst) { swap80 (dst.ptr, dst.length); } /*********************************************************************** Reverses two-byte sequences. Parameter bytes specifies the number of bytes, which should be a multiple of 2 ***********************************************************************/ final static void swap16 (void *dst, size_t bytes) { assert ((bytes & 0x01) is 0); auto p = cast(ubyte*) dst; while (bytes) { ubyte b = p[0]; p[0] = p[1]; p[1] = b; p += short.sizeof; bytes -= short.sizeof; } } /*********************************************************************** Reverses four-byte sequences. Parameter bytes specifies the number of bytes, which should be a multiple of 4 ***********************************************************************/ final static void swap32 (void *dst, size_t bytes) { assert ((bytes & 0x03) is 0); auto p = cast(uint*) dst; while (bytes) { *p = bswap(*p); ++p; bytes -= int.sizeof; } } /*********************************************************************** Reverse eight-byte sequences. Parameter bytes specifies the number of bytes, which should be a multiple of 8 ***********************************************************************/ final static void swap64 (void *dst, size_t bytes) { assert ((bytes & 0x07) is 0); auto p = cast(uint*) dst; while (bytes) { uint i = p[0]; p[0] = bswap(p[1]); p[1] = bswap(i); p += (long.sizeof / int.sizeof); bytes -= long.sizeof; } } /*********************************************************************** Reverse ten-byte sequences. Parameter bytes specifies the number of bytes, which should be a multiple of 10 ***********************************************************************/ final static void swap80 (void *dst, size_t bytes) { assert ((bytes % 10) is 0); auto p = cast(ubyte*) dst; while (bytes) { ubyte b = p[0]; p[0] = p[9]; p[9] = b; b = p[1]; p[1] = p[8]; p[8] = b; b = p[2]; p[2] = p[7]; p[7] = b; b = p[3]; p[3] = p[6]; p[6] = b; b = p[4]; p[4] = p[5]; p[5] = b; p += 10; bytes -= 10; } } } |