Skip to content

Instantly share code, notes, and snippets.

@dataPulverizer
Last active May 8, 2020 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dataPulverizer/744fadf8924ae96135fc600ac86c7060 to your computer and use it in GitHub Desktop.
Save dataPulverizer/744fadf8924ae96135fc600ac86c7060 to your computer and use it in GitHub Desktop.
Endian functions for Nim
#[
Byte order functions for Nim intendend for 2, 4, 6, 8, 16 - byte basic types
]#
#[ Basic functions for in-place reversing bytes 2, 4, 6, 8, 16 ]#
proc reverse2(x: var array[0..1, byte]): void {.inline.} =
var tmp: byte = x[0];
x[0] = x[1];
x[1] = tmp;
proc reverse4(x: var array[0..3, byte]): void {.inline.} =
var tmp: byte = x[0];
x[0] = x[3];
x[3] = tmp;
tmp = x[1];
x[1] = x[2];
x[2] = tmp;
return;
proc reverse8(x: var array[0..7, byte]): void {.inline.} =
var tmp: byte = x[0];
x[0] = x[7];
x[7] = tmp;
tmp = x[1];
x[1] = x[6];
x[6] = tmp;
tmp = x[2];
x[2] = x[5];
x[5] = tmp;
tmp = x[3]
x[3] = x[4]
x[4] = tmp;
return;
proc reverse16(x: var array[0..15, byte]): void {.inline.} =
var tmp: byte = x[0];
x[0] = x[15];
x[15] = tmp;
tmp = x[1];
x[1] = x[14];
x[14] = tmp;
tmp = x[2];
x[2] = x[13];
x[13] = tmp;
tmp = x[3];
x[3] = x[12];
x[12] = tmp;
tmp = x[4];
x[4] = x[11];
x[11] = tmp;
tmp = x[5];
x[5] = x[10];
x[10] = tmp;
tmp = x[6];
x[6] = x[9];
x[9] = tmp;
tmp = x[7];
x[7] = x[8];
x[8] = tmp;
return;
proc reverseByteOrder[T](x: T): T {.inline.} =
const n = sizeof(T);
var y = cast[array[0..n-1, byte]](x);
when n == 1:
return x;
elif n == 2:
reverse2(y);
return cast[T](y);
elif n == 4:
reverse4(y);
return cast[T](y);
elif n == 8:
reverse8(y);
return cast[T](y);
elif n == 16:
reverse16(y);
return cast[T](y);
else:
echo "unknown bit size."
#[ Common Byte Order Functions ]#
proc ntoh[T](x: T): T {.inline.} =
when cpuEndian == littleEndian:
return reverseByteOrder(x);
else:
return x;
proc hton[T](x: T): T {.inline.} =
when cpuEndian == littleEndian:
return reverseByteOrder(x);
else:
return x;
proc ltoh[T](x: T): T {.inline.} =
when cpuEndian == littleEndian:
return x;
else:
return reverseByteOrder(x);
proc htol[T](x: T): T {.inline.} =
when cpuEndian == littleEndian:
return x;
else:
return reverseByteOrder(x);
#[ Reverse functions return copies (unused) ]#
proc reverse2C(x: var array[0..1, byte]): array[0..1, byte] =
var tmp: byte = x[0];
x[0] = x[1];
x[1] = tmp;
return x;
proc reverse4C(x: array[0..3, byte]): array[0..3, byte] =
var o: array[0..3, byte];
o[0] = x[3];
o[1] = x[2];
o[2] = x[1];
o[3] = x[0];
return o;
proc reverse8C(x: array[0..7, byte]): array[0..7, byte] =
var o: array[0..7, byte];
o[0] = x[7];
o[1] = x[6];
o[2] = x[5];
o[3] = x[4];
o[4] = x[3];
o[5] = x[2];
o[6] = x[1];
o[7] = x[0];
return o;
proc reverse16C(x: array[0..15, byte]): array[0..15, byte] =
var o: array[0..15, byte];
o[0] = x[15];
o[1] = x[14];
o[2] = x[13];
o[3] = x[12];
o[4] = x[11];
o[5] = x[10];
o[6] = x[9];
o[7] = x[8];
o[8] = x[7];
o[9] = x[6];
o[10] = x[5];
o[11] = x[4];
o[12] = x[3];
o[13] = x[2];
o[14] = x[1];
o[15] = x[0];
return o;
#[
Byte order functions for Nim (intended for basic types)
]#
proc reverseByteOrder[T](x: T): T =
const n = sizeof(T);
const m = n div 2;
var y = cast[array[0..n-1, byte]](x);
for i in 0..<m:
var idx = n - i - 1;
var tmp = y[i];
y[i] = y[idx];
y[idx] = tmp;
return cast[T](y);
proc ntoh[T](x: T): T =
if cpuEndian == littleEndian:
return reverseByteOrder(x);
else:
return x;
proc hton[T](x: T): T =
if cpuEndian == littleEndian:
return reverseByteOrder(x);
else:
return x;
proc ltoh[T](x: T): T =
if cpuEndian == littleEndian:
return x;
else:
return reverseByteOrder(x);
proc htol[T](x: T): T =
if cpuEndian == littleEndian:
return x;
else:
return reverseByteOrder(x);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment