diff options
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/file_access_compressed.cpp | 20 | ||||
-rw-r--r-- | core/io/image_loader.cpp | 4 | ||||
-rw-r--r-- | core/io/image_loader.h | 4 | ||||
-rw-r--r-- | core/io/marshalls.cpp | 213 | ||||
-rw-r--r-- | core/io/marshalls.h | 21 | ||||
-rw-r--r-- | core/io/packet_peer.cpp | 20 | ||||
-rw-r--r-- | core/io/packet_peer.h | 2 |
7 files changed, 189 insertions, 95 deletions
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 4e802579c6..34bce3f04f 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -43,16 +43,16 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_ block_size = p_block_size; } -#define WRITE_FIT(m_bytes) \ - { \ - if (write_pos + (m_bytes) > write_max) { \ - write_max = write_pos + (m_bytes); \ - } \ - if (write_max > write_buffer_size) { \ - write_buffer_size = nearest_power_of_2(write_max); \ - buffer.resize(write_buffer_size); \ - write_ptr = buffer.ptr(); \ - } \ +#define WRITE_FIT(m_bytes) \ + { \ + if (write_pos + (m_bytes) > write_max) { \ + write_max = write_pos + (m_bytes); \ + } \ + if (write_max > write_buffer_size) { \ + write_buffer_size = next_power_of_2(write_max); \ + buffer.resize(write_buffer_size); \ + write_ptr = buffer.ptr(); \ + } \ } Error FileAccessCompressed::open_after_magic(FileAccess *p_base) { diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 23719940be..7b5b4a13ea 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -43,7 +43,7 @@ bool ImageFormatLoader::recognize(const String &p_extension) const { return false; } -Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear) { +Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear, float p_scale) { ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER); FileAccess *f = p_custom; @@ -62,7 +62,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c if (!loader[i]->recognize(extension)) continue; - Error err = loader[i]->load_image(p_image, f, p_force_linear); + Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale); if (err != ERR_FILE_UNRECOGNIZED) { diff --git a/core/io/image_loader.h b/core/io/image_loader.h index e528d1423b..f79d9789bf 100644 --- a/core/io/image_loader.h +++ b/core/io/image_loader.h @@ -56,7 +56,7 @@ class ImageFormatLoader { friend class ImageLoader; protected: - virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear) = 0; + virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) = 0; virtual void get_recognized_extensions(List<String> *p_extensions) const = 0; bool recognize(const String &p_extension) const; @@ -75,7 +75,7 @@ class ImageLoader { protected: public: - static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false); + static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false, float p_scale = 1.0); static void get_recognized_extensions(List<String> *p_extensions); static bool recognize(const String &p_extension); diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 8eb40b61d7..e701a89c78 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -33,8 +33,28 @@ #include "reference.h" #include <stdio.h> +void EncodedObjectAsID::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_object_id", "id"), &EncodedObjectAsID::set_object_id); + ClassDB::bind_method(D_METHOD("get_object_id"), &EncodedObjectAsID::get_object_id); +} + +void EncodedObjectAsID::set_object_id(ObjectID p_id) { + id = p_id; +} + +ObjectID EncodedObjectAsID::get_object_id() const { + + return id; +} + +EncodedObjectAsID::EncodedObjectAsID() { + + id = 0; +} + #define ENCODE_MASK 0xFF #define ENCODE_FLAG_64 1 << 16 +#define ENCODE_FLAG_OBJECT_AS_ID 1 << 16 static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r_string) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); @@ -381,56 +401,74 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; case Variant::OBJECT: { - ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED); - - String str; - Error err = _decode_string(buf, len, r_len, str); - if (err) - return err; + if (type & ENCODE_FLAG_OBJECT_AS_ID) { + //this _is_ allowed + ObjectID val = decode_uint64(buf); + if (r_len) + (*r_len) += 8; - if (str == String()) { - r_variant = (Object *)NULL; - } else { + if (val == 0) { + r_variant = (Object *)NULL; + } else { + Ref<EncodedObjectAsID> obj_as_id; + obj_as_id.instance(); + obj_as_id->set_object_id(val); - Object *obj = ClassDB::instance(str); + r_variant = obj_as_id; + } - ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE); - ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + } else { + ERR_FAIL_COND_V(!p_allow_objects, ERR_UNAUTHORIZED); - int32_t count = decode_uint32(buf); - buf += 4; - len -= 4; - if (r_len) { - (*r_len) += 4; - } + String str; + Error err = _decode_string(buf, len, r_len, str); + if (err) + return err; - for (int i = 0; i < count; i++) { + if (str == String()) { + r_variant = (Object *)NULL; + } else { - str = String(); - err = _decode_string(buf, len, r_len, str); - if (err) - return err; + Object *obj = ClassDB::instance(str); - Variant value; - int used; - err = decode_variant(value, buf, len, &used, p_allow_objects); - if (err) - return err; + ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE); + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); - buf += used; - len -= used; + int32_t count = decode_uint32(buf); + buf += 4; + len -= 4; if (r_len) { - (*r_len) += used; + (*r_len) += 4; } - obj->set(str, value); - } + for (int i = 0; i < count; i++) { - if (obj->cast_to<Reference>()) { - REF ref = REF(obj->cast_to<Reference>()); - r_variant = ref; - } else { - r_variant = obj; + str = String(); + err = _decode_string(buf, len, r_len, str); + if (err) + return err; + + Variant value; + int used; + err = decode_variant(value, buf, len, &used, p_allow_objects); + if (err) + return err; + + buf += used; + len -= used; + if (r_len) { + (*r_len) += used; + } + + obj->set(str, value); + } + + if (obj->cast_to<Reference>()) { + REF ref = REF(obj->cast_to<Reference>()); + r_variant = ref; + } else { + r_variant = obj; + } } } @@ -769,14 +807,19 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) { encode_uint32(utf8.length(), buf); buf += 4; copymem(buf, utf8.get_data(), utf8.length()); + buf += utf8.length(); } r_len += 4 + utf8.length(); - while (r_len % 4) + while (r_len % 4) { r_len++; //pad + if (buf) { + buf++; + } + } } -Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { +Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id) { uint8_t *buf = r_buffer; @@ -800,6 +843,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { flags |= ENCODE_FLAG_64; //always encode real as double } } break; + case Variant::OBJECT: { + if (p_object_as_id) { + flags |= ENCODE_FLAG_OBJECT_AS_ID; + } + } break; } if (buf) { @@ -1071,49 +1119,66 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { } break; case Variant::OBJECT: { - Object *obj = p_variant; - if (!obj) { + if (p_object_as_id) { + if (buf) { - encode_uint32(0, buf); - buf += 4; - r_len += 4; + + Object *obj = p_variant; + ObjectID id = 0; + if (obj && ObjectDB::instance_validate(obj)) { + id = obj->get_instance_id(); + } + + encode_uint64(id, buf); } + + r_len += 8; + } else { - _encode_string(obj->get_class(), buf, r_len); + Object *obj = p_variant; + if (!obj) { + if (buf) { + encode_uint32(0, buf); + buf += 4; + r_len += 4; + } + } else { + _encode_string(obj->get_class(), buf, r_len); - List<PropertyInfo> props; - obj->get_property_list(&props); + List<PropertyInfo> props; + obj->get_property_list(&props); - int pc = 0; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + int pc = 0; + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) - continue; - pc++; - } + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; + pc++; + } - if (buf) { - encode_uint32(pc, buf); - buf += 4; - } + if (buf) { + encode_uint32(pc, buf); + buf += 4; + } - r_len += 4; + r_len += 4; - for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { + for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) - continue; + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; - _encode_string(E->get().name, buf, r_len); + _encode_string(E->get().name, buf, r_len); - int len; - Error err = encode_variant(obj->get(E->get().name), buf, len); - if (err) - return err; - ERR_FAIL_COND_V(len % 4, ERR_BUG); - r_len += len; - if (buf) - buf += len; + int len; + Error err = encode_variant(obj->get(E->get().name), buf, len, p_object_as_id); + if (err) + return err; + ERR_FAIL_COND_V(len % 4, ERR_BUG); + r_len += len; + if (buf) + buf += len; + } } } @@ -1147,12 +1212,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { r_len++; //pad */ int len; - encode_variant(E->get(), buf, len); + encode_variant(E->get(), buf, len, p_object_as_id); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) buf += len; - encode_variant(d[E->get()], buf, len); + encode_variant(d[E->get()], buf, len, p_object_as_id); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) @@ -1174,7 +1239,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { for (int i = 0; i < v.size(); i++) { int len; - encode_variant(v.get(i), buf, len); + encode_variant(v.get(i), buf, len, p_object_as_id); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) diff --git a/core/io/marshalls.h b/core/io/marshalls.h index a6cc72b691..234ae3b183 100644 --- a/core/io/marshalls.h +++ b/core/io/marshalls.h @@ -32,8 +32,8 @@ #include "typedefs.h" +#include "reference.h" #include "variant.h" - /** * Miscellaneous helpers for marshalling data types, and encoding * in an endian independent way @@ -183,7 +183,22 @@ static inline double decode_double(const uint8_t *p_arr) { return md.d; } -Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects=true); -Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len); +class EncodedObjectAsID : public Reference { + GDCLASS(EncodedObjectAsID, Reference); + + ObjectID id; + +protected: + static void _bind_methods(); + +public: + void set_object_id(ObjectID p_id); + ObjectID get_object_id() const; + + EncodedObjectAsID(); +}; + +Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects = true); +Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id = false); #endif diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index f62ffd7183..ca00b8b480 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -92,7 +92,7 @@ Error PacketPeer::get_var(Variant &r_variant) const { Error PacketPeer::put_var(const Variant &p_packet) { int len; - Error err = encode_variant(p_packet, NULL, len); // compute len first + Error err = encode_variant(p_packet, NULL, len, !allow_object_decoding); // compute len first if (err) return err; @@ -101,7 +101,7 @@ Error PacketPeer::put_var(const Variant &p_packet) { uint8_t *buf = (uint8_t *)alloca(len); ERR_FAIL_COND_V(!buf, ERR_OUT_OF_MEMORY); - err = encode_variant(p_packet, buf, len); + err = encode_variant(p_packet, buf, len, !allow_object_decoding); ERR_FAIL_COND_V(err, err); return put_packet(buf, len); @@ -155,6 +155,8 @@ void PacketPeerStream::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream_peer", "peer"), &PacketPeerStream::_set_stream_peer); ClassDB::bind_method(D_METHOD("set_input_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_input_buffer_max_size); ClassDB::bind_method(D_METHOD("set_output_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_output_buffer_max_size); + ClassDB::bind_method(D_METHOD("get_input_buffer_max_size"), &PacketPeerStream::get_input_buffer_max_size); + ClassDB::bind_method(D_METHOD("get_output_buffer_max_size"), &PacketPeerStream::get_output_buffer_max_size); } Error PacketPeerStream::_poll_buffer() const { @@ -265,12 +267,22 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) { ERR_EXPLAIN("Buffer in use, resizing would cause loss of data"); ERR_FAIL_COND(ring_buffer.data_left()); ring_buffer.resize(nearest_shift(p_max_size + 4)); - input_buffer.resize(nearest_power_of_2(p_max_size + 4)); + input_buffer.resize(next_power_of_2(p_max_size + 4)); +} + +int PacketPeerStream::get_input_buffer_max_size() const { + + return input_buffer.size() - 4; } void PacketPeerStream::set_output_buffer_max_size(int p_max_size) { - output_buffer.resize(nearest_power_of_2(p_max_size + 4)); + output_buffer.resize(next_power_of_2(p_max_size + 4)); +} + +int PacketPeerStream::get_output_buffer_max_size() const { + + return output_buffer.size() - 4; } PacketPeerStream::PacketPeerStream() { diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h index 3bd6876aa7..597119f7f4 100644 --- a/core/io/packet_peer.h +++ b/core/io/packet_peer.h @@ -98,7 +98,9 @@ public: void set_stream_peer(const Ref<StreamPeer> &p_peer); void set_input_buffer_max_size(int p_max_size); + int get_input_buffer_max_size() const; void set_output_buffer_max_size(int p_max_size); + int get_output_buffer_max_size() const; PacketPeerStream(); }; |