How can I get convert wstringstream to char*? - qt

how convert wstringstream to char* ?? (Language c++)
I need this conversion to use the function writeRawData of the qdatastream.h library.
Thank you very much!!

You have to use wstringstream::str() to retrieve the content of the stream.
And then depending on your need you can either convert it to a QString so that the QDataStream can handle the string for you or just write the bytes of the wstring:
void f(wstringstream &stream, QDataStream &qstream)
{
wstring content = stream.str();
QString str = QString::fromStdWString(content);
qstream << str;
}
void g(wstringstream &stream, QDataStream &qstream)
{
wstring content = stream.str();
qstream.writeRawData(static_cast<const char *>(content.c_str()), content.length() * sizeof(wchar_t));
}

wstringstream is a basic_stringstream, you could extract line, char, text from it
look at that http://www.cplusplus.com/reference/sstream/wstringstream/
and you could retreive one example from that http://www.cplusplus.com/reference/sstream/basic_stringstream/str/

Related

QPixmap.loadFromData() does not load image from QByteArray

I'm creating a socket-based program to send a screenshot from one user to another user. I need to convert a screenshot to a byte array before sending. After I convert my screenshot to a QByteArray I insert 4 bytes to the beginning of the array to mark that it is a picture (it is the number 20 to tell me it is a picture and not text or something else).
After I send the byte array via a socket to other user, when it is received I read the first 4 bytes to know what it is. Since it was a picture I then convert it from a QByteArray to QPixmap to show it on a label. I use secondPixmap.loadFromData(byteArray,"JPEG") to load it but it not load any picture.
This is a sample of my code:
void MainWindow::shootScreen()
{
originalPixmap = QPixmap(); // clear image for low memory situations
// on embedded devices.
originalPixmap = QGuiApplication::primaryScreen()->grabWindow(0);
scaledPixmap = originalPixmap.scaled(500, 500);
QByteArray bArray;
QBuffer buffer(&bArray);
buffer.open(QIODevice::WriteOnly);
originalPixmap.save(&buffer,"JPEG",5);
qDebug() << bArray.size() << "diz0";
byteArray= QByteArray();
QDataStream ds(&byteArray,QIODevice::ReadWrite);
int32_t c = 20;
ds << c;
ds<<bArray;
}
void MainWindow::updateScreenshotLabel()
{
this->ui->label->setPixmap(secondPixmap.scaled(this->ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
void MainWindow::on_pushButton_clicked()
{
shootScreen();
}
void MainWindow::on_pushButton_2_clicked()
{
secondPixmap = QPixmap();
QDataStream ds(&byteArray,QIODevice::ReadOnly);
qint32 code;
ds>>code;
secondPixmap.loadFromData(byteArray,"JPEG");
updateScreenshotLabel();
}
Your MainWindow::on_pushButton_2_clicked implementation looks odd. You have...
QDataStream ds(&byteArray,QIODevice::ReadOnly);
which creates a read-only QDataStream that will read it's input data from byteArray. But later you have...
secondPixmap.loadFromData(byteArray,"JPEG");
which attempts to read the QPixmap directly from the same QByteArray -- bypassing the QDataStream completely.
You can also make use of the QPixmap static members that read from/write to a QDataStream. So I think you're looking for something like...
QDataStream ds(&byteArray,QIODevice::ReadOnly);
qint32 code;
ds >> code;
if (code == 20)
ds >> secondPixmap;
And likewise for your MainWindow::shootScreen implementation. You could reduce your code a fair bit by making use of QDataStream & operator<<(QDataStream &stream, const QPixmap &pixmap).

How to unpack 32bit integer packed in a QByteArray?

I'm working with serial communication, and I receive 32bit integers in a QByteArray, packed in 4 separate bytes (little-endian).
I attempt to unpack the value from the 4 bytes using QByteArray::toLong() but it fails the conversion and returns the wrong number:
quint8 packed_bytes[] { 0x12, 0x34, 0x56, 0x78 };
QByteArray packed_array { QByteArray(reinterpret_cast<char*>(packed_bytes),
sizeof(packed_bytes)) };
bool isConversionOK;
qint64 unpacked_value { packed_array.toLong(&isConversionOK) };
// At this point:
// unpacked_value == 0
// isConversionOK == false
The expected unpacked_value is 0x78563412 (little-endian unpacking). Why is the conversion failing?
You can use a QDataStream to read binary data.
quint8 packed_bytes[] { 0x12, 0x34, 0x56, 0x78 };
QByteArray packed_array { QByteArray(reinterpret_cast<char*>(packed_bytes), sizeof(packed_bytes)) };
QDataStream stream(packed_array);
stream.setByteOrder(QDataStream::LittleEndian);
int result;
stream >> result;
qDebug() << QString::number(result,16);
toLong() converts a char * digits string to long. Not bytes. And your values likely don't make the up the string "0x78563412" or its decimal equivalent. Hence the 0 result.
If you need the byte values interpreted as long you can do something like:
long value;
value == *((long*)packed_bytes.data());
Or to access an array of bytes as long array:
long * values;
values == (long*)packed_bytes.data();
values[0]; // contains first long
values[1]; // contains second long
...
Don't know whether my examples work out of the box but it should make clear the principle.
Check out this example:
char bytes[] = {255, 0};
QByteArray b(bytes, 2);
QByteArray c("255");
qDebug() << b.toShort() << c.toShort();
qDebug() << *((short*)b.data()) << *((short*)c.data());
the output is:
0 255
255 13618
You may need to change the byte order depending on the endianess. But it does what you need.
you can build your qint64 with bit manipulators:
#include <QtGlobal>
#include <QByteArray>
#include <QDebug>
int main()
{
quint8 packed_bytes[] { 0x12, 0x34, 0x56, 0x78 };
QByteArray packed_array { QByteArray(reinterpret_cast<char*>(packed_bytes),
sizeof(packed_bytes)) };
qint64 unpacked_value = 0;
unpacked_value |= packed_array.at(0) |
packed_array.at(1) << 8 |
packed_array.at(2) << 16 |
packed_array.at(3) << 24;
qDebug() << QString("0x%1").arg(unpacked_value, 0, 16);
}
Here's a generic solution for converting a QByteArray to "some other type" (such as what is specifically asked in the question) by running it through a QDataStream (as done by the accepted answer).
DISCLAIMER: I am only advocating for using this in a private implementation. I am aware there are many ways one could abuse the
macro!
Using this macro, you can easily produce many conversion functions such as the examples I've provided. Defining a series of such functions in this way may be useful if you need to pull a variety of types out of a stream. Obviously, you could tweak the macro for your use case, the point is the pattern can remain basically same and be put in a macro like this.
#define byteArrayToType( data, order, type ) \
QDataStream stream( data ); \
stream.setByteOrder( order ); \
type t; \
stream >> t; \
return t;
Example functions, which simply wrap the macro:
16 bit, signed
qint16 toQInt16( const QByteArray &data,
const QDataStream::ByteOrder order=QDataStream::BigEndian )
{ byteArrayToType( data, order, qint16 ) }
32 bit, signed
qint32 toQInt32( const QByteArray &data,
const QDataStream::ByteOrder order=QDataStream::BigEndian )
{ byteArrayToType( data, order, qint32 ) }
64 bit, signed
qint64 toQInt64( const QByteArray &data,
const QDataStream::ByteOrder order=QDataStream::BigEndian )
{ byteArrayToType( data, order, qint64 ) }
Cast the Byte array to the required format and use the built-in function qFromBigEndian or qFromLittleEndian to set the Byte order. Example code is shown below,
QByteArray byteArray("\x45\x09\x03\x00");
quint32 myValue = qFromBigEndian<quint32>(byteArray);
qDebug() << "Hex value: " << QString("0x%1").arg(myValue, 8, 16, QLatin1Char( '0' ));
myValue holds the converted value.
Don't forget to include the header file <QtEndian>

QString with special characters to const char*

I m trying to convert QString with special characters to const char* but I did not succeed. my function is:
void class::func(const QString& Name) // fileName = "â.tmp"
{
qDebug()<< Name; // display "â.tmp"
const char* cfileName = Name.toAscii().data();
qDebug() << cfileName; // display "a?.tmp"
}
qDebug()<< fileName display the true value that is "â.tmp" but after converting it to const a char*, I do not succeed to have the right value.
In the second time I try to use const char* cfileName = QString::fromUtf8(fileName.toAscii().data()); but I did not still have the right value, it display the same thing: "a?.tmp". How can I fix this thank you
due to convert QString to const char* :
QString str("hi lor!");
const char *s = str.toStdString().c_str();
msg.setText(QString::fromUtf8(s));
msg.exec();
EDIT: using QByteArray QString::toUtf8 () const is much better
QString string = "â.tmp";
const char* encodedString = string.toUtf8().data();
ORIGIONAL:
You probably need to use a codec, see http://qt-project.org/doc/qt-4.8/qtextcodec.html
something like this should work:
QString string = "â.tmp";
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray encodedString = codec->fromUnicode(string);
the documentation does not say what encoding types QDebug & QDebug::operator<< ( const char * s ) supports, it may be platform dependent, try verifying a correct conversion another. The problem may be in qDebug() or the stream it writes to.

Qt array QString

I get result from db by selectall query and I want save result in array and send it by socket.
db.open();
QSqlQuery *selectall = new QSqlQuery(db);
selectall->prepare("select * from phone_table");
selectall->exec();
selectall->first();
QString result;
QByteArray arrayresult;
int index = 0;
while (selectall->next())
{
index += 1;
// qint16 id = selectall->value(0).toString();
QString name_ = selectall->value(1).toString();
QString surname = selectall->value(2).toString();
QString phone_number = selectall->value(3).toString();
result = "*"+ name_+"*"+surname+"*"+phone_number;
arrayresult[index] = result;
}
I get this error binary '=' : no operator found which takes a right-hand operand of type 'const char [16]'
You are trying to set a QByteRef to a QString.
I think you may want a QList and to arrayresult.append(result).
Or else if you want one QByteArray with the concat of all results use arrayresult+= result.
You may build the QString you want to initialize QByteArray. To then convert from QString to QByteArray, you can do
QByteArray array_ = string_.toLatin1();
if encoding is Latin1.
You may alternatively use append
QByteArray & QByteArray::append ( const QString & str )
This is an overloaded function.
Appends the string str to this byte array. The Unicode data is
converted into 8-bit characters using QString::toAscii().
If the QString contains non-ASCII Unicode characters, using this
function can lead to loss of information. You can disable this
function by defining QT_NO_CAST_TO_ASCII when you compile your
applications. You then need to call QString::toAscii() (or
QString::toLatin1() or QString::toUtf8() or QString::toLocal8Bit())
explicitly if you want to convert the data to const char *.
append is doing the same as + operator.
You can do the following with the toLatin1() function of the QString.
// ...
QString result = QString( "*%1*%2*%3" ).arg( name_ )
.arg( surname )
.arg( phone_number );
QByteArray resultArray = result.toLatin1();
// Or ...
// QByteArray resultArray = result.toLocal8Bit();
// QByteArray resultArray = result.toUtf8();
And you shall use a QList< QByteArray > for containing the results, or you can just append the last result item to your final result object.

QByteArray convert to/from unsigned char *

QByteArray inArray = " ... ";
unsigned char *in = convert1(inArray);
unsigned char *out;
someFunction(in, out);
QByteArray outArray = convert2(out);
the question is how can I correctly make these conversions (convert1 and convert2).
I cannot change someFunction(unsigned char *, unsigned char *), but I have to work with QByteArray here.
Qt has really great docs, you should use them.
If someFunction doesn't modify or store pointer to in data you can use this:
QByteArray inArray = " ... ";
unsigned char *out;
someFunction((unsigned char*)(inArray.data()), out);
QByteArray outArray((char*)out);
Otherwise you have to make a deep copy of the char* returned by QByteArray::data() (see the docs for code snippet).
if someFunction takes a const char* args then just use ConstData() or data() in QByteArray class.
if you need a char*, you can then use strdup(). This method is doing this
char *strdup (const char *s) {
char *d = malloc (strlen (s) + 1); // Space for length plus nul
if (d == NULL) return NULL; // No memory
strcpy (d,s); // Copy the characters
return d; // Return the new string
}
more info here: strdup() - what does it do in C?

Resources