[Development] Enhancement to QIODevice?

André Somers andre at familiesomers.nl
Mon Sep 14 12:43:59 CEST 2015


Op 14-9-2015 om 12:25 schreef Andrzej Ostruszka:
> 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].
I guess that also means that your countTo() would need to be virtual, 
right? That would not be bc.

Would it not make sense to just add a non-virtual getter and a setter 
for the delimitation marker in the QIODevice API, instead of hard-coding 
'\n'? Obviously you would default that to '\n', but for your usecase you 
would then set it to '\r' and everything else remain as-is...

André




More information about the Development mailing list