summaryrefslogtreecommitdiffstats
path: root/src/uscxml/URL.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/URL.h')
-rw-r--r--src/uscxml/URL.h246
1 files changed, 136 insertions, 110 deletions
diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h
index 9ff24c5..0858626 100644
--- a/src/uscxml/URL.h
+++ b/src/uscxml/URL.h
@@ -1,77 +1,106 @@
-#ifndef URL_H_27HPRH76
-#define URL_H_27HPRH76
+#ifndef URL_H_9DAEGSMV
+#define URL_H_9DAEGSMV
+#include <curl/curl.h>
#include <string>
+#include <iostream>
#include <sstream>
-#include <curl/curl.h>
+#include <map>
+#include <set>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "uscxml/concurrency/tinythread.h"
// use arabica URL parser
#include <io/uri.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
namespace uscxml {
+class URL;
+
+class URLMonitor {
+public:
+ virtual void downloadStarted(const URL& url) {};
+ virtual void downloadCompleted(const URL& url) {};
+ virtual void downloadFailed(const URL& url, int errorCode) {};
+ virtual void headerChunkReceived(const URL& url, const std::string& headerChunk) {};
+ virtual void contentChunkReceived(const URL& url, const std::string& contentChunk) {};
+};
+
class URLImpl : public boost::enable_shared_from_this<URLImpl> {
public:
- URLImpl() {}
- URLImpl(const std::string uri) : _uri(uri) {}
- virtual ~URLImpl();
- const bool toAbsoluteCwd();
+ URLImpl(const std::string& url);
+ ~URLImpl();
+ static boost::shared_ptr<URLImpl> toLocalFile(const std::string& content, const std::string& suffix);
+
+ static size_t writeHandler(void *ptr, size_t size, size_t nmemb, void *userdata);
+ static size_t headerHandler(void *ptr, size_t size, size_t nmemb, void *userdata);
+
+ void addMonitor(URLMonitor* monitor) { _monitors.insert(monitor); }
+ void removeMonitor(URLMonitor* monitor) { _monitors.erase(monitor); }
+
+ const bool isAbsolute() const { return _uri.is_absolute(); }
+ const std::string scheme() const { return _uri.scheme(); }
+ const std::string host() const { return _uri.host(); }
+ const std::string port() const { return _uri.port(); }
+ const std::string path() const { return _uri.path(); }
+ const std::string asString() const { return _uri.as_string(); }
+
+ const bool toAbsoluteCwd();
const bool toAbsolute(const std::string& baseUrl);
const std::string asLocalFile(const std::string& suffix, bool reload = false);
- static boost::shared_ptr<URLImpl> toLocalFile(const std::string& content, const std::string& suffix);
+ void addOutHeader(const std::string& key, const std::string& value) { _outHeader[key] = value; }
+ void setOutContent(const std::string& content);
+ void setRequestType(const std::string& requestType);
+
+ const std::map<std::string, std::string> getInHeaderFields();
+ const std::string getInContent(bool forceReload = false);
+ const void download(bool blocking = false);
+
+ void downloadStarted();
+ void downloadCompleted();
+ void downloadFailed(int errorCode);
- const bool isAbsolute() const {
- return _uri.is_absolute();
- }
- const std::string scheme() const {
- return _uri.scheme();
- }
- const std::string host() const {
- return _uri.host();
- }
- const std::string port() const {
- return _uri.port();
- }
- const std::string path() const {
- return _uri.path();
- }
- const std::string asString() const {
- return _uri.as_string();
- }
+ friend class URLFetcher;
-private:
+protected:
+ URLImpl() : _handle(NULL), _isDownloaded(false), _hasFailed(false) {}
std::string getLocalFilename(const std::string& suffix);
- Arabica::io::URI _uri;
- std::string _localFile;
+ std::string _outContent;
+ std::map<std::string, std::string> _outHeader;
+ std::string _requestType;
+
+ CURL* _handle;
+ std::stringstream _inContent;
+ std::stringstream _inHeader;
+
+ Arabica::io::URI _uri;
+ bool _isDownloaded;
+ bool _hasFailed;
+
+ std::string _localFile;
+
+ tthread::condition_variable _condVar;
+ tthread::recursive_mutex _mutex;
+
+ std::set<URLMonitor*> _monitors;
+ typedef std::set<URLMonitor*>::iterator monIter_t;
};
class URL {
-public:
+public:
URL() : _impl() {}
- URL(const std::string uri) : _impl(new URLImpl(uri)) {}
+ URL(const std::string url) : _impl(new URLImpl(url)) {}
URL(boost::shared_ptr<URLImpl> const impl) : _impl(impl) { }
URL(const URL& other) : _impl(other._impl) { }
virtual ~URL() {};
-
- static URL toLocalFile(const std::string& content, const std::string& suffix) {
- boost::shared_ptr<URLImpl> impl = URLImpl::toLocalFile(content, suffix);
- return URL(impl);
- }
-
- operator bool() const {
- return _impl;
- }
- bool operator< (const URL& other) const {
- return _impl < other._impl;
- }
- bool operator==(const URL& other) const {
- return _impl == other._impl;
- }
+
+ operator bool() const { return _impl; }
+ bool operator< (const URL& other) const { return _impl < other._impl; }
+ bool operator==(const URL& other) const { return _impl == other._impl; }
bool operator!=(const URL& other) const {
return _impl != other._impl;
}
@@ -80,75 +109,72 @@ public:
return *this;
}
- const bool toAbsoluteCwd() {
- return _impl->toAbsoluteCwd();
- }
- const bool toAbsolute(const std::string& baseUrl) {
- return _impl->toAbsolute(baseUrl);
- }
- const bool toAbsolute(const URL& baseUrl) {
- return _impl->toAbsolute(baseUrl.asString());
- }
- const std::string asLocalFile(const std::string& suffix, bool reload = false) {
- return _impl->asLocalFile(suffix, reload);
- }
-
- const bool isAbsolute() const {
- return _impl->isAbsolute();
- }
- const std::string scheme() const {
- return _impl->scheme();
- }
- const std::string host() const {
- return _impl->host();
- }
- const std::string port() const {
- return _impl->port();
- }
- const std::string path() const {
- return _impl->path();
- }
- const std::string asString() const {
- return _impl->asString();
- }
-
+ const std::map<std::string, std::string> getInHeaderFields() const { return _impl->getInHeaderFields(); }
+ const std::string getInContent() const { return _impl->getInContent(); }
+ const void download(bool blocking = false) const { return _impl->download(blocking); }
+
+ void addOutHeader(const std::string& key, const std::string& value) { _impl->addOutHeader(key, value); }
+ void setRequestType(const std::string& requestType) { _impl->setRequestType(requestType); }
+ void setOutContent(const std::string& content) { _impl->setOutContent(content); }
+
+ const bool toAbsoluteCwd() { return _impl->toAbsoluteCwd(); }
+ const bool toAbsolute(const std::string& baseUrl) { return _impl->toAbsolute(baseUrl); }
+ const bool toAbsolute(const URL& baseUrl) { return _impl->toAbsolute(baseUrl.asString()); }
+ const std::string asLocalFile(const std::string& suffix, bool reload = false) { return _impl->asLocalFile(suffix, reload); }
+
+ static URL toLocalFile(const std::string& content, const std::string& suffix) {
+ boost::shared_ptr<URLImpl> impl = URLImpl::toLocalFile(content, suffix);
+ return URL(impl);
+ }
+
+ void addMonitor(URLMonitor* monitor) { _impl->addMonitor(monitor); }
+ void removeMonitor(URLMonitor* monitor) { _impl->removeMonitor(monitor); }
+
+ const bool isAbsolute() const { return _impl->isAbsolute(); }
+ const std::string scheme() const { return _impl->scheme(); }
+ const std::string host() const { return _impl->host(); }
+ const std::string port() const { return _impl->port(); }
+ const std::string path() const { return _impl->path(); }
+ const std::string asString() const { return _impl->asString(); }
+
+ friend class URLFetcher;
friend std::ostream & operator<<(std::ostream &stream, const URL& p);
protected:
- boost::shared_ptr<URLImpl> _impl;
-};
-
-enum fcurl_type_e {
- CFTYPE_NONE=0,
- CFTYPE_FILE=1,
- CFTYPE_CURL=2
-};
+ void downloadStarted() { return _impl->downloadStarted(); }
+ void downloadCompleted() { return _impl->downloadCompleted(); }
+ void downloadFailed(int errorCode) { return _impl->downloadFailed(errorCode); }
-struct fcurl_data {
- enum fcurl_type_e type; /* type of handle */
- union {
- CURL *curl;
- FILE *file;
- } handle; /* handle */
-
- char *buffer; /* buffer to store cached data*/
- size_t buffer_len; /* currently allocated buffers length */
- size_t buffer_pos; /* end of data in buffer*/
- int still_running; /* Is background url fetch still in progress */
+ boost::shared_ptr<URLImpl> _impl;
};
-typedef struct fcurl_data URL_FILE;
+class URLFetcher {
+public:
+ URLFetcher();
+ ~URLFetcher();
+
+ static void fetchURL(URL& url);
+ static void breakURL(URL& url);
-URL_FILE *url_fopen(const char *url,const char *operation);
-int url_fclose(URL_FILE *file);
-int url_feof(URL_FILE *file);
-size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
-char * url_fgets(char *ptr, size_t size, URL_FILE *file);
-void url_rewind(URL_FILE *file);
+ void start();
+ void stop();
-std::ostream & operator<<(std::ostream &stream, const URL& url);
+protected:
+ static URLFetcher* _instance;
+ static URLFetcher* getInstance();
+
+ static void run(void* instance);
+ void perform();
+
+ tthread::thread* _thread;
+ tthread::condition_variable _condVar;
+ tthread::recursive_mutex _mutex;
+ bool _isStarted;
+
+ std::map<CURL*, URL> _handlesToURLs;
+ CURLM* _multiHandle;
+};
}
-
-#endif /* end of include guard: URL_H_27HPRH76 */
+#endif /* end of include guard: URL_H_9DAEGSMV */