Sending / Receiving of byte arrays
Simon McVittie
simon.mcvittie at collabora.co.uk
Wed Feb 8 01:48:41 PST 2012
On 07/02/12 22:24, Bogdan Lotko wrote:
> In the following (C++) structure the *buff *shall be sent as a byte array
...
> I suppose the signature will be something like (sia(yyyy)), and I have
> to send all bytes separately, or there is a better way to do it
(Disclaimer: I understand D-Bus, but I haven't used Qt for a while.)
Think about what you want to achieve on D-Bus, *then* about how to get
that to happen in QtDBus. Do you want the signature to be (siay) or
(si(yyyy)) or (siyyyy), or even (siu)? Any of those are achievable - the
right one depends on what those four bytes represent.
I suspect the answer is probably that you want (siay), but I could be
wrong - it depends what the bytes represent, and you haven't really
given enough context for a good guess.
If you want (si(yyyy)) or (siyyyy), you'll have to serialize each of the
four bytes separately (it's a special case of a struct); if you want
(siu) you'll have to combine the bytes into an unsigned int and send that.
> I've also been thinking to use the structure with QByteArray instead
> of *buff. *Is it feasible?
> e.g construct the QByteArray using fromRawData(buff,4) just before
> sending.
That's how I'd do it: I believe QtDBus already knows how to send a
QByteArray as an 'ay', so construct a temporary one from buff and
serialize that with the << operator. (But use sizeof(myStruct.buff)
instead of hard-coding 4.)
> How to receive this byte array ( there is nothing like "toRawData()" ) ?
You can deserialize an 'ay' into a temporary QByteArray with the >>
operator. After that, there are three situations you need to think about:
* the other process sends the right amount of data
* the other process sends too much data
* the other process sends too little data
Possible resolutions for "too much data" include returning an error to
the other process, or silently truncating at 4 bytes. Possible
resolutions for "too little data" include returning an error to the
other process, or padding with zeroes. Don't let the other process
overflow the buffer and trigger a remote exploit... and you probably
don't want to be using uninitialized data if it provides too little, either.
Here's one possible implementation of truncation and zero-padding:
std::memset(myStruct.buff, '\0', sizeof(myStruct.buff));
std::memcpy(myStruct.buff, myByteArray.constData(),
MIN(myByteArray.size(), sizeof(myStruct.buff)));
but to be honest I'm not sure why you're using a fixed-size char[n] in
Qt/C++ code at all - if you can just put a QByteArray in the struct,
you'll be much better-protected from buffer overflows. (Similarly, I'd
be inclined to use a GByteArray or a GString if this was GLib code.)
S
More information about the dbus
mailing list