mirror of https://github.com/KLayout/klayout.git
HTTP access enhancments
Added the ability for asyn requests. Fixed a memory lead issue in WebDAV access.
This commit is contained in:
parent
ffb56335fb
commit
bf5f932ff1
|
|
@ -123,7 +123,7 @@ InputHttpStream::InputHttpStream (const std::string &url)
|
|||
|
||||
InputHttpStream::~InputHttpStream ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -166,6 +166,7 @@ InputHttpStream::finished (QNetworkReply *reply)
|
|||
issue_request (QUrl (redirect_target.toString ()));
|
||||
} else {
|
||||
mp_reply = reply;
|
||||
m_ready ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,6 +206,14 @@ InputHttpStream::issue_request (const QUrl &url)
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
InputHttpStream::send ()
|
||||
{
|
||||
if (mp_reply == 0) {
|
||||
issue_request (QUrl (tl::to_qstring (m_url)));
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
InputHttpStream::read (char *b, size_t n)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#define HDR_tlHttpStream
|
||||
|
||||
#include "tlStream.h"
|
||||
#include "tlEvents.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QBuffer>
|
||||
|
|
@ -84,6 +85,19 @@ public:
|
|||
*/
|
||||
virtual ~InputHttpStream ();
|
||||
|
||||
/**
|
||||
* @brief Sends the request for data
|
||||
* To ensure prompt delivery of data, this method can be used prior to
|
||||
* "read" to trigger the download from the given URL.
|
||||
* This method will return immediately. When the reply is available,
|
||||
* the "ready" event will be triggered. "read" can then be used to
|
||||
* read the data or - in case of an error - throw an exception.
|
||||
* If "send" is not used before "read", "read" will block until data
|
||||
* is available.
|
||||
* If a request has already been sent, this method will do nothing.
|
||||
*/
|
||||
void send ();
|
||||
|
||||
/**
|
||||
* @brief Sets the request verb
|
||||
* The default verb is "GET"
|
||||
|
|
@ -115,6 +129,23 @@ public:
|
|||
*/
|
||||
virtual size_t read (char *b, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Gets the "ready" event
|
||||
* Connect to this event for the asynchroneous interface.
|
||||
*/
|
||||
tl::Event &ready ()
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether data is available
|
||||
*/
|
||||
bool data_available ()
|
||||
{
|
||||
return mp_reply != 0;
|
||||
}
|
||||
|
||||
virtual void reset ();
|
||||
|
||||
virtual std::string source () const
|
||||
|
|
@ -140,6 +171,7 @@ private:
|
|||
QByteArray m_data;
|
||||
QBuffer *mp_buffer;
|
||||
std::map<std::string, std::string> m_headers;
|
||||
tl::Event m_ready;
|
||||
|
||||
void issue_request (const QUrl &url);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -311,6 +311,14 @@ InputStream::InputStream (InputStreamBase &delegate)
|
|||
mp_buffer = new char [m_bcap];
|
||||
}
|
||||
|
||||
InputStream::InputStream (InputStreamBase *delegate)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (delegate), m_owns_delegate (true), mp_inflate (0)
|
||||
{
|
||||
m_bcap = 4096; // initial buffer capacity
|
||||
m_blen = 0;
|
||||
mp_buffer = new char [m_bcap];
|
||||
}
|
||||
|
||||
InputStream::InputStream (const std::string &abstract_path)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (0), m_owns_delegate (false), mp_inflate (0)
|
||||
{
|
||||
|
|
@ -357,7 +365,15 @@ std::string InputStream::absolute_path (const std::string &abstract_path)
|
|||
InputStream::~InputStream ()
|
||||
{
|
||||
if (mp_delegate && m_owns_delegate) {
|
||||
delete mp_delegate;
|
||||
// NOTE: HTTP stream objects should not be deleted now, since events
|
||||
// may be pending that deliver the finished signal to the object.
|
||||
tl::InputHttpStream *http = dynamic_cast<tl::InputHttpStream *>(mp_delegate);
|
||||
if (http) {
|
||||
http->ready ().clear (); // avoids events from deleted streams
|
||||
http->deleteLater ();
|
||||
} else {
|
||||
delete mp_delegate;
|
||||
}
|
||||
mp_delegate = 0;
|
||||
}
|
||||
if (mp_inflate) {
|
||||
|
|
|
|||
|
|
@ -172,11 +172,16 @@ class TL_PUBLIC InputStream
|
|||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object.
|
||||
* This constructor takes a delegate object, but does not take ownership.
|
||||
*/
|
||||
InputStream (InputStreamBase &delegate);
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
* This constructor takes a delegate object, and takes ownership.
|
||||
*/
|
||||
InputStream (InputStreamBase *delegate);
|
||||
|
||||
/**
|
||||
* @brief Opens a stream from a abstract path
|
||||
*
|
||||
|
|
@ -305,6 +310,14 @@ public:
|
|||
* @brief Gets the absolute path for a given URL
|
||||
*/
|
||||
static std::string absolute_path (const std::string &path);
|
||||
|
||||
/**
|
||||
* @brief Gets the base reader (delegate)
|
||||
*/
|
||||
InputStreamBase *base ()
|
||||
{
|
||||
return mp_delegate;
|
||||
}
|
||||
|
||||
protected:
|
||||
void reset_pos ()
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ WebDAVObject::download_item (const std::string &url)
|
|||
tl::InputHttpStream *http = new tl::InputHttpStream (url);
|
||||
// This trick allows accessing GitHub repos through their SVN API
|
||||
http->add_header ("User-Agent", "SVN");
|
||||
return new tl::InputStream (*http);
|
||||
return new tl::InputStream (http);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include "tlHttpStream.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
static std::string test_url1 ("http://www.klayout.org/svn-public/klayout-resources/trunk/testdata/text");
|
||||
static std::string test_url2 ("http://www.klayout.org/svn-public/klayout-resources/trunk/testdata/dir1");
|
||||
|
||||
|
|
@ -73,3 +75,38 @@ TEST(2)
|
|||
"</D:multistatus>\n"
|
||||
);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class Receiver : public tl::Object
|
||||
{
|
||||
public:
|
||||
Receiver () : flag (false) { }
|
||||
void handle () { flag = true; }
|
||||
bool flag;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// async mode
|
||||
TEST(3)
|
||||
{
|
||||
tl::InputHttpStream stream (test_url1);
|
||||
|
||||
Receiver r;
|
||||
stream.ready ().add (&r, &Receiver::handle);
|
||||
|
||||
stream.send ();
|
||||
EXPECT_EQ (stream.data_available (), false);
|
||||
|
||||
while (! stream.data_available ()) {
|
||||
QCoreApplication::processEvents (QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
EXPECT_EQ (r.flag, true);
|
||||
|
||||
char b[100];
|
||||
size_t n = stream.read (b, sizeof (b));
|
||||
std::string res (b, n);
|
||||
EXPECT_EQ (res, "hello, world.\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue