/******************************************************************************
* Copyright (C) Ultraleap, Inc. 2011-2021. *
* *
* Use subject to the terms of the Apache License 2.0 available at *
* http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
* between Ultraleap and you, your company or other organization. *
******************************************************************************/
using System;
using System.Runtime.InteropServices;
namespace Leap.Unity
{
public static class BitConverterNonAlloc
{
#if !ENABLE_IL2CPP
[ThreadStatic]
private static ConversionStruct _c;
#endif
///
/// Given an array of bytes, and an offset to start reading from, return
/// the UInt16 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static UInt16 ToUInt16(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(UInt16*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
return _c.UInt16;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Int16 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static Int16 ToInt16(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(Int16*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
return _c.Int16;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the UInt32 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static UInt32 ToUInt32(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(UInt32*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
return _c.UInt32;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Int32 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static Int32 ToInt32(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(Int32*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
return _c.Int32;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the UInt64 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static UInt64 ToUInt64(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(UInt64*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
_c.Byte4 = bytes[offset++];
_c.Byte5 = bytes[offset++];
_c.Byte6 = bytes[offset++];
_c.Byte7 = bytes[offset++];
return _c.UInt64;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Int64 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static Int64 ToInt64(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(Int64*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
_c.Byte4 = bytes[offset++];
_c.Byte5 = bytes[offset++];
_c.Byte6 = bytes[offset++];
_c.Byte7 = bytes[offset++];
return _c.Int64;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Single value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static Single ToSingle(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(Single*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
return _c.Single;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Double value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
public static Double ToDouble(byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
return *(Double*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
_c.Byte4 = bytes[offset++];
_c.Byte5 = bytes[offset++];
_c.Byte6 = bytes[offset++];
_c.Byte7 = bytes[offset++];
return _c.Double;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the UInt16 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the UInt16 in bytes
/// after this method is complete.
///
public static UInt16 ToUInt16(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(UInt16);
return *(UInt16*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
return _c.UInt16;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Int16 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the Int16 in bytes
/// after this method is complete.
///
public static Int16 ToInt16(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Int16);
return *(Int16*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
return _c.Int16;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the UInt32 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the UInt32 in bytes
/// after this method is complete.
///
public static UInt32 ToUInt32(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(UInt32);
return *(UInt32*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
return _c.UInt32;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Int32 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the Int32 in bytes
/// after this method is complete.
///
public static Int32 ToInt32(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Int32);
return *(Int32*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
return _c.Int32;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the UInt64 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the UInt64 in bytes
/// after this method is complete.
///
public static UInt64 ToUInt64(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(UInt64);
return *(UInt64*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
_c.Byte4 = bytes[offset++];
_c.Byte5 = bytes[offset++];
_c.Byte6 = bytes[offset++];
_c.Byte7 = bytes[offset++];
return _c.UInt64;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Int64 value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the Int64 in bytes
/// after this method is complete.
///
public static Int64 ToInt64(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Int64);
return *(Int64*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
_c.Byte4 = bytes[offset++];
_c.Byte5 = bytes[offset++];
_c.Byte6 = bytes[offset++];
_c.Byte7 = bytes[offset++];
return _c.Int64;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Single value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the Single in bytes
/// after this method is complete.
///
public static Single ToSingle(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Single);
return *(Single*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
return _c.Single;
#endif
}
///
/// Given an array of bytes, and an offset to start reading from, return
/// the Double value that is represented by that byte pattern. Undefined
/// results if there are not enough bytes in the array.
///
/// The offset variable is incremented by the size of the Double in bytes
/// after this method is complete.
///
public static Double ToDouble(byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Double);
return *(Double*)ptr;
}
}
#else
_c.Byte0 = bytes[offset++];
_c.Byte1 = bytes[offset++];
_c.Byte2 = bytes[offset++];
_c.Byte3 = bytes[offset++];
_c.Byte4 = bytes[offset++];
_c.Byte5 = bytes[offset++];
_c.Byte6 = bytes[offset++];
_c.Byte7 = bytes[offset++];
return _c.Double;
#endif
}
///
/// Given a UInt16 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(UInt16 value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(UInt16*)ptr = value;
}
}
#else
_c.UInt16 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
#endif
}
///
/// Given a Int16 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(Int16 value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(Int16*)ptr = value;
}
}
#else
_c.Int16 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
#endif
}
///
/// Given a UInt32 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(UInt32 value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(UInt32*)ptr = value;
}
}
#else
_c.UInt32 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
#endif
}
///
/// Given a Int32 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(Int32 value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(Int32*)ptr = value;
}
}
#else
_c.Int32 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
#endif
}
///
/// Given a UInt64 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(UInt64 value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(UInt64*)ptr = value;
}
}
#else
_c.UInt64 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
bytes[offset++] = _c.Byte4;
bytes[offset++] = _c.Byte5;
bytes[offset++] = _c.Byte6;
bytes[offset++] = _c.Byte7;
#endif
}
///
/// Given a Int64 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(Int64 value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(Int64*)ptr = value;
}
}
#else
_c.Int64 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
bytes[offset++] = _c.Byte4;
bytes[offset++] = _c.Byte5;
bytes[offset++] = _c.Byte6;
bytes[offset++] = _c.Byte7;
#endif
}
///
/// Given a Single value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(Single value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(Single*)ptr = value;
}
}
#else
_c.Single = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
#endif
}
///
/// Given a Double value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
public static void GetBytes(Double value, byte[] bytes, int offset = 0)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
*(Double*)ptr = value;
}
}
#else
_c.Double = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
bytes[offset++] = _c.Byte4;
bytes[offset++] = _c.Byte5;
bytes[offset++] = _c.Byte6;
bytes[offset++] = _c.Byte7;
#endif
}
///
/// Given a UInt16 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the UInt16 in bytes
/// after this method is complete.
///
public static void GetBytes(UInt16 value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(UInt16);
*(UInt16*)ptr = value;
}
}
#else
_c.UInt16 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
#endif
}
///
/// Given a Int16 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the Int16 in bytes
/// after this method is complete.
///
public static void GetBytes(Int16 value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Int16);
*(Int16*)ptr = value;
}
}
#else
_c.Int16 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
#endif
}
///
/// Given a UInt32 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the UInt32 in bytes
/// after this method is complete.
///
public static void GetBytes(UInt32 value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(UInt32);
*(UInt32*)ptr = value;
}
}
#else
_c.UInt32 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
#endif
}
///
/// Given a Int32 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the Int32 in bytes
/// after this method is complete.
///
public static void GetBytes(Int32 value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Int32);
*(Int32*)ptr = value;
}
}
#else
_c.Int32 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
#endif
}
///
/// Given a UInt64 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the UInt64 in bytes
/// after this method is complete.
///
public static void GetBytes(UInt64 value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(UInt64);
*(UInt64*)ptr = value;
}
}
#else
_c.UInt64 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
bytes[offset++] = _c.Byte4;
bytes[offset++] = _c.Byte5;
bytes[offset++] = _c.Byte6;
bytes[offset++] = _c.Byte7;
#endif
}
///
/// Given a Int64 value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the Int64 in bytes
/// after this method is complete.
///
public static void GetBytes(Int64 value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Int64);
*(Int64*)ptr = value;
}
}
#else
_c.Int64 = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
bytes[offset++] = _c.Byte4;
bytes[offset++] = _c.Byte5;
bytes[offset++] = _c.Byte6;
bytes[offset++] = _c.Byte7;
#endif
}
///
/// Given a Single value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the Single in bytes
/// after this method is complete.
///
public static void GetBytes(Single value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Single);
*(Single*)ptr = value;
}
}
#else
_c.Single = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
#endif
}
///
/// Given a Double value, copy its binary representation into the given array
/// of bytes, at the given offset. Undefined results if there are not enough
/// bytes in the array to accept the value.
///
/// The offset variable is incremented by the size of the Double in bytes
/// after this method is complete.
///
public static void GetBytes(Double value, byte[] bytes, ref int offset)
{
#if ENABLE_IL2CPP
unsafe {
fixed (void* ptr = &bytes[offset]) {
offset += sizeof(Double);
*(Double*)ptr = value;
}
}
#else
_c.Double = value;
bytes[offset++] = _c.Byte0;
bytes[offset++] = _c.Byte1;
bytes[offset++] = _c.Byte2;
bytes[offset++] = _c.Byte3;
bytes[offset++] = _c.Byte4;
bytes[offset++] = _c.Byte5;
bytes[offset++] = _c.Byte6;
bytes[offset++] = _c.Byte7;
#endif
}
#if !ENABLE_IL2CPP
[StructLayout(LayoutKind.Explicit)]
private struct ConversionStruct
{
[FieldOffset(0)]
public byte Byte0;
[FieldOffset(1)]
public byte Byte1;
[FieldOffset(2)]
public byte Byte2;
[FieldOffset(3)]
public byte Byte3;
[FieldOffset(4)]
public byte Byte4;
[FieldOffset(5)]
public byte Byte5;
[FieldOffset(6)]
public byte Byte6;
[FieldOffset(7)]
public byte Byte7;
[FieldOffset(0)]
public UInt16 UInt16;
[FieldOffset(0)]
public Int16 Int16;
[FieldOffset(0)]
public UInt32 UInt32;
[FieldOffset(0)]
public Int32 Int32;
[FieldOffset(0)]
public UInt64 UInt64;
[FieldOffset(0)]
public Int64 Int64;
[FieldOffset(0)]
public Single Single;
[FieldOffset(0)]
public Double Double;
}
#endif
}
}