mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
further fixes for npapi under unicode directories
This commit is contained in:
parent
c3936305e4
commit
cbc1842899
@ -18,7 +18,6 @@
|
|||||||
#include "ppBrowserObject.h"
|
#include "ppBrowserObject.h"
|
||||||
#include "startup.h"
|
#include "startup.h"
|
||||||
#include "p3d_plugin_config.h"
|
#include "p3d_plugin_config.h"
|
||||||
#include "find_root_dir.h"
|
|
||||||
#include "mkdir_complete.h"
|
#include "mkdir_complete.h"
|
||||||
#include "parse_color.h"
|
#include "parse_color.h"
|
||||||
#include "nppanda3d_common.h"
|
#include "nppanda3d_common.h"
|
||||||
@ -97,10 +96,6 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16_t mode,
|
|||||||
_root_dir = global_root_dir;
|
_root_dir = global_root_dir;
|
||||||
|
|
||||||
_got_instance_url = false;
|
_got_instance_url = false;
|
||||||
_opened_p3d_temp_file = false;
|
|
||||||
_finished_p3d_temp_file = false;
|
|
||||||
_p3d_temp_file_current_size = 0;
|
|
||||||
_p3d_temp_file_total_size = 0;
|
|
||||||
_p3d_instance_id = 0;
|
_p3d_instance_id = 0;
|
||||||
|
|
||||||
// fgcolor and bgcolor are useful to know here (in case we have to
|
// fgcolor and bgcolor are useful to know here (in case we have to
|
||||||
@ -216,12 +211,6 @@ PPInstance::
|
|||||||
browser->releaseobject(_script_object);
|
browser->releaseobject(_script_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_p3d_temp_filename.empty()) {
|
|
||||||
_p3d_temp_file.close();
|
|
||||||
unlink(_p3d_temp_filename.c_str());
|
|
||||||
_p3d_temp_filename.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the tokens we allocated.
|
// Free the tokens we allocated.
|
||||||
Tokens::iterator ti;
|
Tokens::iterator ti;
|
||||||
for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) {
|
for (ti = _tokens.begin(); ti != _tokens.end(); ++ti) {
|
||||||
@ -412,16 +401,17 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16_t *stype) {
|
|||||||
PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
|
PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
|
||||||
switch (req->_rtype) {
|
switch (req->_rtype) {
|
||||||
case PPDownloadRequest::RT_contents_file:
|
case PPDownloadRequest::RT_contents_file:
|
||||||
// This is the initial contents.xml file. We'll just download
|
// This is the initial contents.xml file. We used to download
|
||||||
// this directly to a file, since it is small and this is easy.
|
// this via NP_ASFILEONLY, but that option doesn't work on Windows
|
||||||
*stype = NP_ASFILEONLY;
|
// within a Unicode user directory. So we use NP_NORMAL instead.
|
||||||
|
*stype = NP_NORMAL;
|
||||||
_streams.push_back(stream);
|
_streams.push_back(stream);
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_core_dll:
|
case PPDownloadRequest::RT_core_dll:
|
||||||
// This is the core API DLL (or dylib or whatever). We want to
|
// This is the core API DLL (or dylib or whatever). Again, we
|
||||||
// download this to file for convenience.
|
// have to use NP_NORMAL.
|
||||||
*stype = NP_ASFILEONLY;
|
*stype = NP_NORMAL;
|
||||||
_streams.push_back(stream);
|
_streams.push_back(stream);
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
|
|
||||||
@ -510,8 +500,8 @@ write_stream(NPStream *stream, int offset, int len, void *buffer) {
|
|||||||
switch (req->_rtype) {
|
switch (req->_rtype) {
|
||||||
case PPDownloadRequest::RT_user:
|
case PPDownloadRequest::RT_user:
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
||||||
P3D_RC_in_progress, 0,
|
P3D_RC_in_progress, 0,
|
||||||
stream->end, buffer, len);
|
stream->end, buffer, len);
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_instance_data:
|
case PPDownloadRequest::RT_instance_data:
|
||||||
@ -533,27 +523,36 @@ write_stream(NPStream *stream, int offset, int len, void *buffer) {
|
|||||||
// temporary file until the instance is ready for it.
|
// temporary file until the instance is ready for it.
|
||||||
if (_p3d_inst == NULL) {
|
if (_p3d_inst == NULL) {
|
||||||
// The instance isn't ready, so stuff it in a temporary file.
|
// The instance isn't ready, so stuff it in a temporary file.
|
||||||
if (!_opened_p3d_temp_file) {
|
if (!_p3d_temp_file.feed(stream->end, buffer, len)) {
|
||||||
open_p3d_temp_file();
|
set_failed();
|
||||||
}
|
}
|
||||||
_p3d_temp_file.write((const char *)buffer, len);
|
|
||||||
_p3d_temp_file_current_size += len;
|
|
||||||
_p3d_temp_file_total_size = stream->end;
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// The instance has been created. Redirect the stream into the
|
// The instance has been created. Redirect the stream into the
|
||||||
// instance.
|
// instance.
|
||||||
assert(!_opened_p3d_temp_file);
|
assert(!_p3d_temp_file._opened);
|
||||||
req->_rtype = PPDownloadRequest::RT_user;
|
req->_rtype = PPDownloadRequest::RT_user;
|
||||||
req->_user_id = _p3d_instance_id;
|
req->_user_id = _p3d_instance_id;
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
||||||
P3D_RC_in_progress, 0,
|
P3D_RC_in_progress, 0,
|
||||||
stream->end, buffer, len);
|
stream->end, buffer, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PPDownloadRequest::RT_contents_file:
|
||||||
|
if (!_contents_temp_file.feed(stream->end, buffer, len)) {
|
||||||
|
set_failed();
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
|
||||||
|
case PPDownloadRequest::RT_core_dll:
|
||||||
|
if (!_core_dll_temp_file.feed(stream->end, buffer, len)) {
|
||||||
|
set_failed();
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
nout << "Unexpected write_stream on " << stream->url << "\n";
|
nout << "Unexpected write_stream on " << stream->url << "\n";
|
||||||
break;
|
break;
|
||||||
@ -595,38 +594,51 @@ destroy_stream(NPStream *stream, NPReason reason) {
|
|||||||
|
|
||||||
switch (req->_rtype) {
|
switch (req->_rtype) {
|
||||||
case PPDownloadRequest::RT_user:
|
case PPDownloadRequest::RT_user:
|
||||||
{
|
if (!req->_notified_done) {
|
||||||
assert(!req->_notified_done);
|
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
||||||
result_code, 0, stream->end, NULL, 0);
|
result_code, 0, stream->end, NULL, 0);
|
||||||
req->_notified_done = true;
|
req->_notified_done = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_instance_data:
|
case PPDownloadRequest::RT_instance_data:
|
||||||
if (_p3d_inst == NULL) {
|
if (!req->_notified_done) {
|
||||||
// The instance still isn't ready; just mark the data done.
|
if (_p3d_inst == NULL) {
|
||||||
// We'll send the entire file to the instance when it is ready.
|
// The instance still isn't ready; just mark the data done.
|
||||||
_finished_p3d_temp_file = true;
|
// We'll send the entire file to the instance when it is ready.
|
||||||
_p3d_temp_file_total_size = _p3d_temp_file_current_size;
|
_p3d_temp_file.finish();
|
||||||
|
if (result_code != P3D_RC_done) {
|
||||||
|
set_failed();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// The instance has (only just) been created. Tell it we've
|
||||||
|
// sent it all the data it will get.
|
||||||
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, _p3d_instance_id,
|
||||||
|
result_code, 0, stream->end, NULL, 0);
|
||||||
|
}
|
||||||
|
req->_notified_done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPDownloadRequest::RT_contents_file:
|
||||||
|
if (!req->_notified_done) {
|
||||||
|
_contents_temp_file.finish();
|
||||||
if (result_code != P3D_RC_done) {
|
if (result_code != P3D_RC_done) {
|
||||||
set_failed();
|
set_failed();
|
||||||
}
|
}
|
||||||
|
req->_notified_done = true;
|
||||||
} else {
|
|
||||||
// The instance has (only just) been created. Tell it we've
|
|
||||||
// sent it all the data it will get.
|
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, _p3d_instance_id,
|
|
||||||
result_code, 0, stream->end, NULL, 0);
|
|
||||||
}
|
}
|
||||||
assert(!req->_notified_done);
|
|
||||||
req->_notified_done = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_core_dll:
|
case PPDownloadRequest::RT_core_dll:
|
||||||
case PPDownloadRequest::RT_contents_file:
|
if (!req->_notified_done) {
|
||||||
// These are received as a full-file only, so we don't care about
|
_core_dll_temp_file.finish();
|
||||||
// the destroy_stream notification.
|
if (result_code != P3D_RC_done) {
|
||||||
|
set_failed();
|
||||||
|
}
|
||||||
|
req->_notified_done = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -668,13 +680,15 @@ url_notify(const char *url, NPReason reason, void *notifyData) {
|
|||||||
assert(reason != NPRES_DONE);
|
assert(reason != NPRES_DONE);
|
||||||
|
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, req->_user_id,
|
||||||
P3D_RC_generic_error, 0, 0, NULL, 0);
|
P3D_RC_generic_error, 0, 0, NULL, 0);
|
||||||
req->_notified_done = true;
|
req->_notified_done = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_contents_file:
|
case PPDownloadRequest::RT_contents_file:
|
||||||
if (reason != NPRES_DONE) {
|
if (reason == NPRES_DONE) {
|
||||||
|
downloaded_contents_file(_contents_temp_file._filename);
|
||||||
|
} else {
|
||||||
nout << "Failure downloading " << url << "\n";
|
nout << "Failure downloading " << url << "\n";
|
||||||
|
|
||||||
if (reason == NPRES_USER_BREAK) {
|
if (reason == NPRES_USER_BREAK) {
|
||||||
@ -695,7 +709,10 @@ url_notify(const char *url, NPReason reason, void *notifyData) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_core_dll:
|
case PPDownloadRequest::RT_core_dll:
|
||||||
if (reason != NPRES_DONE) {
|
if (reason == NPRES_DONE) {
|
||||||
|
downloaded_plugin(_core_dll_temp_file._filename);
|
||||||
|
|
||||||
|
} else {
|
||||||
nout << "Failure downloading " << url << "\n";
|
nout << "Failure downloading " << url << "\n";
|
||||||
|
|
||||||
if (reason == NPRES_USER_BREAK) {
|
if (reason == NPRES_USER_BREAK) {
|
||||||
@ -1269,6 +1286,38 @@ start_download(const string &url, PPDownloadRequest *req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::downloaded_contents_file
|
||||||
|
// Access: Private
|
||||||
|
// Description: The contents.xml file has been successfully downloaded;
|
||||||
|
// copy it into place.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::
|
||||||
|
downloaded_contents_file(const string &filename) {
|
||||||
|
// Now we have the contents.xml file. Read this to get the
|
||||||
|
// filename and md5 hash of our core API DLL.
|
||||||
|
if (read_contents_file(filename, true)) {
|
||||||
|
// Successfully downloaded and read, and it has been written
|
||||||
|
// into its normal place.
|
||||||
|
get_core_api();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Error reading the contents.xml file, or in loading the core
|
||||||
|
// API that it references.
|
||||||
|
nout << "Unable to read contents file " << filename << "\n";
|
||||||
|
|
||||||
|
// If there's an outstanding contents.xml file on disk, try to
|
||||||
|
// load that one as a fallback.
|
||||||
|
string contents_filename = _root_dir + "/contents.xml";
|
||||||
|
if (read_contents_file(contents_filename, false)) {
|
||||||
|
get_core_api();
|
||||||
|
} else {
|
||||||
|
nout << "Unable to read contents file " << contents_filename << "\n";
|
||||||
|
set_failed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PPInstance::read_contents_file
|
// Function: PPInstance::read_contents_file
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1428,32 +1477,14 @@ get_filename_from_url(const string &url) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PPInstance::
|
void PPInstance::
|
||||||
downloaded_file(PPDownloadRequest *req, const string &filename) {
|
downloaded_file(PPDownloadRequest *req, const string &filename) {
|
||||||
|
// Since we're no longer using NP_ASFILEONLY, none of these URL
|
||||||
|
// requests will normally come through this codepath (they'll go
|
||||||
|
// through url_notify() above, instead), unless we short-circuited
|
||||||
|
// the browser by "downloading" a file:// url.
|
||||||
switch (req->_rtype) {
|
switch (req->_rtype) {
|
||||||
case PPDownloadRequest::RT_contents_file:
|
case PPDownloadRequest::RT_contents_file:
|
||||||
{
|
// The contents.xml file that gets things going.
|
||||||
// Now we have the contents.xml file. Read this to get the
|
downloaded_contents_file(filename);
|
||||||
// filename and md5 hash of our core API DLL.
|
|
||||||
if (read_contents_file(filename, true)) {
|
|
||||||
// Successfully downloaded and read, and it has been written
|
|
||||||
// into its normal place.
|
|
||||||
get_core_api();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Error reading the contents.xml file, or in loading the core
|
|
||||||
// API that it references.
|
|
||||||
nout << "Unable to read contents file " << filename << "\n";
|
|
||||||
|
|
||||||
// If there's an outstanding contents.xml file on disk, try to
|
|
||||||
// load that one as a fallback.
|
|
||||||
string contents_filename = _root_dir + "/contents.xml";
|
|
||||||
if (read_contents_file(contents_filename, false)) {
|
|
||||||
get_core_api();
|
|
||||||
} else {
|
|
||||||
nout << "Unable to read contents file " << contents_filename << "\n";
|
|
||||||
set_failed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_core_dll:
|
case PPDownloadRequest::RT_core_dll:
|
||||||
@ -1463,9 +1494,8 @@ downloaded_file(PPDownloadRequest *req, const string &filename) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PPDownloadRequest::RT_user:
|
case PPDownloadRequest::RT_user:
|
||||||
// Normally, RT_user requests won't come here, unless we
|
// Here's the user-requested file. It needs to be streamed to the
|
||||||
// short-circuited the browser by "downloading" a file:// url. In
|
// user, so we'll open the file and feed it to the user.
|
||||||
// any case, we'll now open the file and feed it to the user.
|
|
||||||
feed_file(req, filename);
|
feed_file(req, filename);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1487,35 +1517,6 @@ feed_file(PPDownloadRequest *req, const string &filename) {
|
|||||||
_file_datas.push_back(file_data);
|
_file_datas.push_back(file_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PPInstance::open_p3d_temp_file
|
|
||||||
// Access: Private
|
|
||||||
// Description: Creates a temporary file into which the p3d file data
|
|
||||||
// is stored before the instance has been created.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PPInstance::
|
|
||||||
open_p3d_temp_file() {
|
|
||||||
assert(!_opened_p3d_temp_file);
|
|
||||||
_opened_p3d_temp_file = true;
|
|
||||||
_finished_p3d_temp_file = false;
|
|
||||||
_p3d_temp_file_current_size = 0;
|
|
||||||
_p3d_temp_file_total_size = 0;
|
|
||||||
|
|
||||||
char *name = tempnam(NULL, "p3d_");
|
|
||||||
_p3d_temp_filename = name;
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
_p3d_temp_file.clear();
|
|
||||||
_p3d_temp_file.open(_p3d_temp_filename.c_str(), ios::binary);
|
|
||||||
if (!_p3d_temp_file) {
|
|
||||||
nout << "Unable to open temp file " << _p3d_temp_filename << "\n";
|
|
||||||
set_failed();
|
|
||||||
} else {
|
|
||||||
nout << "Opening " << _p3d_temp_filename
|
|
||||||
<< " for storing preliminary p3d data\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PPInstance::send_p3d_temp_file_data
|
// Function: PPInstance::send_p3d_temp_file_data
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1525,10 +1526,10 @@ open_p3d_temp_file() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PPInstance::
|
void PPInstance::
|
||||||
send_p3d_temp_file_data() {
|
send_p3d_temp_file_data() {
|
||||||
assert(_opened_p3d_temp_file);
|
assert(_p3d_temp_file._opened);
|
||||||
|
|
||||||
nout << "Sending " << _p3d_temp_file_current_size
|
nout << "Sending " << _p3d_temp_file._current_size
|
||||||
<< " preliminary bytes of " << _p3d_temp_file_total_size
|
<< " preliminary bytes of " << _p3d_temp_file._total_size
|
||||||
<< " total p3d data\n";
|
<< " total p3d data\n";
|
||||||
|
|
||||||
static const size_t buffer_size = 4096;
|
static const size_t buffer_size = 4096;
|
||||||
@ -1536,14 +1537,14 @@ send_p3d_temp_file_data() {
|
|||||||
|
|
||||||
_p3d_temp_file.close();
|
_p3d_temp_file.close();
|
||||||
|
|
||||||
ifstream in(_p3d_temp_filename.c_str(), ios::binary);
|
ifstream in(_p3d_temp_file._filename.c_str(), ios::binary);
|
||||||
in.read(buffer, buffer_size);
|
in.read(buffer, buffer_size);
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
size_t count = in.gcount();
|
size_t count = in.gcount();
|
||||||
while (count != 0) {
|
while (count != 0) {
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, _p3d_instance_id,
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, _p3d_instance_id,
|
||||||
P3D_RC_in_progress, 0,
|
P3D_RC_in_progress, 0,
|
||||||
_p3d_temp_file_total_size, buffer, count);
|
_p3d_temp_file._total_size, buffer, count);
|
||||||
total += count;
|
total += count;
|
||||||
|
|
||||||
in.read(buffer, buffer_size);
|
in.read(buffer, buffer_size);
|
||||||
@ -1552,16 +1553,14 @@ send_p3d_temp_file_data() {
|
|||||||
nout << "sent " << count << " bytes.\n";
|
nout << "sent " << count << " bytes.\n";
|
||||||
|
|
||||||
in.close();
|
in.close();
|
||||||
_opened_p3d_temp_file = false;
|
|
||||||
unlink(_p3d_temp_filename.c_str());
|
|
||||||
_p3d_temp_filename.clear();
|
|
||||||
|
|
||||||
if (_finished_p3d_temp_file) {
|
if (_p3d_temp_file._finished) {
|
||||||
// If we'd already finished the stream earlier, tell the plugin.
|
// If we'd already finished the stream earlier, tell the plugin.
|
||||||
P3D_instance_feed_url_stream_ptr(_p3d_inst, _p3d_instance_id,
|
P3D_instance_feed_url_stream_ptr(_p3d_inst, _p3d_instance_id,
|
||||||
P3D_RC_done, 0, _p3d_temp_file_total_size,
|
P3D_RC_done, 0, _p3d_temp_file._total_size,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
}
|
}
|
||||||
|
_p3d_temp_file.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1795,7 +1794,7 @@ create_instance() {
|
|||||||
|
|
||||||
// If we have already started to receive any instance data, send it
|
// If we have already started to receive any instance data, send it
|
||||||
// to the plugin now.
|
// to the plugin now.
|
||||||
if (_opened_p3d_temp_file) {
|
if (_p3d_temp_file._opened) {
|
||||||
send_p3d_temp_file_data();
|
send_p3d_temp_file_data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2912,3 +2911,130 @@ thread_run() {
|
|||||||
// All done.
|
// All done.
|
||||||
_thread_done = true;
|
_thread_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PPInstance::StreamTempFile::
|
||||||
|
StreamTempFile() {
|
||||||
|
_opened = false;
|
||||||
|
_finished = false;
|
||||||
|
_current_size = 0;
|
||||||
|
_total_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PPInstance::StreamTempFile::
|
||||||
|
~StreamTempFile() {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::open
|
||||||
|
// Access: Public
|
||||||
|
// Description: Creates the temp file and prepares to write to it.
|
||||||
|
// It is not normally necessary to call this explicitly;
|
||||||
|
// it will be called automatically on the first call to
|
||||||
|
// feed().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::StreamTempFile::
|
||||||
|
open() {
|
||||||
|
assert(!_opened);
|
||||||
|
_opened = true;
|
||||||
|
_finished = false;
|
||||||
|
_current_size = 0;
|
||||||
|
_total_size = 0;
|
||||||
|
|
||||||
|
char *name = tempnam(NULL, "p3d_");
|
||||||
|
_filename = name;
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
_stream.clear();
|
||||||
|
_stream.open(_filename.c_str(), ios::binary);
|
||||||
|
if (!_stream) {
|
||||||
|
nout << "Unable to open temp file " << _filename << "\n";
|
||||||
|
} else {
|
||||||
|
nout << "Opening " << _filename << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::feed
|
||||||
|
// Access: Public
|
||||||
|
// Description: Receives new data from the URL and writes it to the
|
||||||
|
// temp file. Returns true on success, false on
|
||||||
|
// failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PPInstance::StreamTempFile::
|
||||||
|
feed(size_t total_expected_data, const void *this_data,
|
||||||
|
size_t this_data_size) {
|
||||||
|
assert(!_finished);
|
||||||
|
if (!_opened) {
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream.write((const char *)this_data, this_data_size);
|
||||||
|
_current_size += this_data_size;
|
||||||
|
_total_size = total_expected_data;
|
||||||
|
|
||||||
|
if (!_stream) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::finish
|
||||||
|
// Access: Public
|
||||||
|
// Description: Marks the end of the data received from the URL. The
|
||||||
|
// file is closed but not yet deleted; it remains on
|
||||||
|
// disk and may be read at leisure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::StreamTempFile::
|
||||||
|
finish() {
|
||||||
|
if (!_finished) {
|
||||||
|
_finished = true;
|
||||||
|
_total_size = _current_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::close
|
||||||
|
// Access: Public
|
||||||
|
// Description: Closes the stream for more data. The file is not yet
|
||||||
|
// deleted; it remains on disk and may be read at
|
||||||
|
// leisure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::StreamTempFile::
|
||||||
|
close() {
|
||||||
|
_stream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::StreamTempFile::cleanup
|
||||||
|
// Access: Public
|
||||||
|
// Description: Closes all open processes and removes the temp file
|
||||||
|
// from disk.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::StreamTempFile::
|
||||||
|
cleanup() {
|
||||||
|
finish();
|
||||||
|
|
||||||
|
if (!_filename.empty()) {
|
||||||
|
nout << "Deleting " << _filename << "\n";
|
||||||
|
unlink(_filename.c_str());
|
||||||
|
_filename.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
_opened = false;
|
||||||
|
_finished = false;
|
||||||
|
}
|
||||||
|
@ -86,6 +86,7 @@ private:
|
|||||||
void open_p3d_temp_file();
|
void open_p3d_temp_file();
|
||||||
void send_p3d_temp_file_data();
|
void send_p3d_temp_file_data();
|
||||||
|
|
||||||
|
void downloaded_contents_file(const string &filename);
|
||||||
bool read_contents_file(const string &contents_filename, bool fresh_download);
|
bool read_contents_file(const string &contents_filename, bool fresh_download);
|
||||||
void get_core_api();
|
void get_core_api();
|
||||||
void downloaded_plugin(const string &filename);
|
void downloaded_plugin(const string &filename);
|
||||||
@ -168,15 +169,34 @@ private:
|
|||||||
bool _failed;
|
bool _failed;
|
||||||
bool _started;
|
bool _started;
|
||||||
|
|
||||||
|
// This class is used to stream data from some URL into a temporary
|
||||||
|
// local file.
|
||||||
|
class StreamTempFile {
|
||||||
|
public:
|
||||||
|
StreamTempFile();
|
||||||
|
~StreamTempFile();
|
||||||
|
|
||||||
|
void open();
|
||||||
|
bool feed(size_t total_expected_data, const void *this_data,
|
||||||
|
size_t this_data_size);
|
||||||
|
void finish();
|
||||||
|
void close();
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
bool _opened;
|
||||||
|
bool _finished;
|
||||||
|
size_t _current_size;
|
||||||
|
size_t _total_size;
|
||||||
|
ofstream _stream;
|
||||||
|
string _filename;
|
||||||
|
};
|
||||||
|
|
||||||
bool _got_instance_url;
|
bool _got_instance_url;
|
||||||
string _instance_url;
|
string _instance_url;
|
||||||
bool _opened_p3d_temp_file;
|
|
||||||
bool _finished_p3d_temp_file;
|
|
||||||
size_t _p3d_temp_file_current_size;
|
|
||||||
size_t _p3d_temp_file_total_size;
|
|
||||||
ofstream _p3d_temp_file;
|
|
||||||
string _p3d_temp_filename;
|
|
||||||
int _p3d_instance_id;
|
int _p3d_instance_id;
|
||||||
|
StreamTempFile _p3d_temp_file;
|
||||||
|
StreamTempFile _contents_temp_file;
|
||||||
|
StreamTempFile _core_dll_temp_file;
|
||||||
|
|
||||||
// We need to keep a list of the NPStream objects that the instance
|
// We need to keep a list of the NPStream objects that the instance
|
||||||
// owns, because Safari (at least) won't automatically delete all of
|
// owns, because Safari (at least) won't automatically delete all of
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "p3d_lock.h"
|
#include "p3d_lock.h"
|
||||||
#include "ppBrowserObject.h"
|
#include "ppBrowserObject.h"
|
||||||
#include "wstring_encode.h"
|
#include "wstring_encode.h"
|
||||||
|
#include "find_root_dir.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user