QIODevice の API で FIFO をお手軽に実現する

Qt で低レベルなデータの読み書きをする場合、QFileQTcpSocket など QIODevice の派生クラスを使う事が多いですよね。

read, write, pos, size, bytesAvailable, readyRead と、QIODevice の API はとても便利なのですが、残念ながらこの API で FIFO 的に動作するクラスは Qt にはありません。

これは、QIODevice::pos() などの API が読み書き両方に(別々に/同時に)対応するのが難しいからだと推測されます。

というわけで、基本的には難しいのですが、QByteArray をバッファとする QBuffer というクラスを少し工夫して使うことでこれを実現する方法を思いついたのでメモしておきます。

#include <QtCore>

int main(int argc, char **argv) {
    QCoreApplication app(argc, argv);
    QByteArray sharedData;
    QBuffer reader(&sharedData);
    QBuffer writer(&sharedData);
    QObject::connect(&writer, &QBuffer::readyRead, &reader, &QBuffer::readyRead);
    reader.open(QBuffer::ReadOnly);
    writer.open(QBuffer::WriteOnly);

    QObject::connect(&reader, &QBuffer::readyRead, [&]() {
        qDebug() << reader.readAll();
        reader.close();
        writer.close();
        app.quit();
    });

    writer.write(QByteArrayLiteral("Hello Qt!"));

    app.exec();
}

1つの QByteArray を2つの QBuffer で共有して必要なシグナルを転送しています。

色々やろうとするともう少しめんどくさいのですが、これだけでも十分便利というケースはあるんじゃないでしょうか?