From b25d059474caaa78b09f3abc0aa68e3326516ef7 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 11 Jan 2010 21:15:11 +0000 Subject: [PATCH] expand get_log() etc. --- direct/src/plugin/p3dInstance.cxx | 8 +- direct/src/plugin/p3dMainObject.cxx | 128 ++++++++++++++++++++++++---- direct/src/plugin/p3dMainObject.h | 1 + 3 files changed, 116 insertions(+), 21 deletions(-) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 80c0c7553c..71076c5c3c 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -212,7 +212,7 @@ P3DInstance(P3D_request_ready_func *func, _panda_script_object->set_string_property("pluginDistributor", inst_mgr->get_plugin_distributor()); _panda_script_object->set_string_property("coreapiHostUrl", inst_mgr->get_coreapi_host_url()); time_t timestamp = inst_mgr->get_coreapi_timestamp(); - _panda_script_object->set_int_property("coreapiTimestamp", timestamp); + _panda_script_object->set_int_property("coreapiTimestamp", (int)timestamp); _panda_script_object->set_string_property("coreapiTimestampString", ctime(×tamp)); @@ -1245,6 +1245,8 @@ make_xml() { P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); xinstance->SetAttribute("root_dir", inst_mgr->get_root_dir()); + xinstance->SetAttribute("log_directory", inst_mgr->get_log_directory()); + if (!inst_mgr->get_super_mirror().empty()) { xinstance->SetAttribute("super_mirror", inst_mgr->get_super_mirror()); } @@ -2976,7 +2978,7 @@ report_package_progress(P3DPackage *package, double progress) { char buffer[buffer_size]; time_t elapsed = time(NULL) - _download_begin; - _panda_script_object->set_int_property("downloadElapsedSeconds", elapsed); + _panda_script_object->set_int_property("downloadElapsedSeconds", (int)elapsed); sprintf(buffer, "%d:%02d", (int)(elapsed / 60), (int)(elapsed % 60)); _panda_script_object->set_string_property("downloadElapsedFormatted", buffer); @@ -2984,7 +2986,7 @@ report_package_progress(P3DPackage *package, double progress) { if (progress > 0 && (elapsed > 5 || progress > 0.2)) { time_t total = (time_t)((double)elapsed / progress); time_t remaining = max(total, elapsed) - elapsed; - _panda_script_object->set_int_property("downloadRemainingSeconds", remaining); + _panda_script_object->set_int_property("downloadRemainingSeconds", (int)remaining); sprintf(buffer, "%d:%02d", (int)(remaining / 60), (int)(remaining % 60)); _panda_script_object->set_string_property("downloadRemainingFormatted", buffer); } diff --git a/direct/src/plugin/p3dMainObject.cxx b/direct/src/plugin/p3dMainObject.cxx index 37e493cc72..47ee6c78ce 100644 --- a/direct/src/plugin/p3dMainObject.cxx +++ b/direct/src/plugin/p3dMainObject.cxx @@ -191,6 +191,8 @@ has_method(const string &method_name) { return true; } else if (method_name == "read_system_log") { return true; + } else if (method_name == "read_log") { + return true; } else if (method_name == "uninstall") { return true; } @@ -227,6 +229,8 @@ call(const string &method_name, bool needs_response, return call_read_game_log(params, num_params); } else if (method_name == "read_system_log") { return call_read_system_log(params, num_params); + } else if (method_name == "read_log") { + return call_read_log(params, num_params); } else if (method_name == "uninstall") { return call_uninstall(params, num_params); } @@ -362,9 +366,7 @@ call_play(P3D_object *params[], int num_params) { P3D_object *P3DMainObject:: call_read_game_log(P3D_object *params[], int num_params) { if (_inst != NULL) { - nout << "querying " << _inst << "->_log_pathname\n"; string log_pathname = _inst->get_log_pathname(); - nout << "result is " << log_pathname << "\n"; return read_log(log_pathname, params, num_params); } @@ -396,6 +398,54 @@ call_read_system_log(P3D_object *params[], int num_params) { //////////////////////////////////////////////////////////////////// // Function: P3DMainObject::call_read_log // Access: Private +// Description: Reads a named logfile. The filename must end +// in ".log" and must not contain any slashes or colons +// (it must be found within the log directory). +//////////////////////////////////////////////////////////////////// +P3D_object *P3DMainObject:: +call_read_log(P3D_object *params[], int num_params) { + P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); + + if (num_params < 1) { + return inst_mgr->new_undefined_object(); + } + + int size = P3D_OBJECT_GET_STRING(params[0], NULL, 0); + char *buffer = new char[size]; + P3D_OBJECT_GET_STRING(params[0], buffer, size); + string log_filename = string(buffer, size); + delete[] buffer; + + if (log_filename.size() < 4 || log_filename.substr(log_filename.size() - 4) != string(".log")) { + // Wrong filename extension. + return inst_mgr->new_undefined_object(); + } + + size_t slash = log_filename.find('/'); + if (slash != string::npos) { + // No slashes allowed. + return inst_mgr->new_undefined_object(); + } + + slash = log_filename.find('\\'); + if (slash != string::npos) { + // Nor backslashes. + return inst_mgr->new_undefined_object(); + } + + size_t colon = log_filename.find(':'); + if (colon != string::npos) { + // Nor colons, for that matter. + return inst_mgr->new_undefined_object(); + } + + string log_pathname = inst_mgr->get_log_directory() + log_filename; + return read_log(log_pathname, params + 1, num_params - 1); +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DMainObject::read_log +// Access: Private // Description: The generic log-reader function. //////////////////////////////////////////////////////////////////// P3D_object *P3DMainObject:: @@ -406,35 +456,77 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) { return inst_mgr->new_undefined_object(); } - // Check the parameter, if any--if specified, it specifies the last - // n bytes to retrieve. - int max_bytes = 0; + // Check the first parameter, if any--if given, it specifies the + // last n bytes to retrieve. + size_t tail_bytes = 0; if (num_params > 0) { - max_bytes = P3D_OBJECT_GET_INT(params[0]); + tail_bytes = (size_t)max(P3D_OBJECT_GET_INT(params[0]), 0); + } + + // Check the second parameter, if any--if given, it specifies the + // first n bytes to retrieve. + size_t head_bytes = 0; + if (num_params > 1) { + head_bytes = (size_t)max(P3D_OBJECT_GET_INT(params[1]), 0); } // Get the size of the file. log.seekg(0, ios::end); - size_t size = (size_t)log.tellg(); - nout << "read_log: " << log_pathname << " is " << size << " bytes\n"; + size_t file_size = (size_t)log.tellg(); + nout << "read_log: " << log_pathname << " is " << file_size + << " bytes, tail_bytes = " << tail_bytes << ", head_bytes = " + << head_bytes << "\n"; + + size_t return_size = file_size; + string separator; + + if (file_size <= head_bytes + tail_bytes) { + // We will return the entire log. + head_bytes = file_size; + tail_bytes = 0; + return_size = file_size; + + } else if (head_bytes == 0) { + // We will be returning the tail of the log only. + return_size = tail_bytes; + + } else if (tail_bytes == 0) { + // We will be returning the head of the log only. + return_size = head_bytes; - if (max_bytes > 0 && max_bytes < (int)size) { - // Apply the limit. - log.seekg(size - max_bytes, ios::beg); - size = (size_t)max_bytes; } else { - // Read the entire file. - log.seekg(0, ios::beg); + // We will be excising the middle part of the log. + separator = "\n\n**** truncated ****\n\n"; + return_size = head_bytes + separator.size() + tail_bytes; } - nout << "allocating " << size << " bytes to return.\n"; - char *buffer = new char[size]; + nout << "allocating " << return_size << " bytes to return.\n"; + char *buffer = new char[return_size]; if (buffer == NULL) { return NULL; } - log.read(buffer, size); - P3D_object *result = new P3DStringObject(buffer, log.gcount()); + char *bp = buffer; + if (head_bytes > 0) { + log.seekg(0, ios::beg); + log.read(bp, head_bytes); + bp += log.gcount(); + } + + if (!separator.empty()) { + memcpy(bp, separator.data(), separator.length()); + bp += separator.length(); + } + + if (tail_bytes > 0) { + log.seekg(file_size - tail_bytes, ios::beg); + log.read(bp, tail_bytes); + bp += log.gcount(); + } + + assert(bp <= buffer + return_size); + + P3D_object *result = new P3DStringObject(buffer, bp - buffer); delete[] buffer; return result; diff --git a/direct/src/plugin/p3dMainObject.h b/direct/src/plugin/p3dMainObject.h index a77e8b004e..01f56e1aec 100644 --- a/direct/src/plugin/p3dMainObject.h +++ b/direct/src/plugin/p3dMainObject.h @@ -71,6 +71,7 @@ private: P3D_object *call_play(P3D_object *params[], int num_params); P3D_object *call_read_game_log(P3D_object *params[], int num_params); P3D_object *call_read_system_log(P3D_object *params[], int num_params); + P3D_object *call_read_log(P3D_object *params[], int num_params); P3D_object *read_log(const string &log_pathname, P3D_object *params[], int num_params); P3D_object *call_uninstall(P3D_object *params[], int num_params);