Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to losslessly convert to and from std::string and QByteArray

What is the correct way to convert losslessly between std::string and QByteArray... mostly for the purpose of handling binary data?

I'm using:

QByteArray qba = QString::fromStdString(stdString).toAscii(); 

and

QString(qba).toStdString(); 

but I wanted to check whether this is actually correct.

like image 336
Jake Petroules Avatar asked May 26 '12 16:05

Jake Petroules


2 Answers

For binary data your solution is problematic since non-ASCII characters would be converted to '?' by QString::toAscii(). There is also the unnecessary overhead of UTF-16 conversion for the internal representation of QString. As you might have guessed, QString should only be used if the data is textual, not binary.

Both QByteArray and std::string have constructors for raw data (C-string + length) and also a conversion to C-string + length. So you can use them for conversion:

// std::string => QByteArray QByteArray byteArray(stdString.c_str(), stdString.length());  // QByteArray => std::string std::string stdString(byteArray.constData(), byteArray.length()); 

They are both binary-safe, meaning that the string may contain '\0' characters and doesn't get truncated. The data also doesn't get touched (there is no UTF conversion), so this conversion is "lossless".

Make sure to use the constructors with the length as the second argument (for both QByteArray and std::string), as most other constructors will truncate the data before the first occurrence of a zero.

like image 88
leemes Avatar answered Oct 13 '22 15:10

leemes


As of Qt 5.4, QByteArray has built in support for std::string conversions via QByteArray::toStdString() and QByteArray::fromStdString().

These are implemented almost identically to leemes' answer.

inline std::string QByteArray::toStdString() const { return std::string(constData(), length()); }  inline QByteArray QByteArray::fromStdString(const std::string &s) { return QByteArray(s.data(), int(s.size())); } 
like image 28
Parker Coates Avatar answered Oct 13 '22 16:10

Parker Coates