Skip to content

Commit

Permalink
New class QgsNetworkReplyContent
Browse files Browse the repository at this point in the history
Encapsulates a network reply within a container which
is inexpensive to copy and safe to pass around between threads.
The default Qt QNetworkReply class is a QObject, which prevents
it from being copied and passed between threads. This class
grabs all the useful information from a QNetworkReply,
allowing the reply's content to be stored indefinetly without
concern for the lifetime of the QNetworkReply object itself.
  • Loading branch information
nyalldawson committed Dec 20, 2018
1 parent a2b5008 commit e4959a6
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 0 deletions.
103 changes: 103 additions & 0 deletions python/core/auto_generated/qgsnetworkreply.sip.in
@@ -0,0 +1,103 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsnetworkreply.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsNetworkReplyContent
{
%Docstring
Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between threads.

.. versionadded:: 3.6
%End

%TypeHeaderCode
#include "qgsnetworkreply.h"
%End
public:

QgsNetworkReplyContent();
%Docstring
Default constructor for an empty reply.
%End

explicit QgsNetworkReplyContent( QNetworkReply *reply );
%Docstring
Constructor for QgsNetworkReplyContent, populated from the specified ``reply``.
%End

void clear();
%Docstring
Clears the reply, resetting it back to a default, empty reply.
%End

QByteArray content() const;
%Docstring
Returns the raw reply content.
%End

QNetworkReply::NetworkError error() const;
%Docstring
Returns the reply's error message, or QNetworkReply.NoError if no
error was encountered.

.. seealso:: :py:func:`errorString`
%End

QString errorString() const;
%Docstring
Returns the error text for the reply, or an empty string if no
error was encountered.

.. seealso:: :py:func:`error`
%End


bool hasRawHeader( const QByteArray &headerName ) const;
%Docstring
Returns true if the reply contains a header with the specified ``headerName``.

.. seealso:: :py:func:`rawHeaderPairs`

.. seealso:: :py:func:`rawHeaderList`

.. seealso:: :py:func:`rawHeader`
%End

QList<QByteArray> rawHeaderList() const;
%Docstring
Returns a list of raw header names contained within the reply.

.. seealso:: :py:func:`rawHeaderPairs`

.. seealso:: :py:func:`hasRawHeader`

.. seealso:: :py:func:`rawHeader`
%End

QByteArray rawHeader( const QByteArray &headerName ) const;
%Docstring
Returns the content of the header with the specified ``headerName``, or an
empty QByteArray if the specified header was not found in the reply.

.. seealso:: :py:func:`rawHeaderPairs`

.. seealso:: :py:func:`hasRawHeader`

.. seealso:: :py:func:`rawHeaderList`
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsnetworkreply.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -80,6 +80,7 @@
%Include auto_generated/qgsmargins.sip
%Include auto_generated/qgsmimedatautils.sip
%Include auto_generated/qgsmultirenderchecker.sip
%Include auto_generated/qgsnetworkreply.sip
%Include auto_generated/qgsobjectcustomproperties.sip
%Include auto_generated/qgsogcutils.sip
%Include auto_generated/qgsoptional.sip
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -257,6 +257,7 @@ SET(QGIS_CORE_SRCS
qgsnetworkcontentfetcher.cpp
qgsnetworkcontentfetcherregistry.cpp
qgsnetworkcontentfetchertask.cpp
qgsnetworkreply.cpp
qgsnetworkreplyparser.cpp
qgsobjectcustomproperties.cpp
qgsofflineediting.cpp
Expand Down Expand Up @@ -908,6 +909,7 @@ SET(QGIS_CORE_HDRS
qgsmargins.h
qgsmimedatautils.h
qgsmultirenderchecker.h
qgsnetworkreply.h
qgsobjectcustomproperties.h
qgsogcutils.h
qgsoptional.h
Expand Down
60 changes: 60 additions & 0 deletions src/core/qgsnetworkreply.cpp
@@ -0,0 +1,60 @@
/***************************************************************************
qgsnetworkreply.cpp
-------------------
begin : November 2018
copyright : (C) 2018 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsnetworkreply.h"
#include <QNetworkReply>

QgsNetworkReplyContent::QgsNetworkReplyContent( QNetworkReply *reply )
: mContent( reply->readAll() )
, mError( reply->error() )
, mErrorString( reply->errorString() )
, mRawHeaderPairs( reply->rawHeaderPairs() )
{}

void QgsNetworkReplyContent::clear()
{
*this = QgsNetworkReplyContent();
}

bool QgsNetworkReplyContent::hasRawHeader( const QByteArray &headerName ) const
{
for ( auto &header : mRawHeaderPairs )
{
if ( header.first == headerName )
return true;
}
return false;
}

QList<QByteArray> QgsNetworkReplyContent::rawHeaderList() const
{
QList< QByteArray > res;
res.reserve( mRawHeaderPairs.length() );
for ( auto &header : mRawHeaderPairs )
{
res << header.first;
}
return res;
}

QByteArray QgsNetworkReplyContent::rawHeader( const QByteArray &headerName ) const
{
for ( auto &header : mRawHeaderPairs )
{
if ( header.first == headerName )
return header.second;
}
return QByteArray();
}
125 changes: 125 additions & 0 deletions src/core/qgsnetworkreply.h
@@ -0,0 +1,125 @@
/***************************************************************************
qgsnetworkreply.h
-----------------
begin : November 2018
copyright : (C) 2018 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSNETWORKREPLY_H
#define QGSNETWORKREPLY_H

#include "qgis_core.h"

#include <QNetworkReply>

/**
* Encapsulates a network reply within a container which is inexpensive to copy and safe to pass between threads.
* \ingroup core
* \since QGIS 3.6
*/
class CORE_EXPORT QgsNetworkReplyContent
{
public:

/**
* Default constructor for an empty reply.
*/
QgsNetworkReplyContent() = default;

/**
* Constructor for QgsNetworkReplyContent, populated from the specified \a reply.
*/
explicit QgsNetworkReplyContent( QNetworkReply *reply );

/**
* Clears the reply, resetting it back to a default, empty reply.
*/
void clear();

/**
* Returns the raw reply content.
*/
QByteArray content() const
{
return mContent;
}

/**
* Returns the reply's error message, or QNetworkReply::NoError if no
* error was encountered.
*
* \see errorString()
*/
QNetworkReply::NetworkError error() const
{
return mError;
}

/**
* Returns the error text for the reply, or an empty string if no
* error was encountered.
*
* \see error()
*/
QString errorString() const
{
return mErrorString;
}

#ifndef SIP_RUN
typedef QPair<QByteArray, QByteArray> RawHeaderPair;

/**
* Returns the list of raw header pairs in the reply.
* \see hasRawHeader()
* \see rawHeaderList()
* \see rawHeader()
* \note Not available in Python bindings
*/
const QList<RawHeaderPair> &rawHeaderPairs() const
{
return mRawHeaderPairs;
}
#endif

/**
* Returns true if the reply contains a header with the specified \a headerName.
* \see rawHeaderPairs()
* \see rawHeaderList()
* \see rawHeader()
*/
bool hasRawHeader( const QByteArray &headerName ) const;

/**
* Returns a list of raw header names contained within the reply.
* \see rawHeaderPairs()
* \see hasRawHeader()
* \see rawHeader()
*/
QList<QByteArray> rawHeaderList() const;

/**
* Returns the content of the header with the specified \a headerName, or an
* empty QByteArray if the specified header was not found in the reply.
* \see rawHeaderPairs()
* \see hasRawHeader()
* \see rawHeaderList()
*/
QByteArray rawHeader( const QByteArray &headerName ) const;

private:

QByteArray mContent;
QNetworkReply::NetworkError mError = QNetworkReply::NoError;
QString mErrorString;
QList<RawHeaderPair> mRawHeaderPairs;
};

#endif // QGSNETWORKREPLY_H

0 comments on commit e4959a6

Please sign in to comment.