On Wed, May 16, 2012 at 11:03 AM, Regan Heath <re...@netmail.co.nz> wrote:
> On Wed, 16 May 2012 15:24:33 +0100, ref2401 <refacto...@gmail.com> wrote: > > i have an array of ubytes. how can i convert two adjacent ubytes from the >> array to an integer? >> >> pseudocode example: >> ubyte[5] array = createArray(); >> int value = array[2..3]; >> >> is there any 'memcpy' method or something else to do this? >> > > You don't need to "copy" the data, just tell the compiler to "pretend" > it's a short (in this case, for 2 bytes) then copy the value/assign to an > int. e.g. > > import std.stdio; > > void main() > { > ubyte[5] array = [ 0xFF, 0xFF, 0x01, 0x00, 0xFF ]; > int value = *cast(short*)array[2..3].ptr; > writefln("Result = %s", value); > } > > The line: > int value = *cast(short*)array[2..3].ptr; > > 1. slices 2 bytes from the array. > 2. obtains the ptr to them > 3. casts the ptr to short* > 4. copies the value pointed at by the short* ptr to an int > > You may need to worry about little/big endian issues, see: > http://en.wikipedia.org/wiki/**Endianness<http://en.wikipedia.org/wiki/Endianness> > > The above code outputs "Result = 1" on my little-endian x86 desktop > machine but would output "Result = 256" on a big-endian machine. > > R > > Unfortunately, this is undefined behavior because you're breaking alignment rules. On x86, this will just cause a slow load from memory. On ARM, this will either crash your program with a bus error on newer hardware or give you a gibberish value on ARMv6 and older. Declaring a short, getting a pointer to it, and casting that pointer to a ubyte* to copy into it is fine, but casting a ubyte* to a short* will cause a 2-byte load from a 1-byte aligned address, which leads down the yellow brick road to pain.