diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/file_access_buffered_fa.h | 5 | ||||
-rw-r--r-- | core/io/file_access_compressed.cpp | 7 | ||||
-rw-r--r-- | core/io/file_access_compressed.h | 1 | ||||
-rw-r--r-- | core/io/file_access_encrypted.cpp | 6 | ||||
-rw-r--r-- | core/io/file_access_encrypted.h | 1 | ||||
-rw-r--r-- | core/io/file_access_memory.cpp | 4 | ||||
-rw-r--r-- | core/io/file_access_memory.h | 1 | ||||
-rw-r--r-- | core/io/file_access_network.cpp | 4 | ||||
-rw-r--r-- | core/io/file_access_network.h | 1 | ||||
-rw-r--r-- | core/io/file_access_pack.cpp | 5 | ||||
-rw-r--r-- | core/io/file_access_pack.h | 1 | ||||
-rw-r--r-- | core/io/file_access_zip.cpp | 5 | ||||
-rw-r--r-- | core/io/file_access_zip.h | 1 | ||||
-rw-r--r-- | core/io/http_client.cpp | 2 | ||||
-rw-r--r-- | core/io/logger.cpp | 255 | ||||
-rw-r--r-- | core/io/logger.h | 107 | ||||
-rw-r--r-- | core/io/resource_import.cpp | 2 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 2 |
18 files changed, 407 insertions, 3 deletions
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index 9e41834561..309fc16d09 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -76,6 +76,11 @@ protected: }; public: + void flush() { + + f.flush(); + }; + void store_8(uint8_t p_dest) { f.store_8(p_dest); diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 4750945854..514e3c65f0 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -338,6 +338,13 @@ Error FileAccessCompressed::get_error() const { return read_eof ? ERR_FILE_EOF : OK; } +void FileAccessCompressed::flush() { + ERR_FAIL_COND(!f); + ERR_FAIL_COND(!writing); + + // compressed files keep data in memory till close() +} + void FileAccessCompressed::store_8(uint8_t p_dest) { ERR_FAIL_COND(!f); diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 1a57e2d4ee..1d99e5bfd4 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -84,6 +84,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 461c5bafe2..c93e12f7da 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -268,6 +268,12 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) { } } +void FileAccessEncrypted::flush() { + ERR_FAIL_COND(!writing); + + // encrypted files keep data in memory till close() +} + void FileAccessEncrypted::store_8(uint8_t p_dest) { ERR_FAIL_COND(!writing); diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 82f60ac654..d83fed3e0e 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -71,6 +71,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index b948394385..0a5815fca8 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -170,6 +170,10 @@ Error FileAccessMemory::get_error() const { return pos >= length ? ERR_FILE_EOF : OK; } +void FileAccessMemory::flush() { + ERR_FAIL_COND(!data); +} + void FileAccessMemory::store_8(uint8_t p_byte) { ERR_FAIL_COND(!data); diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index b7b8430089..23392719b4 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -62,6 +62,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_byte); ///< store a byte virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 8c624226a1..a224abd9e7 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -456,6 +456,10 @@ Error FileAccessNetwork::get_error() const { return pos == total_size ? ERR_FILE_EOF : OK; } +void FileAccessNetwork::flush() { + ERR_FAIL(); +} + void FileAccessNetwork::store_8(uint8_t p_dest) { ERR_FAIL(); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index abbe378b60..20614476d0 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -155,6 +155,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual bool file_exists(const String &p_path); ///< return true if a file exists diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index ff4c28ec39..a7eb8ce6a9 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -293,6 +293,11 @@ Error FileAccessPack::get_error() const { return OK; } +void FileAccessPack::flush() { + + ERR_FAIL(); +} + void FileAccessPack::store_8(uint8_t p_dest) { ERR_FAIL(); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 3deb0d2bd3..12187a353a 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -161,6 +161,7 @@ public: virtual Error get_error() const; + virtual void flush(); virtual void store_8(uint8_t p_dest); virtual void store_buffer(const uint8_t *p_src, int p_length); diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 73b23ac702..ec809011a9 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -353,6 +353,11 @@ Error FileAccessZip::get_error() const { return OK; }; +void FileAccessZip::flush() { + + ERR_FAIL(); +} + void FileAccessZip::store_8(uint8_t p_dest) { ERR_FAIL(); diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index a40e1a753d..0977b241ee 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -108,6 +108,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index dd56db9bf9..b8c0a2b616 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -297,7 +297,7 @@ Error HTTPClient::poll() { case StreamPeerTCP::STATUS_CONNECTED: { if (ssl) { Ref<StreamPeerSSL> ssl = StreamPeerSSL::create(); - Error err = ssl->connect_to_stream(tcp_connection, true, ssl_verify_host ? conn_host : String()); + Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, ssl_verify_host ? conn_host : String()); if (err != OK) { close(); status = STATUS_SSL_HANDSHAKE_ERROR; diff --git a/core/io/logger.cpp b/core/io/logger.cpp new file mode 100644 index 0000000000..b94007d316 --- /dev/null +++ b/core/io/logger.cpp @@ -0,0 +1,255 @@ +/*************************************************************************/ +/* logger.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "logger.h" +#include "os/dir_access.h" +#include "os/os.h" +#include "print_string.h" + +bool Logger::should_log(bool p_err) { + return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled); +} + +void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { + if (!should_log(true)) { + return; + } + + const char *err_type = "**ERROR**"; + switch (p_type) { + case ERR_ERROR: err_type = "**ERROR**"; break; + case ERR_WARNING: err_type = "**WARNING**"; break; + case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break; + case ERR_SHADER: err_type = "**SHADER ERROR**"; break; + default: ERR_PRINT("Unknown error type"); break; + } + + const char *err_details; + if (p_rationale && *p_rationale) + err_details = p_rationale; + else + err_details = p_code; + + logf_error("%s: %s\n", err_type, err_details); + logf_error(" At: %s:%i:%s() - %s\n", p_file, p_line, p_function, p_code); +} + +void Logger::logf(const char *p_format, ...) { + if (!should_log(false)) { + return; + } + + va_list argp; + va_start(argp, p_format); + + logv(p_format, argp, false); + + va_end(argp); +} + +void Logger::logf_error(const char *p_format, ...) { + if (!should_log(true)) { + return; + } + + va_list argp; + va_start(argp, p_format); + + logv(p_format, argp, true); + + va_end(argp); +} + +Logger::~Logger() {} + +void RotatedFileLogger::close_file() { + if (file) { + memdelete(file); + file = NULL; + } +} + +void RotatedFileLogger::clear_old_backups() { + int max_backups = max_files - 1; // -1 for the current file + + String basename = base_path.get_basename(); + String extension = "." + base_path.get_extension(); + + DirAccess *da = DirAccess::open(base_path.get_base_dir()); + if (!da) { + return; + } + + da->list_dir_begin(); + String f = da->get_next(); + Set<String> backups; + while (f != String()) { + if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path) { + backups.insert(f); + } + f = da->get_next(); + } + da->list_dir_end(); + + if (backups.size() > max_backups) { + // since backups are appended with timestamp and Set iterates them in sorted order, + // first backups are the oldest + int to_delete = backups.size() - max_backups; + for (Set<String>::Element *E = backups.front(); E && to_delete > 0; E = E->next(), --to_delete) { + da->remove(E->get()); + } + } + + memdelete(da); +} + +void RotatedFileLogger::rotate_file() { + close_file(); + + if (FileAccess::exists(base_path)) { + if (max_files > 1) { + char timestamp[21]; + OS::Date date = OS::get_singleton()->get_date(); + OS::Time time = OS::get_singleton()->get_time(); + sprintf(timestamp, "-%04d-%02d-%02d-%02d-%02d-%02d", date.year, date.month, date.day + 1, time.hour, time.min, time.sec); + + String backup_name = base_path.get_basename() + timestamp + "." + base_path.get_extension(); + + DirAccess *da = DirAccess::open(base_path.get_base_dir()); + if (da) { + da->copy(base_path, backup_name); + memdelete(da); + } + clear_old_backups(); + } + } else { + DirAccess *da = DirAccess::create(DirAccess::ACCESS_USERDATA); + if (da) { + da->make_dir_recursive(base_path.get_base_dir()); + memdelete(da); + } + } + + file = FileAccess::open(base_path, FileAccess::WRITE); +} + +RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) { + file = NULL; + base_path = p_base_path.simplify_path(); + max_files = p_max_files > 0 ? p_max_files : 1; + + rotate_file(); +} + +void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) { + if (!should_log(p_err)) { + return; + } + + if (file) { + const int static_buf_size = 512; + char static_buf[static_buf_size]; + char *buf = static_buf; + va_list list_copy; + va_copy(list_copy, p_list); + int len = vsnprintf(buf, static_buf_size, p_format, p_list); + if (len >= static_buf_size) { + buf = (char *)Memory::alloc_static(len + 1); + vsnprintf(buf, len + 1, p_format, list_copy); + } + va_end(list_copy); + file->store_buffer((uint8_t *)buf, len); + if (len >= static_buf_size) { + Memory::free_static(buf); + } +#ifdef DEBUG_ENABLED + const bool need_flush = true; +#else + bool need_flush = p_err; +#endif + if (need_flush) { + file->flush(); + } + } +} + +RotatedFileLogger::~RotatedFileLogger() { + close_file(); +} + +void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) { + if (!should_log(p_err)) { + return; + } + + if (p_err) { + vfprintf(stderr, p_format, p_list); + } else { + vprintf(p_format, p_list); +#ifdef DEBUG_ENABLED + fflush(stdout); +#endif + } +} + +StdLogger::~StdLogger() {} + +CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) { + loggers = p_loggers; +} + +void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) { + if (!should_log(p_err)) { + return; + } + + for (int i = 0; i < loggers.size(); ++i) { + va_list list_copy; + va_copy(list_copy, p_list); + loggers[i]->logv(p_format, list_copy, p_err); + va_end(list_copy); + } +} + +void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { + if (!should_log(true)) { + return; + } + + for (int i = 0; i < loggers.size(); ++i) { + loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type); + } +} + +CompositeLogger::~CompositeLogger() { + for (int i = 0; i < loggers.size(); ++i) { + memdelete(loggers[i]); + } +} diff --git a/core/io/logger.h b/core/io/logger.h new file mode 100644 index 0000000000..cf0cc7699f --- /dev/null +++ b/core/io/logger.h @@ -0,0 +1,107 @@ +/*************************************************************************/ +/* logger.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef LOGGER_H +#define LOGGER_H + +#include "os/file_access.h" +#include "ustring.h" +#include "vector.h" +#include <stdarg.h> + +class Logger { +protected: + bool should_log(bool p_err); + +public: + enum ErrorType { + ERR_ERROR, + ERR_WARNING, + ERR_SCRIPT, + ERR_SHADER + }; + + virtual void logv(const char *p_format, va_list p_list, bool p_err) = 0; + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + + void logf(const char *p_format, ...); + void logf_error(const char *p_format, ...); + + virtual ~Logger(); +}; + +/** + * Writes messages to stdout/stderr. + */ +class StdLogger : public Logger { + +public: + virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual ~StdLogger(); +}; + +/** + * Writes messages to the specified file. If the file already exists, creates a copy (backup) + * of it with timestamp appended to the file name. Maximum number of backups is configurable. + * When maximum is reached, the oldest backups are erased. With the maximum being equal to 1, + * it acts as a simple file logger. + */ +class RotatedFileLogger : public Logger { + String base_path; + int max_files; + + FileAccess *file; + + void rotate_file_without_closing(); + void close_file(); + void clear_old_backups(); + void rotate_file(); + +public: + RotatedFileLogger(const String &p_base_path, int p_max_files = 10); + + virtual void logv(const char *p_format, va_list p_list, bool p_err); + + virtual ~RotatedFileLogger(); +}; + +class CompositeLogger : public Logger { + Vector<Logger *> loggers; + +public: + CompositeLogger(Vector<Logger *> p_loggers); + + virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + + virtual ~CompositeLogger(); +}; + +#endif
\ No newline at end of file diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index bc7ea47762..401d704222 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -77,7 +77,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy if (assign != String()) { if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) { String feature = assign.get_slicec('.', 1); - if (OS::get_singleton()->check_feature_support(feature)) { + if (OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; path_found = true; //first match must have priority } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 89cb4a22c2..ed0d491679 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -492,7 +492,7 @@ void ResourceLoader::reload_translation_remaps() { void ResourceLoader::load_translation_remaps() { - if (!ProjectSettings::get_singleton()->has("locale/translation_remaps")) + if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) return; Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); |