root/libcore/LoadVariablesThread.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- completeLoad
- _canceled
- _canceled
- cancel
- cancelRequested
//
// 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
//
#include "LoadVariablesThread.h"
#include "IOChannel.h"
#include "log.h"
#include "GnashException.h"
#include "utf8.h"
#include <string>
#include <boost/scoped_array.hpp>
//#define DEBUG_LOAD_VARIABLES 1
namespace gnash {
void
LoadVariablesThread::completeLoad()
{
#ifdef DEBUG_LOAD_VARIABLES
log_debug("completeLoad called");
#endif
// TODO: how to set _bytesTotal ?
// this is going to override any previous setting,
// better do this inside a subclass (in a separate thread)
_bytesLoaded = 0;
_bytesTotal = _stream->size();
std::string toparse;
const size_t chunkSize = 1024;
boost::scoped_array<char> buf(new char[chunkSize]);
unsigned int parsedLines = 0;
// TODO: use read_string ?
while ( size_t bytesRead = _stream->read(buf.get(), chunkSize) )
{
#ifdef DEBUG_LOAD_VARIABLES
log_debug("Read %u bytes", bytesRead);
#endif
if ( _bytesLoaded )
{
std::string chunk(buf.get(), bytesRead);
toparse += chunk;
}
else
{
size_t dataSize = bytesRead;
utf8::TextEncoding encoding;
char* ptr = utf8::stripBOM(buf.get(), dataSize,
encoding);
if ( encoding != utf8::encUTF8 &&
encoding != utf8::encUNSPECIFIED )
{
log_unimpl("%s to utf8 conversion in "
"MovieClip.loadVariables "
"input parsing",
utf8::textEncodingName(encoding));
}
std::string chunk(ptr, dataSize);
toparse += chunk;
}
#ifdef DEBUG_LOAD_VARIABLES
log_debug("toparse: %s", toparse);
#endif
// parse remainder
size_t lastamp = toparse.rfind('&');
if ( lastamp != std::string::npos )
{
std::string parseable = toparse.substr(0, lastamp);
#ifdef DEBUG_LOAD_VARIABLES
log_debug("parseable: %s", parseable);
#endif
parse(parseable);
toparse = toparse.substr(lastamp+1);
#ifdef DEBUG_LOAD_VARIABLES
log_debug("toparse nextline: %s", toparse);
#endif
++parsedLines;
}
_bytesLoaded += bytesRead;
//dispatchDataEvent();
// eof, get out !
if ( _stream->eof() ) break;
if ( cancelRequested() )
{
log_debug("Cancelling LoadVariables download thread...");
_stream.reset();
return;
}
}
if ( ! toparse.empty() )
{
parse(toparse);
}
try {
_stream->go_to_end();
}
catch (IOException& ex) {
log_error("Stream couldn't seek to end: %s", ex.what());
}
_bytesLoaded = _stream->tell();
if ( _bytesTotal != _bytesLoaded )
{
log_error("Size of 'variables' stream advertised to be %d bytes,"
" but turned out to be %d bytes.",
_bytesTotal, _bytesLoaded);
_bytesTotal = _bytesLoaded;
}
_stream.reset(); // we don't need the IOChannel anymore
//dispatchLoadEvent();
setCompleted();
}
LoadVariablesThread::LoadVariablesThread(const StreamProvider& sp,
const URL& url, const std::string& postdata)
:
_stream(sp.getStream(url, postdata)),
_completed(false),
_canceled(false)
{
if ( ! _stream.get() )
{
throw NetworkException();
}
}
LoadVariablesThread::LoadVariablesThread(const StreamProvider& sp,
const URL& url)
:
_stream(sp.getStream(url)),
_completed(false),
_canceled(false)
{
if ( ! _stream.get() )
{
throw NetworkException();
}
}
void
LoadVariablesThread::cancel()
{
boost::mutex::scoped_lock lock(_mutex);
_canceled = true;
}
bool
LoadVariablesThread::cancelRequested()
{
boost::mutex::scoped_lock lock(_mutex);
return _canceled;
}
LoadVariablesThread::~LoadVariablesThread()
{
if ( _thread.get() )
{
cancel();
_thread->join();
_thread.reset();
}
}
} // namespace gnash