diff options
Diffstat (limited to 'core/io/marshalls.cpp')
-rw-r--r-- | core/io/marshalls.cpp | 148 |
1 files changed, 136 insertions, 12 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index f5f9d34439..df951c759a 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -264,26 +264,94 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * } r_variant=img; - if (r_len) + if (r_len) { + if (datalen%4) + (*r_len)+=4-datalen%4; + (*r_len)+=4*5+datalen; + } } break; case Variant::NODE_PATH: { - ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); - buf+=4; - len-=4; - ERR_FAIL_COND_V((int)strlen>len,ERR_INVALID_DATA); + if (strlen&0x80000000) { + //new format + ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA); + Vector<StringName> names; + Vector<StringName> subnames; + bool absolute; + StringName prop; - String str; - str.parse_utf8((const char*)buf,strlen); + int i=0; + uint32_t namecount=strlen&=0x7FFFFFFF; + uint32_t subnamecount = decode_uint32(buf+4); + uint32_t flags = decode_uint32(buf+8); - r_variant=NodePath(str); + len-=12; + buf+=12; - if (r_len) - (*r_len)+=4+strlen; + int total=namecount+subnamecount; + if (flags&2) + total++; + + if (r_len) + (*r_len)+=12; + + + for(int i=0;i<total;i++) { + + ERR_FAIL_COND_V((int)len<4,ERR_INVALID_DATA); + strlen = decode_uint32(buf); + + int pad=0; + + if (strlen%4) + pad+=4-strlen%4; + + buf+=4; + len-=4; + ERR_FAIL_COND_V((int)strlen+pad>len,ERR_INVALID_DATA); + + String str; + str.parse_utf8((const char*)buf,strlen); + + + if (i<namecount) + names.push_back(str); + else if (i<namecount+subnamecount) + subnames.push_back(str); + else + prop=str; + + buf+=strlen+pad; + len-=strlen+pad; + + if (r_len) + (*r_len)+=4+strlen+pad; + + } + + r_variant=NodePath(names,subnames,flags&1,prop); + + } else { + //old format, just a string + + buf+=4; + len-=4; + ERR_FAIL_COND_V((int)strlen>len,ERR_INVALID_DATA); + + + String str; + str.parse_utf8((const char*)buf,strlen); + + r_variant=NodePath(str); + + if (r_len) + (*r_len)+=4+strlen; + } } break; /*case Variant::RESOURCE: { @@ -713,7 +781,59 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) { r_len+=4; } break; - case Variant::NODE_PATH: + case Variant::NODE_PATH: { + + NodePath np=p_variant; + if (buf) { + encode_uint32(uint32_t(np.get_name_count())|0x80000000,buf); //for compatibility with the old format + encode_uint32(np.get_subname_count(),buf+4); + uint32_t flags=0; + if (np.is_absolute()) + flags|=1; + if (np.get_property()!=StringName()) + flags|=2; + + encode_uint32(flags,buf+8); + + buf+=12; + } + + r_len+=12; + + int total = np.get_name_count()+np.get_subname_count(); + if (np.get_property()!=StringName()) + total++; + + for(int i=0;i<total;i++) { + + String str; + + if (i<np.get_name_count()) + str=np.get_name(i); + else if (i<np.get_name_count()+np.get_subname_count()) + str=np.get_subname(i-np.get_subname_count()); + else + str=np.get_property(); + + CharString utf8 = str.utf8(); + + int pad = 0; + + if (utf8.length()%4) + pad=4-utf8.length()%4; + + if (buf) { + encode_uint32(utf8.length(),buf); + buf+=4; + copymem(buf,utf8.get_data(),utf8.length()); + buf+=pad+utf8.length(); + } + + + r_len+=4+utf8.length()+pad; + } + + } break; case Variant::STRING: { @@ -879,7 +999,11 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) { copymem(&buf[20],&r[0],ds); } - r_len+=data.size()+5*4; + int pad=0; + if (data.size()%4) + pad=4-data.size()%4; + + r_len+=data.size()+5*4+pad; } break; /*case Variant::RESOURCE: { |