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;
}
}
}
|