root/libcore/LoadVariablesThread.h
/* [<][>][^][v][top][bottom][index][help] */
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
// 2011 Free Software Foundation, Inc
//
// 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 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
#ifndef GNASH_LOADVARIABLESTHREAD_H
#define GNASH_LOADVARIABLESTHREAD_H
#include "StreamProvider.h" // for inlines
#include "URL.h" // for inlines
#include <string>
#include <map>
#include <memory>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
// Forward declarations
namespace gnash {
//class URL;
}
namespace gnash {
// Exception thrown by LoadVariablesThread constructor if unable to connect
// to the stream input.
class NetworkException {};
/// A manager for loadVariable requests
//
/// Provides services for starting a "load and parse" thread, checking
/// its status and getting a parsed variables structure back when done.
///
class LoadVariablesThread
{
public:
typedef std::map<std::string, std::string> ValuesMap;
/// Construct a LoadVariablesThread opening a stream for the given URL
//
/// Throws a NetworkException if unable.
///
/// @param url
/// URL to post to and fetch from
///
LoadVariablesThread(const StreamProvider& sp, const URL& url);
/// \brief
/// Construct a LoadVariablesThread opening a stream for the given URL,
/// posting the given url-encoded data if using HTTP.
//
/// Throws a NetworkException if unable.
///
/// @param url
/// URL to post to and fetch from
///
/// @param postdata
/// Url-encoded post data.
///
LoadVariablesThread(const StreamProvider& sp, const URL& url,
const std::string& postdata);
/// Destroy the LoadVariablesThread, joining the thread if spawned
~LoadVariablesThread();
/// Return the name,value map parsed out of the loaded stream
ValuesMap& getValues()
{
return _vals;
}
/// Start the load and parse thread
void process()
{
assert(!_thread.get());
assert(_stream.get());
_thread.reset(new boost::thread(
boost::bind(LoadVariablesThread::execLoadingThread, this)));
}
/// Cancel a download in progress
//
/// Locks _mutex
///
void cancel();
/// Return true if loading/parsing is in progress
bool inProgress()
{
// TODO: should we mutex-protect this ?
return ( _thread.get() != NULL );
}
/// Mutex-protected inspector for thread completion
//
/// Only call this method from the same thread that
/// also called process(), as the thread will be joined
/// if it completed.
///
bool completed()
{
boost::mutex::scoped_lock lock(_mutex);
if ( _completed && _thread.get() )
{
_thread->join();
_thread.reset();
}
return _completed;
}
size_t getBytesLoaded() const
{
// TODO: should we mutex-protect this ?
return _bytesLoaded;
}
size_t getBytesTotal() const
{
// TODO: should we mutex-protect this ?
return _bytesTotal;
}
private:
/// Prevent copy
LoadVariablesThread& operator==(const LoadVariablesThread&);
LoadVariablesThread(const LoadVariablesThread&);
/// Since I haven't found a way to pass boost::thread
/// constructor a non-static function, this is here to
/// workaround that limitation (in either boost or more
/// likely my own knowledge of it)
static void execLoadingThread(LoadVariablesThread* ptr)
{
//log_debug("LoadVars loading thread started");
ptr->completeLoad();
//log_debug("LoadVars loading thread completed");
}
/// Mutex-protected mutator for thread completion
void setCompleted()
{
boost::mutex::scoped_lock lock(_mutex);
_completed = true;
//log_debug("Completed");
}
/// Load all data from the _stream input.
//
/// This function should be run by a separate thread.
///
void completeLoad();
/// Parse an url-encoded query string
//
/// Variables in the string will be added as properties
/// of this object.
///
/// @param querystring
/// An url-encoded query string.
/// The string will be parsed using URL::parse_querystring
///
/// @return the number of variables found in the string
///
size_t parse(const std::string& str)
{
URL::parse_querystring(str, _vals);
return _vals.size();
}
/// Check if download cancel was requested
//
/// Locks _mutex
///
bool cancelRequested();
size_t _bytesLoaded;
size_t _bytesTotal;
std::auto_ptr<IOChannel> _stream;
std::auto_ptr<boost::thread> _thread;
ValuesMap _vals;
bool _completed;
bool _canceled;
boost::mutex _mutex;
};
} // namespace gnash
#endif // GNASH_LOADVARIABLESTHREAD_H