summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-06-11 10:41:03 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-06-11 10:41:03 -0300
commit9b8696d3dd92e2ed6f310ad0f0bf3c2182c9c6ae (patch)
treeb2ed0515196bb774504b54aab0bf242992ac3d9f /core
parent6f0b4678e26c04abfc88c0226c803e78a108de98 (diff)
Light Baker!
-=-=-=-=-=-= -Support for lightmap baker, have fun figuring out how it works before tutorial is published.
Diffstat (limited to 'core')
-rw-r--r--core/SCsub28
-rw-r--r--core/bind/core_bind.cpp4
-rw-r--r--core/image.cpp9
-rw-r--r--core/image.h6
-rw-r--r--core/io/resource_format_xml.cpp9
-rw-r--r--core/io/resource_format_xml.h2
-rw-r--r--core/math/aabb.cpp9
-rw-r--r--core/math/aabb.h61
-rw-r--r--core/math/face3.cpp2
-rw-r--r--core/math/face3.h169
-rw-r--r--core/packed_data_container.cpp20
-rw-r--r--core/packed_data_container.h2
-rw-r--r--core/script_language.cpp2
-rw-r--r--core/script_language.h1
-rw-r--r--core/ustring.cpp113
-rw-r--r--core/variant_op.cpp2
16 files changed, 398 insertions, 41 deletions
diff --git a/core/SCsub b/core/SCsub
index 9a86c2943d..7eace22b73 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -19,9 +19,37 @@ f = open("global_defaults.cpp","wb")
f.write(gd_cpp)
f.close()
+import os
+txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
+if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
+ e=os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
+ txt = ""
+ ec_valid=True
+ if (len(e)!=64):
+ ec_valid=False
+ else:
+
+ for i in range(len(e)>>1):
+ if (i>0):
+ txt+=","
+ txts="0x"+e[i*2:i*2+2]
+ try:
+ int(txts,16)
+ except:
+ ec_valid=False
+ txt+=txts
+ if (not ec_valid):
+ txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
+ print("Invalid AES256 encryption key, not 64 bits hex: "+e)
+
+f = open("script_encryption_key.cpp", "wb")
+f.write("#include \"globals.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
+f.close()
+
env.add_source_files(env.core_sources,"*.cpp")
+
Export('env')
import make_binders
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 960cdbac20..8d6662157d 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -1418,7 +1418,7 @@ String _Marshalls::variant_to_base64(const Variant& p_var) {
err = encode_variant(p_var,&w[0],len);
ERR_FAIL_COND_V( err != OK, "" );
- int b64len = len / 3 * 4 + 4;
+ int b64len = len / 3 * 4 + 4 + 1;
DVector<uint8_t> b64buff;
b64buff.resize(b64len);
DVector<uint8_t>::Write w64 = b64buff.write();
@@ -1437,7 +1437,7 @@ Variant _Marshalls::base64_to_variant(const String& p_str) {
CharString cstr = p_str.ascii();
DVector<uint8_t> buf;
- buf.resize(strlen / 4 * 3);
+ buf.resize(strlen / 4 * 3 + 1);
DVector<uint8_t>::Write w = buf.write();
int len = base64_decode((char*)(&w[0]), (char*)cstr.get_data(), strlen);
diff --git a/core/image.cpp b/core/image.cpp
index db20862af5..b577117f1e 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1399,14 +1399,17 @@ int Image::get_format_pallete_size(Format p_format) {
}
-void Image::decompress() {
+Error Image::decompress() {
if (format>=FORMAT_BC1 && format<=FORMAT_BC5 && _image_decompress_bc)
_image_decompress_bc(this);
- if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4_ALPHA && _image_decompress_pvrtc)
+ else if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4_ALPHA && _image_decompress_pvrtc)
_image_decompress_pvrtc(this);
- if (format==FORMAT_ETC && _image_decompress_etc)
+ else if (format==FORMAT_ETC && _image_decompress_etc)
_image_decompress_etc(this);
+ else
+ return ERR_UNAVAILABLE;
+ return OK;
}
diff --git a/core/image.h b/core/image.h
index 99300fc3af..87f851959c 100644
--- a/core/image.h
+++ b/core/image.h
@@ -45,8 +45,8 @@
class Image {
enum {
- MAX_WIDTH=4096, // force a limit somehow
- MAX_HEIGHT=4096 // force a limit somehow
+ MAX_WIDTH=16384, // force a limit somehow
+ MAX_HEIGHT=16384// force a limit somehow
};
public:
@@ -317,7 +317,7 @@ public:
Error compress(CompressMode p_mode=COMPRESS_BC);
Image compressed(int p_mode); /* from the Image::CompressMode enum */
- void decompress();
+ Error decompress();
void fix_alpha_edges();
void premultiply_alpha();
diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp
index f3c0f1cb8b..dae95097d3 100644
--- a/core/io/resource_format_xml.cpp
+++ b/core/io/resource_format_xml.cpp
@@ -193,7 +193,9 @@ Error ResourceInteractiveLoaderXML::close_tag(const String& p_name) {
void ResourceInteractiveLoaderXML::unquote(String& p_str) {
- p_str=p_str.strip_edges();
+ p_str=p_str.strip_edges().replace("\"","").xml_unescape();
+
+ /*p_str=p_str.strip_edges();
p_str=p_str.replace("\"","");
p_str=p_str.replace("&gt;","<");
p_str=p_str.replace("&lt;",">");
@@ -205,7 +207,7 @@ void ResourceInteractiveLoaderXML::unquote(String& p_str) {
p_str=p_str.replace("&#"+String::num(i)+";",chr);
}
p_str=p_str.replace("&amp;","&");
-
+*/
//p_str.parse_utf8( p_str.ascii(true).get_data() );
}
@@ -652,11 +654,14 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
while( idx<len*2) {
CharType c=get_char();
+ if (c<=32)
+ continue;
if (idx&1) {
byte|=HEX2CHR(c);
bytesptr[idx>>1]=byte;
+ //printf("%x\n",int(byte));
} else {
byte=HEX2CHR(c)<<4;
diff --git a/core/io/resource_format_xml.h b/core/io/resource_format_xml.h
index 7874431a38..cfa4744915 100644
--- a/core/io/resource_format_xml.h
+++ b/core/io/resource_format_xml.h
@@ -68,7 +68,7 @@ friend class ResourceFormatLoaderXML;
List<RES> resource_cache;
Tag* parse_tag(bool* r_exit=NULL,bool p_printerr=true);
Error close_tag(const String& p_name);
- void unquote(String& p_str);
+ _FORCE_INLINE_ void unquote(String& p_str);
Error goto_end_of_tag();
Error parse_property_data(String &r_data);
Error parse_property(Variant& r_v, String &r_name);
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index 0d454cd07d..576e4fa928 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -335,15 +335,6 @@ AABB AABB::grow(real_t p_by) const {
aabb.grow_by(p_by);
return aabb;
}
-void AABB::grow_by(real_t p_amount) {
-
- pos.x-=p_amount;
- pos.y-=p_amount;
- pos.z-=p_amount;
- size.x+=2.0*p_amount;
- size.y+=2.0*p_amount;
- size.z+=2.0*p_amount;
-}
void AABB::get_edge(int p_edge,Vector3& r_from,Vector3& r_to) const {
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 87be03cf16..089d5d15f7 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -73,6 +73,8 @@ public:
AABB intersection(const AABB& p_aabb) const; ///get box where two intersect, empty if no intersection occurs
bool intersects_segment(const Vector3& p_from, const Vector3& p_to,Vector3* r_clip=NULL,Vector3* r_normal=NULL) const;
bool intersects_ray(const Vector3& p_from, const Vector3& p_dir,Vector3* r_clip=NULL,Vector3* r_normal=NULL) const;
+ _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &from,const Vector3& p_dir, float t0, float t1) const;
+
_FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_plane, int p_plane_count) const;
bool intersects_plane(const Plane &p_plane) const;
@@ -89,7 +91,7 @@ public:
_FORCE_INLINE_ real_t get_shortest_axis_size() const;
AABB grow(real_t p_by) const;
- void grow_by(real_t p_amount);
+ _FORCE_INLINE_ void grow_by(real_t p_amount);
void get_edge(int p_edge,Vector3& r_from,Vector3& r_to) const;
_FORCE_INLINE_ Vector3 get_endpoint(int p_point) const;
@@ -314,6 +316,63 @@ inline real_t AABB::get_shortest_axis_size() const {
return max_size;
}
+bool AABB::smits_intersect_ray(const Vector3 &from,const Vector3& dir, float t0, float t1) const {
+
+ float divx=1.0/dir.x;
+ float divy=1.0/dir.y;
+ float divz=1.0/dir.z;
+
+ Vector3 upbound=pos+size;
+ float tmin, tmax, tymin, tymax, tzmin, tzmax;
+ if (dir.x >= 0) {
+ tmin = (pos.x - from.x) * divx;
+ tmax = (upbound.x - from.x) * divx;
+ }
+ else {
+ tmin = (upbound.x - from.x) * divx;
+ tmax = (pos.x - from.x) * divx;
+ }
+ if (dir.y >= 0) {
+ tymin = (pos.y - from.y) * divy;
+ tymax = (upbound.y - from.y) * divy;
+ }
+ else {
+ tymin = (upbound.y - from.y) * divy;
+ tymax = (pos.y - from.y) * divy;
+ }
+ if ( (tmin > tymax) || (tymin > tmax) )
+ return false;
+ if (tymin > tmin)
+ tmin = tymin;
+ if (tymax < tmax)
+ tmax = tymax;
+ if (dir.z >= 0) {
+ tzmin = (pos.z - from.z) * divz;
+ tzmax = (upbound.z - from.z) * divz;
+ }
+ else {
+ tzmin = (upbound.z - from.z) * divz;
+ tzmax = (pos.z - from.z) * divz;
+ }
+ if ( (tmin > tzmax) || (tzmin > tmax) )
+ return false;
+ if (tzmin > tmin)
+ tmin = tzmin;
+ if (tzmax < tmax)
+ tmax = tzmax;
+ return ( (tmin < t1) && (tmax > t0) );
+}
+
+void AABB::grow_by(real_t p_amount) {
+
+ pos.x-=p_amount;
+ pos.y-=p_amount;
+ pos.z-=p_amount;
+ size.x+=2.0*p_amount;
+ size.y+=2.0*p_amount;
+ size.z+=2.0*p_amount;
+}
+
typedef AABB Rect3;
#endif // AABB_H
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index 9cdf31ed84..814f2d675d 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -247,7 +247,7 @@ bool Face3::intersects_aabb(const AABB& p_aabb) const {
p_aabb.get_edge(i,from,to);
Vector3 e1=from-to;
for (int j=0;j<3;j++) {
- Vector3 e2=edge_norms[i];
+ Vector3 e2=edge_norms[j];
Vector3 axis=vec3_cross( e1, e2 );
diff --git a/core/math/face3.h b/core/math/face3.h
index 3a62f7f812..630c408de3 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -86,6 +86,7 @@ public:
}
bool intersects_aabb(const AABB& p_aabb) const;
+ _FORCE_INLINE_ bool intersects_aabb2(const AABB& p_aabb) const;
operator String() const;
inline Face3() {}
@@ -94,4 +95,172 @@ public:
};
+bool Face3::intersects_aabb2(const AABB& p_aabb) const {
+
+ Vector3 perp = (vertex[0]-vertex[2]).cross(vertex[0]-vertex[1]);
+
+ Vector3 half_extents = p_aabb.size * 0.5;
+ Vector3 ofs = p_aabb.pos + half_extents;
+
+ Vector3 sup =Vector3(
+ (perp.x>0) ? -half_extents.x : half_extents.x,
+ (perp.y>0) ? -half_extents.y : half_extents.y,
+ (perp.z>0) ? -half_extents.z : half_extents.z
+ );
+
+ float d = perp.dot(vertex[0]);
+ float dist_a = perp.dot(ofs+sup)-d;
+ float dist_b = perp.dot(ofs-sup)-d;
+
+ if (dist_a*dist_b > 0)
+ return false; //does not intersect the plane
+
+
+#define TEST_AXIS(m_ax)\
+ {\
+ float aabb_min=p_aabb.pos.m_ax;\
+ float aabb_max=p_aabb.pos.m_ax+p_aabb.size.m_ax;\
+ float tri_min,tri_max;\
+ for (int i=0;i<3;i++) {\
+ if (i==0 || vertex[i].m_ax > tri_max)\
+ tri_max=vertex[i].m_ax;\
+ if (i==0 || vertex[i].m_ax < tri_min)\
+ tri_min=vertex[i].m_ax;\
+ }\
+\
+ if (tri_max<aabb_min || aabb_max<tri_min)\
+ return false;\
+ }
+
+ TEST_AXIS(x);
+ TEST_AXIS(y);
+ TEST_AXIS(z);
+
+#undef TEST_AXIS
+
+
+ Vector3 edge_norms[3]={
+ vertex[0]-vertex[1],
+ vertex[1]-vertex[2],
+ vertex[2]-vertex[0],
+ };
+
+ for (int i=0;i<12;i++) {
+
+ Vector3 from,to;
+ switch(i) {
+
+ case 0:{
+
+ from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z );
+ to=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z );
+ } break;
+ case 1:{
+
+ from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
+ to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z );
+ } break;
+ case 2:{
+ from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
+ to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
+
+ } break;
+ case 3:{
+
+ from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z );
+ to=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
+
+ } break;
+ case 4:{
+
+ from=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
+ to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
+ } break;
+ case 5:{
+
+ from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
+ to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
+ } break;
+ case 6:{
+ from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
+ to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
+
+ } break;
+ case 7:{
+
+ from=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
+ to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
+
+ } break;
+ case 8:{
+
+ from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
+ to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
+
+ } break;
+ case 9:{
+
+ from=Vector3( p_aabb.pos.x , p_aabb.pos.y , p_aabb.pos.z );
+ to=Vector3( p_aabb.pos.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
+
+ } break;
+ case 10:{
+
+ from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z );
+ to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z );
+
+ } break;
+ case 11:{
+
+ from=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y , p_aabb.pos.z+p_aabb.size.z );
+ to=Vector3( p_aabb.pos.x+p_aabb.size.x , p_aabb.pos.y+p_aabb.size.y , p_aabb.pos.z+p_aabb.size.z );
+
+ } break;
+
+ }
+
+ Vector3 e1=from-to;
+ for (int j=0;j<3;j++) {
+ Vector3 e2=edge_norms[j];
+
+ Vector3 axis=vec3_cross( e1, e2 );
+
+ if (axis.length_squared()<0.0001)
+ continue; // coplanar
+ //axis.normalize();
+
+ Vector3 sup2 =Vector3(
+ (axis.x>0) ? -half_extents.x : half_extents.x,
+ (axis.y>0) ? -half_extents.y : half_extents.y,
+ (axis.z>0) ? -half_extents.z : half_extents.z
+ );
+
+ float maxB = axis.dot(ofs+sup2);
+ float minB = axis.dot(ofs-sup2);
+ if (minB>maxB) {
+ SWAP(maxB,minB);
+ }
+
+ float minT=1e20,maxT=-1e20;
+ for (int k=0;k<3;k++) {
+
+ float d=axis.dot(vertex[k]);
+
+ if (d > maxT)
+ maxT=d;
+
+ if (d < minT)
+ minT=d;
+ }
+
+ if (maxB<minT || maxT<minB)
+ return false;
+ }
+ }
+ return true;
+
+
+}
+
+
#endif // FACE3_H
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index 31be886721..65a6433912 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -89,11 +89,13 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant& p_iter,uint32_t p_offs
bool err=false;
if (type==TYPE_ARRAY) {
- return _get_at_ofs(p_offset+8+pos*4,rd.ptr(),err);
+ uint32_t vpos = decode_uint32(rd.ptr() + p_offset+8+pos*4);
+ return _get_at_ofs(vpos,rd.ptr(),err);
} else if (type==TYPE_DICT) {
- return _get_at_ofs(p_offset+8+pos*12+8,rd.ptr(),err);
+ uint32_t vpos = decode_uint32(rd.ptr() + p_offset+8+pos*12+4);
+ return _get_at_ofs(vpos,rd.ptr(),err);
} else {
ERR_FAIL_V(Variant());
}
@@ -127,6 +129,15 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs,const uint8_t *p_buf,boo
}
+uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
+
+ DVector<uint8_t>::Read rd=data.read();
+ const uint8_t *r=&rd[p_ofs];
+ uint32_t type = decode_uint32(r);
+
+ return type;
+};
+
int PackedDataContainer::_size(uint32_t p_ofs) const {
DVector<uint8_t>::Read rd=data.read();
@@ -408,6 +419,10 @@ Variant PackedDataContainerRef::_iter_get(const Variant& p_iter){
return from->_iter_get_ofs(p_iter,offset);
}
+bool PackedDataContainerRef::_is_dictionary() const {
+
+ return from->_type_at_ofs(offset) == PackedDataContainer::TYPE_DICT;
+};
void PackedDataContainerRef::_bind_methods() {
@@ -415,6 +430,7 @@ void PackedDataContainerRef::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_iter_init"),&PackedDataContainerRef::_iter_init);
ObjectTypeDB::bind_method(_MD("_iter_get"),&PackedDataContainerRef::_iter_get);
ObjectTypeDB::bind_method(_MD("_iter_next"),&PackedDataContainerRef::_iter_next);
+ ObjectTypeDB::bind_method(_MD("_is_dictionary"),&PackedDataContainerRef::_is_dictionary);
}
diff --git a/core/packed_data_container.h b/core/packed_data_container.h
index dcbac447ba..b223d3bcfe 100644
--- a/core/packed_data_container.h
+++ b/core/packed_data_container.h
@@ -68,6 +68,7 @@ class PackedDataContainer : public Resource {
friend class PackedDataContainerRef;
Variant _key_at_ofs(uint32_t p_ofs,const Variant& p_key,bool &err) const;
Variant _get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, bool &err) const;
+ uint32_t _type_at_ofs(uint32_t p_ofs) const;
int _size(uint32_t p_ofs) const;
protected:
@@ -100,6 +101,7 @@ public:
Variant _iter_init(const Array& p_iter);
Variant _iter_next(const Array& p_iter);
Variant _iter_get(const Variant& p_iter);
+ bool _is_dictionary() const;
int size() const;
virtual Variant getvar(const Variant& p_key, bool *r_valid=NULL) const;
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 58d8bcf8ee..031fcb0c4c 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -229,8 +229,6 @@ ScriptDebugger::ScriptDebugger() {
}
-
-
bool PlaceHolderScriptInstance::set(const StringName& p_name, const Variant& p_value) {
if (values.has(p_name)) {
diff --git a/core/script_language.h b/core/script_language.h
index 560de520ca..8c59a9e6b8 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -166,6 +166,7 @@ public:
virtual ~ScriptLanguage() {};
};
+extern uint8_t script_encryption_key[32];
class PlaceHolderScriptInstance : public ScriptInstance {
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 188818bc2a..00477e7570 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -1596,6 +1596,7 @@ bool String::is_numeric() const {
};
#define IS_DIGIT(m_d) ( (m_d)>='0' && (m_d)<='9' )
+#define IS_HEX_DIGIT(m_d) ( ( (m_d)>='0' && (m_d)<='9' ) || ( (m_d)>='a' && (m_d)<='f' ) || ( (m_d)>='A' && (m_d)<='F' ) )
template<class C>
static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
@@ -2891,23 +2892,107 @@ String String::xml_escape(bool p_escape_quotes) const {
return str;
}
-String String::xml_unescape() const {
+static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src,int p_src_len,CharType *p_dst) {
- String str=*this;
- str=str.strip_edges();
- //str=str.replace("\"","");
- str=str.replace("&gt;","<");
- str=str.replace("&lt;",">");
- str=str.replace("&apos;","'");
- str=str.replace("&quot;","\"");
- /*
- for (int i=1;i<32;i++) {
+ int len=0;
+ while(p_src_len) {
- char chr[2]={i,0};
- str=str.replace("&#"+String::num(i)+";",chr);
- }*/
- str=str.replace("&amp;","&");
+ if (*p_src=='&') {
+
+ int eat=0;
+
+ if (p_src_len>=4 && p_src[1]=='#') {
+
+ CharType c=0;
+
+ for(int i=2;i<p_src_len;i++) {
+
+ eat=i+1;
+ CharType ct=p_src[i];
+ if (ct==';') {
+ break;
+ } else if (ct>='0' && ct<='9') {
+ ct=ct-'0';
+ } else if (ct>='a' && ct<='f') {
+ ct=(ct-'a')+10;
+ } else if (ct>='A' && ct<='F') {
+ ct=(ct-'A')+10;
+ } else {
+ continue;
+ }
+ c<<=4;
+ c|=ct;
+ }
+
+ if (p_dst)
+ *p_dst=c;
+
+ } else if (p_src_len>=4 && p_src[1]=='g' && p_src[2]=='t' && p_src[3]==';') {
+
+ if (p_dst)
+ *p_dst='<';
+ eat=4;
+ } else if (p_src_len>=4 && p_src[1]=='l' && p_src[2]=='t' && p_src[3]==';') {
+
+ if (p_dst)
+ *p_dst='>';
+ eat=4;
+ } else if (p_src_len>=5 && p_src[1]=='a' && p_src[2]=='m' && p_src[3]=='p' && p_src[4]==';') {
+
+ if (p_dst)
+ *p_dst='&';
+ eat=5;
+ } else if (p_src_len>=6 && p_src[1]=='q' && p_src[2]=='u' && p_src[3]=='o' && p_src[4]=='t' && p_src[5]==';') {
+
+ if (p_dst)
+ *p_dst='"';
+ eat=6;
+ } else if (p_src_len>=6 && p_src[1]=='a' && p_src[2]=='p' && p_src[3]=='o' && p_src[4]=='s' && p_src[5]==';') {
+
+ if (p_dst)
+ *p_dst='\'';
+ eat=6;
+ } else {
+
+ if (p_dst)
+ *p_dst=*p_src;
+ eat=1;
+
+ }
+
+ if (p_dst)
+ p_dst++;
+
+ len++;
+ p_src+=eat;
+ p_src_len-=eat;
+ } else {
+
+ if (p_dst) {
+ *p_dst=*p_src;
+ p_dst++;
+ }
+ len++;
+ p_src++;
+ p_src_len--;
+ }
+ }
+
+ return len;
+
+}
+String String::xml_unescape() const {
+
+
+ String str;
+ int l = length();
+ int len = _xml_unescape(c_str(),l,NULL);
+ if (len==0)
+ return String();
+ str.resize(len+1);
+ _xml_unescape(c_str(),l,&str[0]);
+ str[len]=0;
return str;
}
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 7f46f4c322..1f0f038d77 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -2907,7 +2907,7 @@ bool Variant::iter_init(Variant& r_iter,bool &valid) const {
ref.push_back(r_iter);
Variant vref=ref;
const Variant *refp[]={&vref};
- Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next,refp,1,ce);
+ Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init,refp,1,ce);
if (ref.size()!=1 || ce.error!=Variant::CallError::CALL_OK) {
valid=false;