diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-02-09 22:10:30 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-02-09 22:10:30 -0300 |
commit | 0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac (patch) | |
tree | 276c4d099e178eb67fbd14f61d77b05e3808e9e3 /core/io/marshalls.cpp | |
parent | 0e49da1687bc8192ed210947da52c9e5c5f301bb (diff) |
GODOT IS OPEN SOURCE
Diffstat (limited to 'core/io/marshalls.cpp')
-rw-r--r-- | core/io/marshalls.cpp | 1195 |
1 files changed, 1195 insertions, 0 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp new file mode 100644 index 0000000000..f5f9d34439 --- /dev/null +++ b/core/io/marshalls.cpp @@ -0,0 +1,1195 @@ +/*************************************************************************/ +/* marshalls.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 "marshalls.h" +#include "print_string.h" +#include "os/keyboard.h" +#include <stdio.h> + +Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *r_len) { + + const uint8_t * buf=p_buffer; + int len=p_len; + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + + + uint32_t type=decode_uint32(buf); + + ERR_FAIL_COND_V(type>=Variant::VARIANT_MAX,ERR_INVALID_DATA); + + buf+=4; + len-=4; + if (r_len) + *r_len=4; + + switch(type) { + + case Variant::NIL: { + + r_variant=Variant(); + } break; + case Variant::BOOL: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + bool val = decode_uint32(buf); + r_variant=val; + if (r_len) + (*r_len)+=4; + } break; + case Variant::INT: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + int val = decode_uint32(buf); + r_variant=val; + if (r_len) + (*r_len)+=4; + + } break; + case Variant::REAL: { + + ERR_FAIL_COND_V(len<(int)4,ERR_INVALID_DATA); + float val = decode_float(buf); + r_variant=val; + if (r_len) + (*r_len)+=4; + + } break; + case Variant::STRING: { + + 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); + + String str; + str.parse_utf8((const char*)buf,strlen); + r_variant=str; + + if (r_len) { + if (strlen%4) + (*r_len)+=4-strlen%4; + (*r_len)+=4+strlen; + + } + + } break; + // math types + + case Variant::VECTOR2: { + + ERR_FAIL_COND_V(len<(int)4*2,ERR_INVALID_DATA); + Vector2 val; + val.x=decode_float(&buf[0]); + val.y=decode_float(&buf[4]); + r_variant=val; + + if (r_len) + (*r_len)+=4*2; + + } break; // 5 + case Variant::RECT2: { + + ERR_FAIL_COND_V(len<(int)4*4,ERR_INVALID_DATA); + Rect2 val; + val.pos.x=decode_float(&buf[0]); + val.pos.y=decode_float(&buf[4]); + val.size.x=decode_float(&buf[8]); + val.size.y=decode_float(&buf[12]); + r_variant=val; + + if (r_len) + (*r_len)+=4*4; + + } break; + case Variant::VECTOR3: { + + ERR_FAIL_COND_V(len<(int)4*3,ERR_INVALID_DATA); + Vector3 val; + val.x=decode_float(&buf[0]); + val.y=decode_float(&buf[4]); + val.z=decode_float(&buf[8]); + r_variant=val; + + if (r_len) + (*r_len)+=4*3; + + } break; + case Variant::PLANE: { + + ERR_FAIL_COND_V(len<(int)4*4,ERR_INVALID_DATA); + Plane val; + val.normal.x=decode_float(&buf[0]); + val.normal.y=decode_float(&buf[4]); + val.normal.z=decode_float(&buf[8]); + val.d=decode_float(&buf[12]); + r_variant=val; + + if (r_len) + (*r_len)+=4*4; + + } break; + case Variant::QUAT: { + + ERR_FAIL_COND_V(len<(int)4*4,ERR_INVALID_DATA); + Quat val; + val.x=decode_float(&buf[0]); + val.y=decode_float(&buf[4]); + val.z=decode_float(&buf[8]); + val.w=decode_float(&buf[12]); + r_variant=val; + + if (r_len) + (*r_len)+=4*4; + + } break; + case Variant::_AABB: { + + ERR_FAIL_COND_V(len<(int)4*6,ERR_INVALID_DATA); + AABB val; + val.pos.x=decode_float(&buf[0]); + val.pos.y=decode_float(&buf[4]); + val.pos.z=decode_float(&buf[8]); + val.size.x=decode_float(&buf[12]); + val.size.y=decode_float(&buf[16]); + val.size.z=decode_float(&buf[20]); + r_variant=val; + + if (r_len) + (*r_len)+=4*6; + + } break; + case Variant::MATRIX3: { + + ERR_FAIL_COND_V(len<(int)4*9,ERR_INVALID_DATA); + Matrix3 val; + for(int i=0;i<3;i++) { + for(int j=0;j<3;j++) { + + val.elements[i][j]=decode_float(&buf[(i*3+j)*4]); + } + } + + r_variant=val; + + if (r_len) + (*r_len)+=4*9; + + } break; + case Variant::TRANSFORM: { + + ERR_FAIL_COND_V(len<(int)4*12,ERR_INVALID_DATA); + Transform val; + for(int i=0;i<3;i++) { + for(int j=0;j<3;j++) { + + val.basis.elements[i][j]=decode_float(&buf[(i*3+j)*4]); + } + } + val.origin[0]=decode_float(&buf[36]); + val.origin[1]=decode_float(&buf[40]); + val.origin[2]=decode_float(&buf[44]); + + r_variant=val; + + if (r_len) + (*r_len)+=4*12; + + } break; + + // misc types + case Variant::COLOR: { + + ERR_FAIL_COND_V(len<(int)4*4,ERR_INVALID_DATA); + Color val; + val.r=decode_float(&buf[0]); + val.g=decode_float(&buf[4]); + val.b=decode_float(&buf[8]); + val.a=decode_float(&buf[12]); + r_variant=val; + + if (r_len) + (*r_len)+=4*4; + + } break; + case Variant::IMAGE: { + + ERR_FAIL_COND_V(len<(int)5*4,ERR_INVALID_DATA); + Image::Format fmt = (Image::Format)decode_uint32(&buf[0]); + ERR_FAIL_INDEX_V( fmt, Image::FORMAT_MAX, ERR_INVALID_DATA); + uint32_t mipmaps = decode_uint32(&buf[4]); + uint32_t w = decode_uint32(&buf[8]); + uint32_t h = decode_uint32(&buf[12]); + uint32_t datalen = decode_uint32(&buf[16]); + + Image img; + if (datalen>0) { + len-=5*4; + ERR_FAIL_COND_V( len < datalen, ERR_INVALID_DATA ); + DVector<uint8_t> data; + data.resize(datalen); + DVector<uint8_t>::Write wr = data.write(); + copymem(&wr[0],&buf[20],datalen); + wr = DVector<uint8_t>::Write(); + + + + img=Image(w,h,mipmaps,fmt,data); + } + + r_variant=img; + if (r_len) + (*r_len)+=4*5+datalen; + + } break; + case Variant::NODE_PATH: { + + 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); + + + String str; + str.parse_utf8((const char*)buf,strlen); + + r_variant=NodePath(str); + + if (r_len) + (*r_len)+=4+strlen; + + } break; + /*case Variant::RESOURCE: { + + ERR_EXPLAIN("Can't marshallize resources"); + ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go + } break;*/ + case Variant::_RID: { + + r_variant = RID(); + } break; + case Variant::OBJECT: { + + + r_variant = (Object*)NULL; + } break; + case Variant::INPUT_EVENT: { + + InputEvent ie; + + ie.type=decode_uint32(&buf[0]); + ie.device=decode_uint32(&buf[4]); + uint32_t len = decode_uint32(&buf[8])-12; + + if (r_len) + (*r_len)+=12; + + switch(ie.type) { + + case InputEvent::KEY: { + + uint32_t mods=decode_uint32(&buf[12]); + if (mods&KEY_MASK_SHIFT) + ie.key.mod.shift=true; + if (mods&KEY_MASK_CTRL) + ie.key.mod.control=true; + if (mods&KEY_MASK_ALT) + ie.key.mod.alt=true; + if (mods&KEY_MASK_META) + ie.key.mod.meta=true; + ie.key.scancode=decode_uint32(&buf[16]); + + if (r_len) + (*r_len)+=8; + + + } break; + case InputEvent::MOUSE_BUTTON: { + + ie.mouse_button.button_index=decode_uint32(&buf[12]); + if (r_len) + (*r_len)+=4; + + } break; + case InputEvent::JOYSTICK_BUTTON: { + + ie.joy_button.button_index=decode_uint32(&buf[12]); + if (r_len) + (*r_len)+=4; + } break; + case InputEvent::SCREEN_TOUCH: { + + ie.screen_touch.index=decode_uint32(&buf[12]); + if (r_len) + (*r_len)+=4; + } break; + case InputEvent::JOYSTICK_MOTION: { + + ie.joy_motion.axis=decode_uint32(&buf[12]); + if (r_len) + (*r_len)+=4; + } break; + } + + r_variant = ie; + + } break; + case Variant::DICTIONARY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + bool shared = count&0x80000000; + count&=0x7FFFFFFF; + + buf+=4; + len-=4; + + if (r_len) { + (*r_len)+=4; + } + + Dictionary d(shared); + + for(uint32_t i=0;i<count;i++) { + + Variant key,value; + + int used; + Error err = decode_variant(key,buf,len,&used); + ERR_FAIL_COND_V(err,err); + + buf+=used; + len-=used; + if (r_len) { + (*r_len)+=used; + } + + err = decode_variant(value,buf,len,&used); + ERR_FAIL_COND_V(err,err); + + buf+=used; + len-=used; + if (r_len) { + (*r_len)+=used; + } + + d[key]=value; + } + + r_variant=d; + + } break; + case Variant::ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + bool shared = count&0x80000000; + count&=0x7FFFFFFF; + + buf+=4; + len-=4; + + if (r_len) { + (*r_len)+=4; + } + + Array varr(shared); + + for(uint32_t i=0;i<count;i++) { + + int used=0; + Variant v; + Error err = decode_variant(v,buf,len,&used); + ERR_FAIL_COND_V(err,err); + buf+=used; + len-=used; + varr.push_back(v); + if (r_len) { + (*r_len)+=used; + } + } + + r_variant=varr; + + + } break; + + // arrays + case Variant::RAW_ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + buf+=4; + len-=4; + ERR_FAIL_COND_V((int)count>len,ERR_INVALID_DATA); + + + DVector<uint8_t> data; + + if (count) { + data.resize(count); + DVector<uint8_t>::Write w = data.write(); + for(int i=0;i<count;i++) { + + w[i]=buf[i]; + } + + w = DVector<uint8_t>::Write(); + } + + r_variant=data; + + if (r_len) { + if (count%4) + (*r_len)+=4-count%4; + (*r_len)+=4+count; + } + + + + } break; + case Variant::INT_ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + buf+=4; + len-=4; + ERR_FAIL_COND_V((int)count*4>len,ERR_INVALID_DATA); + + DVector<int> data; + + if (count) { + //const int*rbuf=(const int*)buf; + data.resize(count); + DVector<int>::Write w = data.write(); + for(int i=0;i<count;i++) { + + w[i]=decode_uint32(&buf[i*4]); + } + + w = DVector<int>::Write(); + } + r_variant=Variant(data); + if (r_len) { + (*r_len)+=4+count*sizeof(int); + } + + } break; + case Variant::REAL_ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + buf+=4; + len-=4; + ERR_FAIL_COND_V((int)count*4>len,ERR_INVALID_DATA); + + DVector<float> data; + + if (count) { + //const float*rbuf=(const float*)buf; + data.resize(count); + DVector<float>::Write w = data.write(); + for(int i=0;i<count;i++) { + + w[i]=decode_float(&buf[i*4]); + } + + w = DVector<float>::Write(); + } + r_variant=data; + + if (r_len) { + (*r_len)+=4+count*sizeof(float); + } + + + } break; + case Variant::STRING_ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + ERR_FAIL_COND_V(count<0,ERR_INVALID_DATA); + + DVector<String> strings; + buf+=4; + len-=4; + + if (r_len) + (*r_len)+=4; + //printf("string count: %i\n",count); + + for(int i=0;i<(int)count;i++) { + + 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); + + //printf("loaded string: %s\n",(const char*)buf); + String str; + str.parse_utf8((const char*)buf,strlen); + + strings.push_back(str); + + buf+=strlen; + len-=strlen; + + if (r_len) + (*r_len)+=4+strlen; + + if (strlen%4) { + int pad = 4-(strlen%4); + buf+=pad; + len-=pad; + if (r_len) { + (*r_len)+=pad; + } + } + + } + + r_variant=strings; + + + } break; + case Variant::VECTOR3_ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + ERR_FAIL_COND_V(count<0,ERR_INVALID_DATA); + buf+=4; + len-=4; + + ERR_FAIL_COND_V((int)count*4*3>len,ERR_INVALID_DATA); + DVector<Vector3> varray; + + if (r_len) { + (*r_len)+=4; + } + + if (count) { + varray.resize(count); + DVector<Vector3>::Write w = varray.write(); + const float *r = (const float*)buf; + + for(int i=0;i<(int)count;i++) { + + w[i].x=decode_float(buf+i*4*3+4*0); + w[i].y=decode_float(buf+i*4*3+4*1); + w[i].z=decode_float(buf+i*4*3+4*2); + + } + + int adv = 4*3*count; + + if (r_len) + (*r_len)+=adv; + len-=adv; + buf+=adv; + + } + + r_variant=varray; + + } break; + case Variant::COLOR_ARRAY: { + + ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); + uint32_t count = decode_uint32(buf); + ERR_FAIL_COND_V(count<0,ERR_INVALID_DATA); + buf+=4; + len-=4; + + ERR_FAIL_COND_V((int)count*4*4>len,ERR_INVALID_DATA); + DVector<Color> carray; + + if (r_len) { + (*r_len)+=4; + } + + if (count) { + carray.resize(count); + DVector<Color>::Write w = carray.write(); + const float *r = (const float*)buf; + + for(int i=0;i<(int)count;i++) { + + w[i].r=decode_float(buf+i*4*4+4*0); + w[i].g=decode_float(buf+i*4*4+4*1); + w[i].b=decode_float(buf+i*4*4+4*2); + w[i].a=decode_float(buf+i*4*4+4*3); + + } + + int adv = 4*4*count; + + if (r_len) + (*r_len)+=adv; + len-=adv; + buf+=adv; + + } + + r_variant=carray; + + } break; + default: { ERR_FAIL_V(ERR_BUG); } + } + + return OK; +} + +Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) { + + uint8_t * buf=r_buffer; + + r_len=0; + + if (buf) { + encode_uint32(p_variant.get_type(),buf); + buf+=4; + } + r_len+=4; + + switch(p_variant.get_type()) { + + case Variant::NIL: { + + //nothing to do + } break; + case Variant::BOOL: { + + if (buf) { + encode_uint32(p_variant.operator bool(),buf); + } + + r_len+=4; + + } break; + case Variant::INT: { + + if (buf) { + encode_uint32(p_variant.operator int(),buf); + } + + r_len+=4; + + } break; + case Variant::REAL: { + + if (buf) { + encode_float(p_variant.operator float(),buf); + } + + r_len+=4; + + } break; + case Variant::NODE_PATH: + case Variant::STRING: { + + + CharString utf8 = p_variant.operator String().utf8(); + + if (buf) { + encode_uint32(utf8.length(),buf); + buf+=4; + copymem(buf,utf8.get_data(),utf8.length()); + } + + r_len+=4+utf8.length(); + while (r_len%4) + r_len++; //pad + + } break; + // math types + + case Variant::VECTOR2: { + + if (buf) { + Vector2 v2=p_variant; + encode_float(v2.x,&buf[0]); + encode_float(v2.y,&buf[4]); + + } + + r_len+=2*4; + + } break; // 5 + case Variant::RECT2: { + + if (buf) { + Rect2 r2=p_variant; + encode_float(r2.pos.x,&buf[0]); + encode_float(r2.pos.y,&buf[4]); + encode_float(r2.size.x,&buf[8]); + encode_float(r2.size.y,&buf[12]); + } + r_len+=4*4; + + } break; + case Variant::VECTOR3: { + + if (buf) { + Vector3 v3=p_variant; + encode_float(v3.x,&buf[0]); + encode_float(v3.y,&buf[4]); + encode_float(v3.z,&buf[8]); + } + + r_len+=3*4; + + } break; + case Variant::PLANE: { + + if (buf) { + Plane p=p_variant; + encode_float(p.normal.x,&buf[0]); + encode_float(p.normal.y,&buf[4]); + encode_float(p.normal.z,&buf[8]); + encode_float(p.d,&buf[12]); + } + + r_len+=4*4; + + } break; + case Variant::QUAT: { + + if (buf) { + Quat q=p_variant; + encode_float(q.x,&buf[0]); + encode_float(q.y,&buf[4]); + encode_float(q.z,&buf[8]); + encode_float(q.w,&buf[12]); + } + + r_len+=4*4; + + } break; + case Variant::_AABB: { + + if (buf) { + AABB aabb=p_variant; + encode_float(aabb.pos.x,&buf[0]); + encode_float(aabb.pos.y,&buf[4]); + encode_float(aabb.pos.z,&buf[8]); + encode_float(aabb.size.x,&buf[12]); + encode_float(aabb.size.y,&buf[16]); + encode_float(aabb.size.z,&buf[20]); + } + + r_len+=6*4; + + + } break; + case Variant::MATRIX3: { + + if (buf) { + Matrix3 val=p_variant; + for(int i=0;i<3;i++) { + for(int j=0;j<3;j++) { + + copymem(&buf[(i*3+j)*4],&val.elements[i][j],sizeof(float)); + } + } + } + + + r_len+=9*4; + + } break; + case Variant::TRANSFORM: { + + if (buf) { + Transform val=p_variant; + for(int i=0;i<3;i++) { + for(int j=0;j<3;j++) { + + copymem(&buf[(i*3+j)*4],&val.basis.elements[i][j],sizeof(float)); + } + } + + encode_float(val.origin.x,&buf[36]); + encode_float(val.origin.y,&buf[40]); + encode_float(val.origin.z,&buf[44]); + + + } + + r_len+=12*4; + + } break; + + // misc types + case Variant::COLOR: { + + if (buf) { + Color c=p_variant; + encode_float(c.r,&buf[0]); + encode_float(c.g,&buf[4]); + encode_float(c.b,&buf[8]); + encode_float(c.a,&buf[12]); + } + + r_len+=4*4; + + } break; + case Variant::IMAGE: { + + Image image = p_variant; + DVector<uint8_t> data=image.get_data(); + + if (buf) { + + encode_uint32(image.get_format(),&buf[0]); + encode_uint32(image.get_mipmaps(),&buf[4]); + encode_uint32(image.get_width(),&buf[8]); + encode_uint32(image.get_height(),&buf[12]); + int ds=data.size(); + encode_uint32(ds,&buf[16]); + DVector<uint8_t>::Read r = data.read(); + copymem(&buf[20],&r[0],ds); + } + + r_len+=data.size()+5*4; + + } break; + /*case Variant::RESOURCE: { + + ERR_EXPLAIN("Can't marshallize resources"); + ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go + } break;*/ + case Variant::_RID: + case Variant::OBJECT: { + + + } break; + case Variant::INPUT_EVENT: { + + + InputEvent ie=p_variant; + + if (buf) { + + encode_uint32(ie.type,&buf[0]); + encode_uint32(ie.device,&buf[4]); + encode_uint32(0,&buf[8]); + } + + int llen=12; + + switch(ie.type) { + + case InputEvent::KEY: { + + if (buf) { + + uint32_t mods=0; + if (ie.key.mod.shift) + mods|=KEY_MASK_SHIFT; + if (ie.key.mod.control) + mods|=KEY_MASK_CTRL; + if (ie.key.mod.alt) + mods|=KEY_MASK_ALT; + if (ie.key.mod.meta) + mods|=KEY_MASK_META; + + encode_uint32(mods,&buf[llen]); + encode_uint32(ie.key.scancode,&buf[llen+4]); + } + llen+=8; + + } break; + case InputEvent::MOUSE_BUTTON: { + + if (buf) { + + encode_uint32(ie.mouse_button.button_index,&buf[llen]); + } + llen+=4; + } break; + case InputEvent::JOYSTICK_BUTTON: { + + if (buf) { + + encode_uint32(ie.joy_button.button_index,&buf[llen]); + } + llen+=4; + } break; + case InputEvent::SCREEN_TOUCH: { + + if (buf) { + + encode_uint32(ie.screen_touch.index,&buf[llen]); + } + llen+=4; + } break; + case InputEvent::JOYSTICK_MOTION: { + + if (buf) { + + int axis = ie.joy_motion.axis; + encode_uint32(axis,&buf[llen]); + } + llen+=4; + } break; + } + + if (buf) + encode_uint32(llen,&buf[8]); + r_len+=llen; + + + // not supported + } break; + case Variant::DICTIONARY: { + + Dictionary d = p_variant; + + if (buf) { + encode_uint32(uint32_t(d.size())|(d.is_shared()?0x80000000:0),buf); + buf+=4; + } + r_len+=4; + + List<Variant> keys; + d.get_key_list(&keys); + + + for(List<Variant>::Element *E=keys.front();E;E=E->next()) { + + /* + CharString utf8 = E->->utf8(); + + if (buf) { + encode_uint32(utf8.length()+1,buf); + buf+=4; + copymem(buf,utf8.get_data(),utf8.length()+1); + } + + r_len+=4+utf8.length()+1; + while (r_len%4) + r_len++; //pad + */ + int len; + encode_variant(E->get(),buf,len); + ERR_FAIL_COND_V(len%4,ERR_BUG); + r_len+=len; + if (buf) + buf += len; + encode_variant(d[E->get()],buf,len); + ERR_FAIL_COND_V(len%4,ERR_BUG); + r_len+=len; + if (buf) + buf += len; + } + + } break; + case Variant::ARRAY: { + + Array v = p_variant; + + if (buf) { + encode_uint32(uint32_t(v.size())|(v.is_shared()?0x80000000:0),buf); + buf+=4; + } + + r_len+=4; + + for(int i=0;i<v.size();i++) { + + int len; + encode_variant(v.get(i),buf,len); + ERR_FAIL_COND_V(len%4,ERR_BUG); + r_len+=len; + if (buf) + buf+=len; + } + + + } break; + // arrays + case Variant::RAW_ARRAY: { + + DVector<uint8_t> data = p_variant; + int datalen=data.size(); + int datasize=sizeof(uint8_t); + + if (buf) { + encode_uint32(datalen,buf); + buf+=4; + DVector<uint8_t>::Read r = data.read(); + copymem(buf,&r[0],datalen*datasize); + + } + + r_len+=4+datalen*datasize; + while(r_len%4) + r_len++; + + } break; + case Variant::INT_ARRAY: { + + DVector<int> data = p_variant; + int datalen=data.size(); + int datasize=sizeof(int32_t); + + if (buf) { + encode_uint32(datalen,buf); + buf+=4; + DVector<int>::Read r = data.read(); + for(int i=0;i<datalen;i++) + encode_uint32(r[i],&buf[i*datasize]); + + } + + r_len+=4+datalen*datasize; + + } break; + case Variant::REAL_ARRAY: { + + DVector<real_t> data = p_variant; + int datalen=data.size(); + int datasize=sizeof(real_t); + + if (buf) { + encode_uint32(datalen,buf); + buf+=4; + DVector<real_t>::Read r = data.read(); + for(int i=0;i<datalen;i++) + encode_float(r[i],&buf[i*datasize]); + + } + + r_len+=4+datalen*datasize; + + } break; + case Variant::STRING_ARRAY: { + + + DVector<String> data = p_variant; + int len=data.size(); + + if (buf) { + encode_uint32(len,buf); + buf+=4; + } + + r_len+=4; + + for(int i=0;i<len;i++) { + + + CharString utf8 = data.get(i).utf8(); + + if (buf) { + encode_uint32(utf8.length()+1,buf); + buf+=4; + copymem(buf,utf8.get_data(),utf8.length()+1); + buf+=utf8.length()+1; + } + + r_len+=4+utf8.length()+1; + while (r_len%4) { + r_len++; //pad + if (buf) + buf++; + } + } + + } break; + case Variant::VECTOR3_ARRAY: { + + DVector<Vector3> data = p_variant; + int len=data.size(); + + if (buf) { + encode_uint32(len,buf); + buf+=4; + } + + r_len+=4; + + if (buf) { + + for(int i=0;i<len;i++) { + + Vector3 v = data.get(i); + + encode_float(v.x,&buf[0]); + encode_float(v.y,&buf[4]); + encode_float(v.z,&buf[8]); + buf+=4*3; + + } + } + + r_len+=4*3*len; + + } break; + case Variant::COLOR_ARRAY: { + + DVector<Color> data = p_variant; + int len=data.size(); + + if (buf) { + encode_uint32(len,buf); + buf+=4; + } + + r_len+=4; + + if (buf) { + + for(int i=0;i<len;i++) { + + Color c = data.get(i); + + + encode_float(c.r,&buf[0]); + encode_float(c.g,&buf[4]); + encode_float(c.b,&buf[8]); + encode_float(c.a,&buf[12]); + buf+=4*4; + } + } + + r_len+=4*4*len; + + } break; + default: { ERR_FAIL_V(ERR_BUG); } + } + + return OK; + +} + + |