Skip to content
Snippets Groups Projects
binary_converter.cpp 4.57 KiB
Newer Older
  • Learn to ignore specific revisions
  • theazgra's avatar
    theazgra committed
    /**
     * This implementation is inspired by BitConverter from .NET
     * https://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs
     */
    
    #include "binary_converter.h"
    
    short bytes_to_short(const ByteArray &bytes, const ulong fromIndex)
    
        always_assert(bytes.size() >= sizeof(short));
        always_assert(fromIndex <= bytes.size() - sizeof(short));
    
    theazgra's avatar
    theazgra committed
    
        // Little endian
        auto bit = &bytes[fromIndex];
    
    
        if (fromIndex % 2 == sizeof(short))
    
    theazgra's avatar
    theazgra committed
        {
            return (*((short *)bit));
        }
        else
        {
            return (short)((*bit) | (*(bit + 1) << 8));
        }
    }
    
    
    int bytes_to_int(const ByteArray &bytes, const ulong fromIndex)
    
        always_assert(bytes.size() >= sizeof(int));
        always_assert(fromIndex <= bytes.size() - sizeof(int));
    
    theazgra's avatar
    theazgra committed
    
        // Little endian
        auto bit = &bytes[fromIndex];
    
    
        if (fromIndex % sizeof(int) == 0)
    
    theazgra's avatar
    theazgra committed
        {
            return (*((int *)bit));
        }
        else
        {
            return (*bit | (*(bit + 1) << 8) | (*(bit + 2) << 16) | (*(bit + 3) << 24));
        }
    }
    
    
    int bytes_to_long(const ByteArray &bytes, const ulong fromIndex)
    
        always_assert(bytes.size() >= sizeof(long));
        always_assert(fromIndex <= bytes.size() - sizeof(long));
    
    theazgra's avatar
    theazgra committed
    
        // Little endian
        auto bit = &bytes[fromIndex];
    
        if (fromIndex % sizeof(long) == 0)
    
    theazgra's avatar
    theazgra committed
        {
            return (*((long *)bit));
        }
        else
        {
            int i1 = (*bit) | (*(bit + 1) << 8) | (*(bit + 2) << 16) | (*(bit + 3) << 24);
            int i2 = (*(bit + 4)) | (*(bit + 5) << 8) | (*(bit + 6) << 16) | (*(bit + 7) << 24);
            return ((uint)i1 | ((long)i2 << 32));
        }
    }
    
    
    float bytes_to_float(const ByteArray &bytes, const ulong fromIndex)
    
        always_assert(bytes.size() >= sizeof(float));
        always_assert(fromIndex <= bytes.size() - sizeof(float));
    
        memcpy(&result, (bytes.data() + fromIndex), sizeof(float));
    
    double bytes_to_double(const ByteArray &bytes, const ulong fromIndex)
    
        always_assert(bytes.size() >= sizeof(double));
        always_assert(fromIndex <= bytes.size() - sizeof(double));
    
        memcpy(&result, (bytes.data() + fromIndex), sizeof(double));
    
    ushort bytes_to_ushort(const ByteArray &bytes, const ulong fromIndex)
    
    theazgra's avatar
    theazgra committed
    {
        return ((ushort)bytes_to_short(bytes, fromIndex));
    }
    
    
    uint bytes_to_uint(const ByteArray &bytes, const ulong fromIndex)
    
    theazgra's avatar
    theazgra committed
    {
        return ((uint)bytes_to_int(bytes, fromIndex));
    }
    
    
    ulong bytes_to_ulong(const ByteArray &bytes, const ulong fromIndex)
    
    theazgra's avatar
    theazgra committed
    {
        return ((ulong)bytes_to_long(bytes, fromIndex));
    }
    
    
    std::string utf8bytes_to_string(const ByteArray &bytes)
    
    {
        return utf8bytes_to_string(bytes, 0, bytes.size());
    }
    
    theazgra's avatar
    theazgra committed
    
    
    std::string utf8bytes_to_string(const ByteArray &bytes, const ulong fromIndex, const uint byteCount)
    
    theazgra's avatar
    theazgra committed
    {
    
        if (bytes.size() == 0)
            return "";
    
    theazgra's avatar
    theazgra committed
        auto fromIt = bytes.begin() + fromIndex;
    
        ByteArray stringBytes(fromIt, fromIt + byteCount);
    
    theazgra's avatar
    theazgra committed
        std::string result = boost::locale::conv::from_utf<char>((char *)stringBytes.data(), "UTF-8");
        return result;
    
    }
    
    ByteArray int_to_bytes(const int &i)
    {
        ByteArray intBytes;
        intBytes.resize(sizeof(int));
    
        std::memcpy(intBytes.data(), &i, sizeof(int));
        return intBytes;
    }
    
    
    ByteArray ushort_to_bytes(const ushort &x)
    {
        ByteArray ushortBytes;
        ushortBytes.resize(sizeof(ushort));
    
        std::memcpy(ushortBytes.data(), &x, sizeof(ushort));
        return ushortBytes;
    }
    
    
    void int_to_bytes(const int &i, ByteArray &buffer, size_t bufferPosition)
    {
        always_assert(buffer.size() - bufferPosition >= sizeof(int));
        std::memcpy((buffer.data() + bufferPosition), &i, sizeof(int));
    }
    
    
    void ushort_to_bytes(const ushort &x, ByteArray &buffer, size_t bufferPosition)
    {
        always_assert(buffer.size() - bufferPosition >= sizeof(ushort));
        std::memcpy((buffer.data() + bufferPosition), &x, sizeof(ushort));
    }
    
    
    std::vector<ushort> bytes_to_ushort_array(const ByteArray &data)
    {
        std::vector<ushort> result;
        result.resize(data.size() / sizeof(ushort));
    
        size_t index = 0;
    
        for (size_t i = 0; i < data.size(); i += sizeof(ushort))
    
        {
            result[index++] = bytes_to_ushort(data, i);
        }
    
        return result;
    }
    
    ByteArray int_array_to_bytes(const std::vector<int> &data)
    {
        ByteArray result;
        result.resize(data.size() * sizeof(int));
    
        for (size_t i = 0; i < data.size(); i++)
        {
            int_to_bytes(data[i], result, i * sizeof(int));
        }
    
        return result;
    }
    
    ByteArray ushort_array_to_bytes(const std::vector<ushort> &data)
    {
        ByteArray result;
        result.resize(data.size() * sizeof(ushort));
    
        for (size_t i = 0; i < data.size(); i++)
        {
            ushort_to_bytes(data[i], result, i * sizeof(ushort));
        }