[Development] Enhancement to QIODevice?

Andrzej Ostruszka andrzej.ostruszka at gmail.com
Wed Sep 16 13:13:01 CEST 2015

On 09/16/2015 08:57 AM, Thiago Macieira wrote:
>>> You could use peek() to search the buffer, then read() exactly as much as
>>> you really need.
>> I understand that we are talking about
>> QIODevicePrivateLinearBuffer::peek() here.
> No, I meant QIODevice::peek()

First of all - I do not claim that I have mastered Qt internals!
So everything below you should take with a grain of salt :)

QIODevice::peek() is implemented in terms of QIODevice::read() (which 
then uses QIODevicePrivate::read() which does the memcpy()) and later 
putting it back.  Pretty convoluted but it really does not matter - I 
just assumed the simpler case of direct peek into the buffer.

>> In your approach I'd be copying data twice, but I can eliminate one with
>> peek()ing
>> directly to the output buffer and later skip()ping in successful case.
>> However in case
>> when delimiter is not yet available I'd have unnecessary copying.
> Then please provide a patch that avoids the unnecessary second copy when the
> read() destination is a null pointer.

Here I must say that I don't understand.  Let me rephrase what I've said 
earlier.  Suppose that there is some data in buffer and I want to know 
if delimiter is in it.  Without direct access to this buffer memory I 
can only:
1. copy (by peeking()) it to some other place (possibly the final output 
2. search for delimiter in my copy
3. if found: drop "number of bytes to delimiter" from buffer

What I'm saying is that in successful case (when delimiter is found) 
this sequence is optimal.  However, in case when there is no delimiter 
yet in the buffer, operation 1 is wasted (not really needed).  And I 
don't see how to avoid it without allowing user to search in the 
internal buffer.

Possible ways to allow for searching in this buffer are (I'm shortening 
names here):
A. Add optional param to canReadLine() readLine() (for QIODP or maybe 
even QIOD)
B. Add this QIODPLB::countTo() functionality (which does not break or 
interfere with anything)
C. Add QIODPLB::data() function to buffer which will return "first" (I'm 
talking in terms of QIODPLB implementation)
D. ???

As for C.  This is another solution - which also does not interfere with 
anything.  The amount of data is already available via size().
Then any kind of "packet" termination can be implemented (not just by 
single char) on top of it.  Value returned by this QIODPLB::data() is 
only invalidated by explicit user reading so this would be pretty safe 
too and its only one line of code.

So what do you think?

>> And while peek()ing I'd have to use the min(max size of my output
>> buffer, size())
>> which would mean that I'd be copying "overlapping" parts more than once.
> I didn't understand this.

What I wanted to say is that:
- in operation 1 above the number of bytes to peek need to be specified
- the only reasonable choice - without using some application specific 
heuristic - is the amount of bytes already available (lets forget for a 
moment possible constrains of my output buffer size)

Then in situation when in buffer is more then just one "line" available 
I would be copying parts of data after first delimiter in order to later 
put them back and read them again on next data arrival.

> I think there are easier ways to do this, so I don't think it makes sense to
> accept this suggestion.

Yes one can peek() at buffer but as I've tried to state this approach 
has some drawbacks (from performance point of view).  I can also 
understand that maintainers are worried about growing complexity and 
maintenance burden but honestly I don't see any growth in these from 
options B and C above.  These are internal, no testing for them is 
needed, they don't interfere with any other functionality etc.

So Your Honour, what is the verdict? ;)


More information about the Development mailing list