aboutsummaryrefslogtreecommitdiff
path: root/core/os/file_access.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/os/file_access.cpp')
-rw-r--r--core/os/file_access.cpp94
1 files changed, 91 insertions, 3 deletions
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 7b2062936..033b4b12b 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "file_access.h"
#include "core/io/file_access_pack.h"
@@ -273,9 +274,62 @@ String FileAccess::get_token() const {
return String::utf8(token.get_data());
}
+class CharBuffer {
+ Vector<char> vector;
+ char stack_buffer[256];
+
+ char *buffer;
+ int capacity;
+ int written;
+
+ bool grow() {
+
+ if (vector.resize(next_power_of_2(1 + written)) != OK) {
+
+ return false;
+ }
+
+ if (buffer == stack_buffer) { // first chunk?
+
+ for (int i = 0; i < written; i++) {
+
+ vector[i] = stack_buffer[i];
+ }
+ }
+
+ buffer = vector.ptrw();
+ capacity = vector.size();
+ ERR_FAIL_COND_V(written >= capacity, false);
+
+ return true;
+ }
+
+public:
+ _FORCE_INLINE_ CharBuffer() :
+ buffer(stack_buffer),
+ capacity(sizeof(stack_buffer) / sizeof(char)),
+ written(0) {
+ }
+
+ _FORCE_INLINE_ void push_back(char c) {
+
+ if (written >= capacity) {
+
+ ERR_FAIL_COND(!grow());
+ }
+
+ buffer[written++] = c;
+ }
+
+ _FORCE_INLINE_ const char *get_data() const {
+
+ return buffer;
+ }
+};
+
String FileAccess::get_line() const {
- CharString line;
+ CharBuffer line;
CharType c = get_8();
@@ -425,6 +479,9 @@ void FileAccess::store_double(double p_dest) {
uint64_t FileAccess::get_modified_time(const String &p_file) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file))
+ return 0;
+
FileAccess *fa = create_for_path(p_file);
ERR_FAIL_COND_V(!fa, 0);
@@ -516,6 +573,37 @@ String FileAccess::get_md5(const String &p_file) {
return ret;
}
+String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
+
+ MD5_CTX md5;
+ MD5Init(&md5);
+
+ for (int i = 0; i < p_file.size(); i++) {
+ FileAccess *f = FileAccess::open(p_file[i], READ);
+ ERR_CONTINUE(!f);
+
+ unsigned char step[32768];
+
+ while (true) {
+
+ int br = f->get_buffer(step, 32768);
+ if (br > 0) {
+
+ MD5Update(&md5, step, br);
+ }
+ if (br < 4096)
+ break;
+ }
+ memdelete(f);
+ }
+
+ MD5Final(&md5);
+
+ String ret = String::md5(md5.digest);
+
+ return ret;
+}
+
String FileAccess::get_sha256(const String &p_file) {
FileAccess *f = FileAccess::open(p_file, READ);