[Development] Enhancement to QIODevice?
Andrzej Ostruszka
andrzej.ostruszka at gmail.com
Mon Sep 14 12:25:20 CEST 2015
Hello all,
I'd like to ask for possibility to enhance a bit QIODevice.
My problem/wish is following. I'm using QSerialPort and (as all
QIODevice-s) it is tailored for reading in "lines" ('\n') which is fine
since most of the time this is exactly what I need. But I just happen
to have to deal with an older lock-in device which communicates via
messages terminated by '\r'.
So what I'm aiming to is to make the "line" (or more generally "packet")
termination a bit more flexible, that is to allow user to specify the
delimiter. Currently I think the only available solution for my wish is
double buffering - that is to introduce my own buffer that will suck
everything from QIODevice and allow searching for other delimiter but
I'd like to do better than that.
From now on I'll talk about QIODevice only since QSerialPort is
inheriting from it for the bulk of functionality (and this could also
benefit QIODevice).
Since '\n' is just hardcoded in QIODevice (actually in buffer used in
its private part) one option would be to add it as last optional
parameter to canReadLine() and readLine() with default value '\n'. What
do you think?
I'm afraid a bit that you might object here:
- we don't want to change that low level functionality to just fit some
very specific and rare case (true my example is rare - but I can find
other aplications like e.g. reading pipe delimited values or other)
- this would not be backward compatible (although I don't why)
- being low level would "naturally" push this interface change to all
classes that inherit from QIODevice and this would be significant change
- in addition to changing code we would have to also change documentation
So the other option that I'd like for you to consider is to enhance
buffer used for reading in QIODevicePrivate.
Minimal change that I could come up with is:
--8<-----------------------
diff --git i/src/corelib/io/qiodevice_p.h w/src/corelib/io/qiodevice_p.h
index 56a89ab..090e551 100644
--- i/src/corelib/io/qiodevice_p.h
+++ w/src/corelib/io/qiodevice_p.h
@@ -143,6 +143,10 @@ public:
bool canReadLine() const {
return memchr(first, '\n', len);
}
+ qint64 countTo(char c) {
+ char* pos = static_cast<char*>(memchr(first, c, len));
+ return pos ? 1+(pos-first) : 0;
+ }
void ungetChar(char c) {
if (first == buf) {
// underflow, the existing valid data needs to move to the en
--8<-----------------------
countTo() returns number of bytes one would have to read() in order to
have first delimiter copied to user data structures (that is it is
inclusive) and if delimiter is not available than it returns 0.
By using this I can then subclass QSerialPort and implement what I want
without double buffering. That way I can also avoid double searching
for delimiter [1].
Does this kind of suggestion/change has any chance of going through. In
other words: would it be a waste of time for me to setup dev env and
gerrit to try to push something like this?
Best regards
Andrzej Ostruszka
[1] This is "a problem" with the current interface since usually
QIODevice::canReadLine() and QIODevice::readLine() are used in tandem
and in readyRead() callback one checks for "canReadLine" before invoking
readLine() in order to not block if the whole line is not yet available.
This pattern means that we are doubly searching for the delimiter.
More information about the Development
mailing list