How to convert a boost::multiprecision::cpp_int to QByteArray
-
How can I convert a cpp_int to a binary QByteArray? I already convert a quint32 to a QByteArray with the following function:
QByteArray MySmallNumber::intToByteArray(QDataStream::ByteOrder byteOrder) { // Convert the int to QByteArray QByteArray intByteArray; QDataStream intDataStream(&intByteArray, QIODevice::WriteOnly); // The default setting is big endian. // We recommend leaving this setting unless you have special requirements. //intDataStream.setByteOrder(m_byteOrder); intDataStream.setByteOrder(byteOrder); intDataStream << m_intNumber; return intByteArray; }
-
You already had a conversion in your previous post some days ago - did it not work?
https://forum.qt.io/topic/111466/convert-64-byte-qbytearray-to-two-32-byte-int/8 -
@Christian-Ehrlicher The code in my previous post worked, but I this time I wanted to have it in binary format. It sometimes helps me to ask questions to find the right solution :-)
Now I came up with the following solution:
QByteArray MyBigNumber::byteArrayHex() { // See https://www.systutorials.com/131/convert-string-to-int-and-reverse/ // Convert the cpp_int to a hex std::string std::string str; std::stringstream stream; stream << std::hex << m_cppInt; str = stream.str(); // Convert the hex std::string to a binary QByteArray return QByteArray::fromHex(QByteArray::fromStdString(str)); }
How does that look like?
-
boost's multiprecision keeps the data in tuples of binary, but you can use bitshifts to just extract it byte by byte (as with any other number). Something along these lines:
typedef decltype(m_cppInt) BigInt; constexpr int bytes = std::numeric_limits<BigInt>::digits / 8; constexpr quint8 mask = quint8(-1); constexpr quint8 shift = sizeof(quint8) * 8; QByteArray data(bytes, 0); for (int i = 0; i < bytes; i++) { data[bytes - i - 1] = quint8(m_cppInt & mask); m_cppInt >>= shift; }
-
boost multiprecision can serialise/deserialise itself.
std::vector<char> chars; boost::iostreams::stream_buffer<boost::iostreams::back_insert_device<std::vector<char> > > bb(chars); boost::archive::binary_oarchive oa(bb, boost::archive::no_header | boost::archive::no_tracking | boost::archive::no_codecvt); oa << m_cppInt; QByteArray serialised(chars.data(),chars.size());
P.S.
boost::iostreams::back_insert_device
might work directly withQByteArray
as well without the need to use thestd::vector<char>
indirection but I have no way of testing it atm, feel free to explore that option