...Это продолжение, начало см. Часть 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();
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))); ....Может кто-то поможет с этим окончательно разобраться?