PDA

View Full Version : Using QIODevice to read a GPS filenode?



hickscorp
3rd December 2007, 17:36
Hello people,

i am trying to achieve programmatically an async read on a IO node file which receives the outputs of a NMEA GPS.

i have tried to subclass QIODevice like this (For testing):

#include "QIOGpsReader.h"
#include <QIODevice>

QIOGpsReader::QIOGpsReader (QString node, QObject *parent) : QIODevice(parent) {
qDebug("QIOGpsReader::ctor");
}

QIOGpsReader::~QIOGpsReader (void) {
qDebug("QIOGpsReader::~ctor");
}

qint64 QIOGpsReader::readData (char *data, qint64 maxSize) {
qDebug("QIOGpsReader::readData");
strcpy(data, "1");
return 1;
}

qint64 QIOGpsReader::writeData (const char *data, qint64 maxSize) {
qDebug("QIOGpsReader::writeData");
return 0;
}

qint64 QIOGpsReader::bytesAvailable (void) const {
qDebug("QIOGpsReader::bytesAvailable");
return 1;
}

Then in my main routine i instanciate a QIOGpsReader object and just connect the readyRead signal to a slot. Then i do a open(QIODevice::ReadOnly) "just to do it".

What i dont understand is, on what is based the "readReady" signal? When i look to my debug, i don't see any of my qDebug messages... What will make the QIODevice trigger a readyRead signal? i thought at a first that returning always 1 from readData and bytesAvailable would "tell" the QIODevice that it has to trigger, but it doesnt...

Basically, what is the method i have to reimplement which will tell the QIODevice object to signal a readReady event?

Thanks,
Pierre.

[EDIT:] i think it will not help but anyway here is my .h for my subclass:

#ifndef QIOGpsReader_h
#define QIOGpsReader_h

#include <QIODevice>

class QIOGpsReader : public QIODevice {

Q_OBJECT

public:
QIOGpsReader (QString node, QObject *parent);
~QIOGpsReader (void);

protected:
qint64 readData (char*, qint64);
qint64 writeData (const char *data, qint64 maxSize);
qint64 bytesAvailable (void) const;
};

#endif

wysota
3rd December 2007, 18:20
QIODevice subclass has to have a way to poll the underlying device for new data, for example using a timer. It might help you if you take a look at Qt sources to see how some devices are implemented (for example QTcpSocket or QProcess).

hickscorp
3rd December 2007, 20:51
Thanks wysota,

i think i may have another problem. What i am exactly trying to do is to read in a FIFO (A special file created using mknod p).
My problem is that even when i am at the "end" of the stream for now, atEnd never returns 0, and my readLine loop never ends...

What i want is to read each 1 second on this file. i have tried with a timer, the problem is that each timer tick is starting the routine reading in the file, and EACH routine is stuck on the readAll loop =/

i have also tried with QSocketNotifier, but the simple fact of creating this object with a FOPEN handle makes the program stuck...

Any idea?
Pierre.

wysota
3rd December 2007, 20:59
What i want is to read each 1 second on this file. i have tried with a timer, the problem is that each timer tick is starting the routine reading in the file, and EACH routine is stuck on the readAll loop =/
Bad idea. You need a select() call on the FIFO to see if there is anything to read or ::open() with O_ASYNC passed as one of the flags. You only read when there is actually anything to read. Then you store it in an internal buffer and emit readyRead() to your user. And always return true for atEnd() because you are creating a sequential device which is always at end.

Here is an article to read: http://doc.trolltech.com/qq/qq12-iodevice.html

It's based on Qt3 but everything applies to Qt4 as well. And I suggest you take a look at QTcpSocket source code (or to be more exact the qnativesocketengine_unix.cpp file). You can copy most of its code to your class as FIFO acts exactly the same a a tcp socket (in fact FIFO is a socket in the UNIX domain).

You can even try using QTcpSocket directly just passing it your FIFO file descriptor.

hickscorp
3rd December 2007, 23:01
Sorry wysota i don't understand your example with select().
Do you mean, i have to go back to my implementation of QIODevice, and create an internal system for my QIOGpsReader which uses Async reads with select()?

Also i have tried using QTcpSocket with various methods but it didnt work. I'm not sure why, and since getting debug messages on my handdled platform is tricky i wont tell :)

Thanks for your time,
Pierre.

wysota
3rd December 2007, 23:32
Sorry wysota i don't understand your example with select().
Do you mean, i have to go back to my implementation of QIODevice, and create an internal system for my QIOGpsReader which uses Async reads with select()?
Yes, otherwise you'll block your whole application sooner or later. Of course you don't have to use select, but I think it's the most straightforward approach.


Also i have tried using QTcpSocket with various methods but it didnt work. I'm not sure why, and since getting debug messages on my handdled platform is tricky i wont tell :)
What did you try? Something like:

QTcpSocket socket;
socket.setSocketDescriptor(myFifo);
should have worked.