Дневник Шестеро Михаила - Шифровка потока информации PHP-HTTP-Qt. Часть 2

Apr. 21st, 2014

12:00 am - Шифровка потока информации PHP-HTTP-Qt. Часть 2

Previous Entry Add to Memories Tell A Friend Next Entry

...Это продолжение, начало см. Часть 1!

Decrypter-объект m_decrypter логически "вставляется" между входным потоком QNetworkReply и приёмником QxmlInputSource :

    connect(m_pManager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(onFinish(QNetworkReply*)));

…
    m_reader = new QXmlSimpleReader;
    // connect QXmlSimpleReader to handlers
    m_reader->setContentHandler(this);
    m_reader->setErrorHandler(this);

    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    m_first = true;
    m_timestart.start(); // = QTime::currentTime();
    m_timestop  = QTime();
    m_reply = m_pManager->post( request, postData().encodedQuery() );
    qDebug() << "Got new m_reply=" << m_reply;
    //m_reply->setReadBufferSize(16*1024);

    m_decrypter = new Decrypter(m_reply, m_pSettings);
    m_xmlsource = new QxmlInputSource(m_decrypter); // [**]

    connect(m_reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()) );
    connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)),
            this,  SLOT(onDownloadProgress(qint64, qint64)));
К сожалению, мне не удалось добиться того, что бы Decryptor работал в точности также как объект QNetworkReply; возможно причина в том, что он выдаёт информацию только 16-байтовыми порциями и не может в конце правильно оценить размер, но в handler-е SAX-парсера не запускался endDocument();
Мне удалось тем не менее заставить это работать как надо дополнительно «стимулируя» Decryptor в обработчиках сигналов readyRead() и downloadProgress(qint64, qint64)
(если не использовать шифрование и класть m_reply вместо m_decrypter в QxmlInputSource() это не требуется:

void WorkplaceTab::onReadyRead()
{
    if ( m_reader==NULL || m_xmlsource==NULL )
    {
        qDebug() << "WorkplaceTab::onReadyRead() - warning";
        return;
    }

    if (m_first)
    {
        // выполняется один раз - при приёме превой порции данных
        qDebug() << "m_reader->parse(m_xmlsource, true);";
        if (!m_reader->parse(m_xmlsource, true))
            to_idle_state(); // прекращение режима приёма
        m_first = false;
    }

    long watchdog = 100;
    while ( m_decrypter!=NULL && m_decrypter->bytesAvailable()>0 )
    {
        m_xmlsource->fetchData();
        if (!m_reader->parseContinue())
            to_idle_state();    // прекращение режима приёма

        if (watchdog--<0)
            break;
    }
}

void WorkplaceTab::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    logmessage( tr("%1 bytes and %2 rows loaded").arg(bytesReceived).arg(m_row) );

    if (bytesReceived==bytesTotal)
    {
        // выполняется один раз - после приёма последней порции данных
        qDebug() << "WorkplaceTab::onDownloadProgress LAST TIME";
        if (m_reader==NULL || m_xmlsource==NULL || m_reply==NULL)
        {
            qDebug() << "Warning: m_reader==NULL or m_xmlsource==NULL or m_reply==NULL!";
            return;
        }

        long watchdog=1000000;
        bool b=true;
        while (b && m_xmlsource->data().length()>0 &&--watchdog)
            b = m_reader->parseContinue();

        if (b)
        {
            m_xmlsource->next();        // и ещё раз - вхолостую -
            m_reader->parseContinue();  // что бы вызвалось QXmlInputSource::EndOfDocument
        }
        /*
        if (m_row<=0) // TODO: проверка что QXmlInputSource::EndOfDocument не отработал
            to_idle_state(); // грубая остановка
        */
    }
}

// ?? иногда вызывается до завершения разборки XML! :-O
void WorkplaceTab::onFinish(QNetworkReply *reply)
{
    qDebug() << "WorkplaceTab::onFinish";

    m_timestop.start(); // = QTime::currentTime();

    bool anew = false;

    // отсоединяем обработчики onReadyRead и onDownloadProgress
    //reply->disconnect();
    disconnect(reply, SIGNAL(readyRead()), this, SLOT(onReadyRead()) );
    disconnect(reply, SIGNAL(downloadProgress(qint64, qint64)),
            this,  SLOT(onDownloadProgress(qint64, qint64)));
....
Может кто-то поможет с этим окончательно разобраться?
На этом на сегодя всё... вот так … :-)
Надеюсь вам было интересно!(?)

Tags: , , , , , , ,
Current Mood: [mood icon] satisfied