summaryrefslogtreecommitdiff
path: root/core/io
diff options
context:
space:
mode:
Diffstat (limited to 'core/io')
-rw-r--r--core/io/compression.cpp6
-rw-r--r--core/io/dir_access.cpp8
-rw-r--r--core/io/http_client.cpp11
-rw-r--r--core/io/http_client.h3
-rw-r--r--core/io/http_client_tcp.cpp92
-rw-r--r--core/io/http_client_tcp.h13
-rw-r--r--core/io/image.cpp56
-rw-r--r--core/io/image.h7
-rw-r--r--core/io/ip.cpp42
-rw-r--r--core/io/marshalls.cpp5
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/resource.h2
-rw-r--r--core/io/resource_loader.cpp26
-rw-r--r--core/io/stream_peer.cpp4
14 files changed, 115 insertions, 162 deletions
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index d1f915f064..ae5ccf8354 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -212,7 +212,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
strm.avail_in = p_src_size;
// Ensure the destination buffer is empty
- p_dst_vect->resize(0);
+ p_dst_vect->clear();
// decompress until deflate stream ends or end of file
do {
@@ -244,7 +244,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
WARN_PRINT(strm.msg);
}
(void)inflateEnd(&strm);
- p_dst_vect->resize(0);
+ p_dst_vect->clear();
return ret;
}
} while (strm.avail_out > 0 && strm.avail_in > 0);
@@ -254,7 +254,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
// Enforce max output size
if (p_max_dst_size > -1 && strm.total_out > (uint64_t)p_max_dst_size) {
(void)inflateEnd(&strm);
- p_dst_vect->resize(0);
+ p_dst_vect->clear();
return Z_BUF_ERROR;
}
} while (ret != Z_STREAM_END);
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index 3da9288ffd..db0758d7fc 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -145,14 +145,18 @@ Error DirAccess::make_dir_recursive(String p_dir) {
full_dir = full_dir.replace("\\", "/");
- //int slices = full_dir.get_slice_count("/");
-
String base;
if (full_dir.begins_with("res://")) {
base = "res://";
} else if (full_dir.begins_with("user://")) {
base = "user://";
+ } else if (full_dir.is_network_share_path()) {
+ int pos = full_dir.find("/", 2);
+ ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
+ pos = full_dir.find("/", pos + 1);
+ ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
+ base = full_dir.substr(0, pos + 1);
} else if (full_dir.begins_with("/")) {
base = "/";
} else if (full_dir.find(":/") != -1) {
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 4d0747c591..52b1120b2a 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -96,6 +96,17 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
return query.substr(1);
}
+Error HTTPClient::verify_headers(const Vector<String> &p_headers) {
+ for (int i = 0; i < p_headers.size(); i++) {
+ String sanitized = p_headers[i].strip_edges();
+ ERR_FAIL_COND_V_MSG(sanitized.is_empty(), ERR_INVALID_PARAMETER, "Invalid HTTP header at index " + itos(i) + ": empty.");
+ ERR_FAIL_COND_V_MSG(sanitized.find(":") < 1, ERR_INVALID_PARAMETER,
+ "Invalid HTTP header at index " + itos(i) + ": String must contain header-value pair, delimited by ':', but was: " + p_headers[i]);
+ }
+
+ return OK;
+}
+
Dictionary HTTPClient::_get_response_headers_as_dictionary() {
List<String> rh;
get_response_headers(&rh);
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 8be6e6524c..de6045f647 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -165,6 +165,7 @@ public:
static HTTPClient *create();
String query_string_from_dict(const Dictionary &p_dict);
+ Error verify_headers(const Vector<String> &p_headers);
virtual Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) = 0;
virtual Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true) = 0;
@@ -180,7 +181,7 @@ public:
virtual bool is_response_chunked() const = 0;
virtual int get_response_code() const = 0;
virtual Error get_response_headers(List<String> *r_response) = 0;
- virtual int get_response_body_length() const = 0;
+ virtual int64_t get_response_body_length() const = 0;
virtual PackedByteArray read_response_body_chunk() = 0; // Can't get body as partial text because of most encodings UTF8, gzip, etc.
diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp
index 4c27cd1b10..e61833ce7c 100644
--- a/core/io/http_client_tcp.cpp
+++ b/core/io/http_client_tcp.cpp
@@ -71,7 +71,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
connection = tcp_connection;
if (ssl && https_proxy_port != -1) {
- proxy_client.instantiate(); // Needs proxy negotiation
+ proxy_client.instantiate(); // Needs proxy negotiation.
server_host = https_proxy_host;
server_port = https_proxy_port;
} else if (!ssl && http_proxy_port != -1) {
@@ -83,7 +83,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
}
if (server_host.is_valid_ip_address()) {
- // Host contains valid IP
+ // Host contains valid IP.
Error err = tcp_connection->connect_to_host(IPAddress(server_host), server_port);
if (err) {
status = STATUS_CANT_CONNECT;
@@ -92,7 +92,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
status = STATUS_CONNECTING;
} else {
- // Host contains hostname and needs to be resolved to IP
+ // Host contains hostname and needs to be resolved to IP.
resolving = IP::get_singleton()->resolve_hostname_queue_item(server_host);
status = STATUS_RESOLVING;
}
@@ -124,7 +124,7 @@ Ref<StreamPeer> HTTPClientTCP::get_connection() const {
static bool _check_request_url(HTTPClientTCP::Method p_method, const String &p_url) {
switch (p_method) {
case HTTPClientTCP::METHOD_CONNECT: {
- // Authority in host:port format, as in RFC7231
+ // Authority in host:port format, as in RFC7231.
int pos = p_url.find_char(':');
return 0 < pos && pos < p_url.length() - 1;
}
@@ -135,7 +135,7 @@ static bool _check_request_url(HTTPClientTCP::Method p_method, const String &p_u
[[fallthrough]];
}
default:
- // Absolute path or absolute URL
+ // Absolute path or absolute URL.
return p_url.begins_with("/") || p_url.begins_with("http://") || p_url.begins_with("https://");
}
}
@@ -146,6 +146,11 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA);
+ Error err = verify_headers(p_headers);
+ if (err) {
+ return err;
+ }
+
String uri = p_url;
if (!ssl && http_proxy_port != -1) {
uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url);
@@ -173,7 +178,7 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
}
if (add_host) {
if ((ssl && conn_port == PORT_HTTPS) || (!ssl && conn_port == PORT_HTTP)) {
- // Don't append the standard ports
+ // Don't append the standard ports.
request += "Host: " + conn_host + "\r\n";
} else {
request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n";
@@ -192,21 +197,12 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
request += "\r\n";
CharString cs = request.utf8();
- Vector<uint8_t> data;
- data.resize(cs.length() + p_body_size);
- memcpy(data.ptrw(), cs.get_data(), cs.length());
+ request_buffer->clear();
+ request_buffer->put_data((const uint8_t *)cs.get_data(), cs.length());
if (p_body_size > 0) {
- memcpy(data.ptrw() + cs.length(), p_body, p_body_size);
- }
-
- // TODO Implement non-blocking requests.
- Error err = connection->put_data(data.ptr(), data.size());
-
- if (err) {
- close();
- status = STATUS_CONNECTION_ERROR;
- return err;
+ request_buffer->put_data(p_body, p_body_size);
}
+ request_buffer->seek(0);
status = STATUS_REQUESTING;
head_request = p_method == METHOD_HEAD;
@@ -257,6 +253,7 @@ void HTTPClientTCP::close() {
ip_candidates.clear();
response_headers.clear();
response_str.clear();
+ request_buffer->clear();
body_size = -1;
body_left = 0;
chunk_left = 0;
@@ -274,7 +271,7 @@ Error HTTPClientTCP::poll() {
IP::ResolverStatus rstatus = IP::get_singleton()->get_resolve_item_status(resolving);
switch (rstatus) {
case IP::RESOLVER_STATUS_WAITING:
- return OK; // Still resolving
+ return OK; // Still resolving.
case IP::RESOLVER_STATUS_DONE: {
ip_candidates = IP::get_singleton()->get_resolve_item_addresses(resolving);
@@ -356,7 +353,7 @@ Error HTTPClientTCP::poll() {
} else if (ssl) {
Ref<StreamPeerSSL> ssl;
if (!handshaking) {
- // Connect the StreamPeerSSL and start handshaking
+ // Connect the StreamPeerSSL and start handshaking.
ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
ssl->set_blocking_handshake_enabled(false);
Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
@@ -368,7 +365,7 @@ Error HTTPClientTCP::poll() {
connection = ssl;
handshaking = true;
} else {
- // We are already handshaking, which means we can use your already active SSL connection
+ // We are already handshaking, which means we can use your already active SSL connection.
ssl = static_cast<Ref<StreamPeerSSL>>(connection);
if (ssl.is_null()) {
close();
@@ -376,22 +373,22 @@ Error HTTPClientTCP::poll() {
return ERR_CANT_CONNECT;
}
- ssl->poll(); // Try to finish the handshake
+ ssl->poll(); // Try to finish the handshake.
}
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
- // Handshake has been successful
+ // Handshake has been successful.
handshaking = false;
ip_candidates.clear();
status = STATUS_CONNECTED;
return OK;
} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
- // Handshake has failed
+ // Handshake has failed.
close();
status = STATUS_SSL_HANDSHAKE_ERROR;
return ERR_CANT_CONNECT;
}
- // ... we will need to poll more for handshake to finish
+ // ... we will need to poll more for handshake to finish.
} else {
ip_candidates.clear();
status = STATUS_CONNECTED;
@@ -416,7 +413,7 @@ Error HTTPClientTCP::poll() {
} break;
case STATUS_BODY:
case STATUS_CONNECTED: {
- // Check if we are still connected
+ // Check if we are still connected.
if (ssl) {
Ref<StreamPeerSSL> tmp = connection;
tmp->poll();
@@ -428,10 +425,34 @@ Error HTTPClientTCP::poll() {
status = STATUS_CONNECTION_ERROR;
return ERR_CONNECTION_ERROR;
}
- // Connection established, requests can now be made
+ // Connection established, requests can now be made.
return OK;
} break;
case STATUS_REQUESTING: {
+ if (request_buffer->get_available_bytes()) {
+ int avail = request_buffer->get_available_bytes();
+ int pos = request_buffer->get_position();
+ const Vector<uint8_t> data = request_buffer->get_data_array();
+ int wrote = 0;
+ Error err;
+ if (blocking) {
+ err = connection->put_data(data.ptr() + pos, avail);
+ wrote += avail;
+ } else {
+ err = connection->put_partial_data(data.ptr() + pos, avail, wrote);
+ }
+ if (err != OK) {
+ close();
+ status = STATUS_CONNECTION_ERROR;
+ return ERR_CONNECTION_ERROR;
+ }
+ pos += wrote;
+ request_buffer->seek(pos);
+ if (avail - wrote > 0) {
+ return OK;
+ }
+ request_buffer->clear();
+ }
while (true) {
uint8_t byte;
int rec = 0;
@@ -534,7 +555,7 @@ Error HTTPClientTCP::poll() {
return OK;
}
-int HTTPClientTCP::get_response_body_length() const {
+int64_t HTTPClientTCP::get_response_body_length() const {
return body_size;
}
@@ -547,7 +568,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
if (chunked) {
while (true) {
if (chunk_trailer_part) {
- // We need to consume the trailer part too or keep-alive will break
+ // We need to consume the trailer part too or keep-alive will break.
uint8_t b;
int rec = 0;
err = _get_http_data(&b, 1, rec);
@@ -560,18 +581,18 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
int cs = chunk.size();
if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) {
if (cs == 2) {
- // Finally over
+ // Finally over.
chunk_trailer_part = false;
status = STATUS_CONNECTED;
chunk.clear();
break;
} else {
- // We do not process nor return the trailer data
+ // We do not process nor return the trailer data.
chunk.clear();
}
}
} else if (chunk_left == 0) {
- // Reading length
+ // Reading length.
uint8_t b;
int rec = 0;
err = _get_http_data(&b, 1, rec);
@@ -658,7 +679,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
uint8_t *w = ret.ptrw();
err = _get_http_data(w + _offset, to_read, rec);
}
- if (rec <= 0) { // Ended up reading less
+ if (rec <= 0) { // Ended up reading less.
ret.resize(_offset);
break;
} else {
@@ -679,7 +700,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
close();
if (err == ERR_FILE_EOF) {
- status = STATUS_DISCONNECTED; // Server disconnected
+ status = STATUS_DISCONNECTED; // Server disconnected.
} else {
status = STATUS_CONNECTION_ERROR;
}
@@ -759,6 +780,7 @@ void HTTPClientTCP::set_https_proxy(const String &p_host, int p_port) {
HTTPClientTCP::HTTPClientTCP() {
tcp_connection.instantiate();
+ request_buffer.instantiate();
}
HTTPClient *(*HTTPClient::_create)() = HTTPClientTCP::_create_func;
diff --git a/core/io/http_client_tcp.h b/core/io/http_client_tcp.h
index 886ad0ef48..c10e0b1eca 100644
--- a/core/io/http_client_tcp.h
+++ b/core/io/http_client_tcp.h
@@ -38,13 +38,13 @@ private:
Status status = STATUS_DISCONNECTED;
IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
Array ip_candidates;
- int conn_port = -1; // Server to make requests to
+ int conn_port = -1; // Server to make requests to.
String conn_host;
- int server_port = -1; // Server to connect to (might be a proxy server)
+ int server_port = -1; // Server to connect to (might be a proxy server).
String server_host;
- int http_proxy_port = -1; // Proxy server for http requests
+ int http_proxy_port = -1; // Proxy server for http requests.
String http_proxy_host;
- int https_proxy_port = -1; // Proxy server for https requests
+ int https_proxy_port = -1; // Proxy server for https requests.
String https_proxy_host;
bool ssl = false;
bool ssl_verify_host = false;
@@ -62,9 +62,10 @@ private:
int64_t body_left = 0;
bool read_until_eof = false;
+ Ref<StreamPeerBuffer> request_buffer;
Ref<StreamPeerTCP> tcp_connection;
Ref<StreamPeer> connection;
- Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server
+ Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server.
int response_num = 0;
Vector<String> response_headers;
@@ -87,7 +88,7 @@ public:
bool is_response_chunked() const override;
int get_response_code() const override;
Error get_response_headers(List<String> *r_response) override;
- int get_response_body_length() const override;
+ int64_t get_response_body_length() const override;
PackedByteArray read_response_body_chunk() override;
void set_blocking_mode(bool p_enable) override;
bool is_blocking_mode_enabled() const override;
diff --git a/core/io/image.cpp b/core/io/image.cpp
index 4a1f129245..9df2b6835c 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -65,10 +65,6 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
"BPTC_RGBA",
"BPTC_RGBF",
"BPTC_RGBFU",
- "PVRTC1_2", //pvrtc
- "PVRTC1_2A",
- "PVRTC1_4",
- "PVRTC1_4A",
"ETC", //etc1
"ETC2_R11", //etc2
"ETC2_R11S", //signed", NOT srgb.
@@ -148,14 +144,6 @@ int Image::get_format_pixel_size(Format p_format) {
return 1; //float /
case FORMAT_BPTC_RGBFU:
return 1; //unsigned float
- case FORMAT_PVRTC1_2:
- return 1; //pvrtc
- case FORMAT_PVRTC1_2A:
- return 1;
- case FORMAT_PVRTC1_4:
- return 1;
- case FORMAT_PVRTC1_4A:
- return 1;
case FORMAT_ETC:
return 1; //etc1
case FORMAT_ETC2_R11:
@@ -193,16 +181,6 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
r_w = 4;
r_h = 4;
} break;
- case FORMAT_PVRTC1_2:
- case FORMAT_PVRTC1_2A: {
- r_w = 16;
- r_h = 8;
- } break;
- case FORMAT_PVRTC1_4A:
- case FORMAT_PVRTC1_4: {
- r_w = 8;
- r_h = 8;
- } break;
case FORMAT_ETC: {
r_w = 4;
r_h = 4;
@@ -235,10 +213,8 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
}
int Image::get_format_pixel_rshift(Format p_format) {
- if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC1_4 || p_format == FORMAT_PVRTC1_4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) {
+ if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) {
return 1;
- } else if (p_format == FORMAT_PVRTC1_2 || p_format == FORMAT_PVRTC1_2A) {
- return 2;
} else {
return 0;
}
@@ -254,14 +230,6 @@ int Image::get_format_block_size(Format p_format) {
return 4;
}
- case FORMAT_PVRTC1_2:
- case FORMAT_PVRTC1_2A: {
- return 4;
- }
- case FORMAT_PVRTC1_4A:
- case FORMAT_PVRTC1_4: {
- return 4;
- }
case FORMAT_ETC: {
return 4;
}
@@ -1466,12 +1434,11 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
}
// Set mipmap size.
- // It might be necessary to put this after the minimum mipmap size check because of the possible occurrence of "1 >> 1".
if (r_mm_width) {
- *r_mm_width = bw >> 1;
+ *r_mm_width = w;
}
if (r_mm_height) {
- *r_mm_height = bh >> 1;
+ *r_mm_height = h;
}
// Reach target mipmap.
@@ -2222,8 +2189,6 @@ bool Image::is_invisible() const {
} break;
- case FORMAT_PVRTC1_2A:
- case FORMAT_PVRTC1_4A:
case FORMAT_DXT3:
case FORMAT_DXT5: {
detected = true;
@@ -2264,8 +2229,6 @@ Image::AlphaMode Image::detect_alpha() const {
}
} break;
- case FORMAT_PVRTC1_2A:
- case FORMAT_PVRTC1_4A:
case FORMAT_DXT3:
case FORMAT_DXT5: {
detected = true;
@@ -2361,8 +2324,6 @@ Error Image::decompress() {
_image_decompress_bc(this);
} else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) {
_image_decompress_bptc(this);
- } else if (format >= FORMAT_PVRTC1_2 && format <= FORMAT_PVRTC1_4A && _image_decompress_pvrtc) {
- _image_decompress_pvrtc(this);
} else if (format == FORMAT_ETC && _image_decompress_etc1) {
_image_decompress_etc1(this);
} else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) {
@@ -2385,10 +2346,6 @@ Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels
ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE);
_image_compress_bc_func(this, p_lossy_quality, p_channels);
} break;
- case COMPRESS_PVRTC1_4: {
- ERR_FAIL_COND_V(!_image_compress_pvrtc1_4bpp_func, ERR_UNAVAILABLE);
- _image_compress_pvrtc1_4bpp_func(this);
- } break;
case COMPRESS_ETC: {
ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE);
_image_compress_etc1_func(this, p_lossy_quality);
@@ -2752,10 +2709,8 @@ ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr;
void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = nullptr;
void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = nullptr;
-void (*Image::_image_compress_pvrtc1_4bpp_func)(Image *) = nullptr;
void (*Image::_image_compress_etc1_func)(Image *, float) = nullptr;
void (*Image::_image_compress_etc2_func)(Image *, float, Image::UsedChannels) = nullptr;
-void (*Image::_image_decompress_pvrtc)(Image *) = nullptr;
void (*Image::_image_decompress_bc)(Image *) = nullptr;
void (*Image::_image_decompress_bptc)(Image *) = nullptr;
void (*Image::_image_decompress_etc1)(Image *) = nullptr;
@@ -3238,10 +3193,6 @@ void Image::_bind_methods() {
BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h
BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBF); //float /
BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float
- BIND_ENUM_CONSTANT(FORMAT_PVRTC1_2); //pvrtc
- BIND_ENUM_CONSTANT(FORMAT_PVRTC1_2A);
- BIND_ENUM_CONSTANT(FORMAT_PVRTC1_4);
- BIND_ENUM_CONSTANT(FORMAT_PVRTC1_4A);
BIND_ENUM_CONSTANT(FORMAT_ETC); //etc1
BIND_ENUM_CONSTANT(FORMAT_ETC2_R11); //etc2
BIND_ENUM_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb.
@@ -3265,7 +3216,6 @@ void Image::_bind_methods() {
BIND_ENUM_CONSTANT(ALPHA_BLEND);
BIND_ENUM_CONSTANT(COMPRESS_S3TC);
- BIND_ENUM_CONSTANT(COMPRESS_PVRTC1_4);
BIND_ENUM_CONSTANT(COMPRESS_ETC);
BIND_ENUM_CONSTANT(COMPRESS_ETC2);
BIND_ENUM_CONSTANT(COMPRESS_BPTC);
diff --git a/core/io/image.h b/core/io/image.h
index 29236a55e5..ddfb2bb01d 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -89,10 +89,6 @@ public:
FORMAT_BPTC_RGBA, //btpc bc7
FORMAT_BPTC_RGBF, //float bc6h
FORMAT_BPTC_RGBFU, //unsigned float bc6hu
- FORMAT_PVRTC1_2, //pvrtc1
- FORMAT_PVRTC1_2A,
- FORMAT_PVRTC1_4,
- FORMAT_PVRTC1_4A,
FORMAT_ETC, //etc1
FORMAT_ETC2_R11, //etc2
FORMAT_ETC2_R11S, //signed, NOT srgb.
@@ -136,11 +132,9 @@ public:
static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels);
static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels);
- static void (*_image_compress_pvrtc1_4bpp_func)(Image *);
static void (*_image_compress_etc1_func)(Image *, float);
static void (*_image_compress_etc2_func)(Image *, float, UsedChannels p_channels);
- static void (*_image_decompress_pvrtc)(Image *);
static void (*_image_decompress_bc)(Image *);
static void (*_image_decompress_bptc)(Image *);
static void (*_image_decompress_etc1)(Image *);
@@ -332,7 +326,6 @@ public:
enum CompressMode {
COMPRESS_S3TC,
- COMPRESS_PVRTC1_4,
COMPRESS_ETC,
COMPRESS_ETC2,
COMPRESS_BPTC,
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 4970afc1d3..8e0d47e762 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -98,6 +98,11 @@ struct _IP_ResolverPrivate {
if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) {
continue;
}
+ // We might be overriding another result, but we don't care as long as the result is valid.
+ if (response.size()) {
+ String key = get_cache_key(hostname, type);
+ cache[key] = response;
+ }
queue[i].response = response;
queue[i].status.set(response.is_empty() ? IP::RESOLVER_STATUS_ERROR : IP::RESOLVER_STATUS_DONE);
}
@@ -120,30 +125,8 @@ struct _IP_ResolverPrivate {
};
IPAddress IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
- List<IPAddress> res;
- String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
-
- resolver->mutex.lock();
- if (resolver->cache.has(key)) {
- res = resolver->cache[key];
- } else {
- // This should be run unlocked so the resolver thread can keep
- // resolving other requests.
- resolver->mutex.unlock();
- _resolve_hostname(res, p_hostname, p_type);
- resolver->mutex.lock();
- // We might be overriding another result, but we don't care (they are the
- // same hostname).
- resolver->cache[key] = res;
- }
- resolver->mutex.unlock();
-
- for (int i = 0; i < res.size(); ++i) {
- if (res[i].is_valid()) {
- return res[i];
- }
- }
- return IPAddress();
+ const Array addresses = resolve_hostname_addresses(p_hostname, p_type);
+ return addresses.size() ? addresses[0].operator IPAddress() : IPAddress();
}
Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
@@ -159,17 +142,16 @@ Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
resolver->mutex.unlock();
_resolve_hostname(res, p_hostname, p_type);
resolver->mutex.lock();
- // We might be overriding another result, but we don't care (they are the
- // same hostname).
- resolver->cache[key] = res;
+ // We might be overriding another result, but we don't care as long as the result is valid.
+ if (res.size()) {
+ resolver->cache[key] = res;
+ }
}
resolver->mutex.unlock();
Array result;
for (int i = 0; i < res.size(); ++i) {
- if (res[i].is_valid()) {
- result.push_back(String(res[i]));
- }
+ result.push_back(String(res[i]));
}
return result;
}
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 6a0668f027..555d4f6df4 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -52,9 +52,8 @@ ObjectID EncodedObjectAsID::get_object_id() const {
return id;
}
-#define _S(a) ((int32_t)a)
-#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(_S(b) < 0 || _S(a) < 0 || _S(a) > INT_MAX - _S(b), err)
-#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(_S(a) < 0 || _S(b) <= 0 || _S(a) > INT_MAX / _S(b), err)
+#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(((int32_t)(b)) < 0 || ((int32_t)(a)) < 0 || ((int32_t)(a)) > INT_MAX - ((int32_t)(b)), err)
+#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(((int32_t)(a)) < 0 || ((int32_t)(b)) <= 0 || ((int32_t)(a)) > INT_MAX / ((int32_t)(b)), err)
#define ENCODE_MASK 0xFF
#define ENCODE_FLAG_64 1 << 16
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index e90d1695e5..0af236f766 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -39,7 +39,7 @@ void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes");
ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB");
encode_buffer_max_size = next_power_of_2(p_max_size);
- encode_buffer.resize(0);
+ encode_buffer.clear();
}
int PacketPeer::get_encode_buffer_max_size() const {
diff --git a/core/io/resource.h b/core/io/resource.h
index a0800c57cb..dea2160616 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -37,6 +37,8 @@
#include "core/templates/safe_refcount.h"
#include "core/templates/self_list.h"
+class Node;
+
#define RES_BASE_EXTENSION(m_ext) \
public: \
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 8fe1ac29b3..21bf566b1b 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -806,38 +806,26 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
// To find the path of the remapped resource, we extract the locale name after
// the last ':' to match the project locale.
- // We also fall back in case of regional locales as done in TranslationServer::translate
- // (e.g. 'ru_RU' -> 'ru' if the former has no specific mapping).
String locale = TranslationServer::get_singleton()->get_locale();
ERR_FAIL_COND_V_MSG(locale.length() < 2, p_path, "Could not remap path '" + p_path + "' for translation as configured locale '" + locale + "' is invalid.");
- String lang = TranslationServer::get_language_code(locale);
Vector<String> &res_remaps = *translation_remaps.getptr(new_path);
- bool near_match = false;
+ int best_score = 0;
for (int i = 0; i < res_remaps.size(); i++) {
int split = res_remaps[i].rfind(":");
if (split == -1) {
continue;
}
-
String l = res_remaps[i].substr(split + 1).strip_edges();
- if (l == locale) { // Exact match.
- new_path = res_remaps[i].left(split);
- break;
- } else if (near_match) {
- continue; // Already found near match, keep going for potential exact match.
- }
-
- // No exact match (e.g. locale 'ru_RU' but remap is 'ru'), let's look further
- // for a near match (same language code, i.e. first 2 or 3 letters before
- // regional code, if included).
- if (TranslationServer::get_language_code(l) == lang) {
- // Language code matches, that's a near match. Keep looking for exact match.
- near_match = true;
+ int score = TranslationServer::get_singleton()->compare_locales(locale, l);
+ if (score > 0 && score >= best_score) {
new_path = res_remaps[i].left(split);
- continue;
+ best_score = score;
+ if (score == 10) {
+ break; // Exact match, skip the rest.
+ }
}
}
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 28ebe811c9..c65968ef03 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -98,7 +98,7 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
Error err = get_partial_data(&w[0], p_bytes, received);
if (err != OK) {
- data.resize(0);
+ data.clear();
} else if (received != data.size()) {
data.resize(received);
}
@@ -563,7 +563,7 @@ Vector<uint8_t> StreamPeerBuffer::get_data_array() const {
}
void StreamPeerBuffer::clear() {
- data.resize(0);
+ data.clear();
pointer = 0;
}