1

返信からカスタムバイトを返す独自のカスタム QNetworkReply クラスを作成しようとしています。私もオーバーロードした QNetworkAccessManager::createRequest() オーバーロードからそのクラスを返します。私の問題は、応答が「破損」しているため、関数のオーバーロードが呼び出されず、結果として QWebView の要求が失敗することです。Qt テスト ライブラリからインスピレーションを得ようとしましたが、うまくFakeReplyいきませんでした。

これが私のコードです:

class FakeReply : public QNetworkReply
{
    Q_OBJECT

public:
    FakeReply(const QNetworkRequest& request, QByteArray &data, QObject* parent = 0);
    ~FakeReply();
    QByteArray readAll();
    QByteArray read(qint64 maxSize);
    qint64 peek(char *buffer, qint64 maxlen);
    QByteArray peek(qint64 maxLen);
    qint64 size() const;
    virtual qint64 bytesAvailable() const;
    bool isFinished() const;
    virtual void abort();
    virtual void close();
    bool isSequential() const;
protected:
    qint64 readData(char*, qint64) override;
private:
    QByteArray data;
};

そして .cpp ファイル:

FakeReply::FakeReply(const QNetworkRequest &request, QByteArray &bytes, QObject *parent)
    : QNetworkReply(parent),
      data(bytes)
{
    setOperation(QNetworkAccessManager::GetOperation);
    setRequest(request);
    setUrl(request.url());
    open(QIODevice::ReadOnly);
    setFinished(true);
    emit finished();
}

FakeReply::~FakeReply()
{
    close();
}

QByteArray FakeReply::readAll()
{
    qDebug() << "FakeReply::readAll() got called!";
    size_t len = data.length();
    const char *bytes = static_cast<const char*>(data.data());
    char *buffer = static_cast<char*>(malloc(len));
    ASSERT(buffer != NULL, "run out of memory");
    memcpy(buffer, bytes, len);
    QByteArray output;
    output.setRawData(buffer, len);
    data = data.remove(0, len);
    return output;
}

QByteArray FakeReply::read(qint64 maxSize)
{
    qDebug() << "QByteArray FakeReply::read() got called!";
    static char* buffer = nullptr;
    if(bytesAvailable() == 0) {
        return QByteArray();
    }
    size_t len = computeMaxNumberOfBytes(maxSize);
    if(buffer != nullptr) {
        free(buffer);
    }
    buffer = static_cast<char*>(malloc(len));
    ASSERT(buffer != NULL, "run out of memory");
    memcpy(buffer, data.data(), len);
    data = data.remove(0, len);
    QByteArray output;
    output.setRawData(buffer, len);
    return output;
}

qint64 FakeReply::peek(char *buffer, qint64 maxlen)
{
    qDebug() << "FakeReply::peek() got called!";
    size_t len = computeMaxNumberOfBytes(maxlen);
    memcpy(buffer, data.data(), len);
    return static_cast<qint64>(len);
}

QByteArray FakeReply::peek(qint64 maxlen)
{
    qDebug() << "FakeReply::peek(qint64 maxlen) got called!";
    QByteArray output;
    output.setRawData(data.data(), computeMaxNumberOfBytes(maxlen));
    return output;
}

qint64 FakeReply::size() const
{
    return data.length();
}

qint64 FakeReply::bytesAvailable() const
{
    qDebug() << "FakeReply::bytesAvailable()";
    return data.length();
}

bool FakeReply::isFinished() const
{
    qDebug() << "FakeReply::isFinished() got called!";
    return true;
}

void FakeReply::abort()
{
    qDebug() << "FakeReply::abort() got called!";
}

void FakeReply::close()
{
    qDebug() << "FakeReply::close() got called!";
}

bool FakeReply::isSequential() const
{
    qDebug() << "FakeReply::isSequential() const got called!";
    return false;
}

qint64 FakeReply::readData(char *, qint64)
{
    qDebug() << "FakeReply::readData() got called!";
    return 0;
}

クラスは次のように使用されます。

QNetworkReply *MyNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
{
     QString path = request.url().path();
    QNetworkReply *reply = QNetworkAccessManager::createRequest(op, request, outgoingData);

     if(path == QStringLiteral("/testing")) {
         QByteArray response = waitThenReadAll(reply);
         return new FakeReply(request, response);
     }
     return reply;
   }
4

1 に答える 1