#include "pch.h"
#include "System/BitConverter.h"
#include <cstring>
#include <iomanip>
#include <sstream>
#include "System/ArgumentNullException.h"
#include "System/ArgumentOutOfRangeException.h"

namespace DotNetDupe {
    namespace System {
        const bool BitConverter::IsLittleEndian = true; // Most modern systems are little-endian

        Array<byte> BitConverter::GetBytes(bool bValue) {
            Array<byte> result(1);
            result[0] = bValue ? 1 : 0;
            return result;
        }

        Array<byte> BitConverter::GetBytes(char chValue) {
            Array<byte> result(1);
            result[0] = (byte)chValue;
            return result;
        }

        Array<byte> BitConverter::GetBytes(double value) {
            Array<byte> result(8);
            std::memcpy(result.GetData(), &value, 8);
            return result;
        }

        Array<byte> BitConverter::GetBytes(short iValue) {
            Array<byte> result(2);
            std::memcpy(result.GetData(), &iValue, 2);
            return result;
        }

        Array<byte> BitConverter::GetBytes(int iValue) {
            Array<byte> result(4);
            std::memcpy(result.GetData(), &iValue, 4);
            return result;
        }

        Array<byte> BitConverter::GetBytes(long long llValue) {
            Array<byte> result(8);
            std::memcpy(result.GetData(), &llValue, 8);
            return result;
        }

        Array<byte> BitConverter::GetBytes(float value) {
            Array<byte> result(4);
            std::memcpy(result.GetData(), &value, 4);
            return result;
        }

        Array<byte> BitConverter::GetBytes(unsigned short iValue) {
            Array<byte> result(2);
            std::memcpy(result.GetData(), &iValue, 2);
            return result;
        }

        Array<byte> BitConverter::GetBytes(unsigned int iValue) {
            Array<byte> result(4);
            std::memcpy(result.GetData(), &iValue, 4);
            return result;
        }

        Array<byte> BitConverter::GetBytes(unsigned long long llValue) {
            Array<byte> result(8);
            std::memcpy(result.GetData(), &llValue, 8);
            return result;
        }

        bool BitConverter::ToBoolean(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex >= value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            return value[iStartIndex] != 0;
        }

        char BitConverter::ToChar(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex >= value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            return (char)value[iStartIndex];
        }

        double BitConverter::ToDouble(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 8 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            double result;
            std::memcpy(&result, value.GetData() + iStartIndex, 8);
            return result;
        }

        short BitConverter::ToInt16(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 2 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            short iResult;
            std::memcpy(&iResult, value.GetData() + iStartIndex, 2);
            return iResult;
        }

        int BitConverter::ToInt32(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 4 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            int iResult;
            std::memcpy(&iResult, value.GetData() + iStartIndex, 4);
            return iResult;
        }

        long long BitConverter::ToInt64(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 8 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            long long llResult;
            std::memcpy(&llResult, value.GetData() + iStartIndex, 8);
            return llResult;
        }

        float BitConverter::ToSingle(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 4 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            float result;
            std::memcpy(&result, value.GetData() + iStartIndex, 4);
            return result;
        }

        unsigned short BitConverter::ToUInt16(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 2 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            unsigned short iResult;
            std::memcpy(&iResult, value.GetData() + iStartIndex, 2);
            return iResult;
        }

        unsigned int BitConverter::ToUInt32(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 4 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            unsigned int iResult;
            std::memcpy(&iResult, value.GetData() + iStartIndex, 4);
            return iResult;
        }

        unsigned long long BitConverter::ToUInt64(Array<byte>& value, int iStartIndex) {
            if (value.GetLength() == 0) throw ArgumentNullException("value");
            if (iStartIndex < 0 || iStartIndex + 8 > value.GetLength()) throw ArgumentOutOfRangeException("iStartIndex");
            unsigned long long llResult;
            std::memcpy(&llResult, value.GetData() + iStartIndex, 8);
            return llResult;
        }

        String BitConverter::ToString(Array<byte>& value) {
            return ToString(value, 0, value.GetLength());
        }

        String BitConverter::ToString(Array<byte>& value, int iStartIndex) {
            return ToString(value, iStartIndex, value.GetLength() - iStartIndex);
        }

        String BitConverter::ToString(Array<byte>& value, int iStartIndex, int nLength) {
            int nArrayLength = value.GetLength();
            if (iStartIndex < 0 || (iStartIndex >= nArrayLength && nArrayLength > 0))
                throw ArgumentOutOfRangeException("iStartIndex");
            if (nLength < 0)
                throw ArgumentOutOfRangeException("nLength");
            if (iStartIndex + nLength > nArrayLength)
                throw ArgumentException("iStartIndex + nLength > value.Length");

            if (nLength == 0) return String("");

            std::stringstream ss;
            for (int iIndex = 0; iIndex < nLength; ++iIndex) {
                if (iIndex > 0) ss << "-";
                ss << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << (int)value [iStartIndex + iIndex];
            }
            return String(ss.str().c_str());
        }

        long long BitConverter::DoubleToInt64Bits(double value) {
            long long llResult;
            std::memcpy(&llResult, &value, sizeof(double));
            return llResult;
        }

        double BitConverter::Int64BitsToDouble(long long llValue) {
            double result;
            std::memcpy(&result, &llValue, sizeof(long long));
            return result;
        }

        int BitConverter::SingleToInt32Bits(float value) {
            int iResult;
            std::memcpy(&iResult, &value, sizeof(float));
            return iResult;
        }

        float BitConverter::Int32BitsToSingle(int iValue) {
            float result;
            std::memcpy(&result, &iValue, sizeof(int));
            return result;
        }
    }
}

Generated by OpenCppCoverage (Version: 0.9.9.0)