From d57bb00eced54a74936b253c2db5a712bf6a35cb Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Thu, 27 Oct 2011 20:56:32 +0000 Subject: [PATCH] Fix sparse array serialization This was SVN commit r10442. --- source/simulation2/serialization/BinarySerializer.cpp | 7 +++++++ source/simulation2/serialization/StdDeserializer.cpp | 10 +++++++++- source/simulation2/tests/test_Serializer.h | 9 ++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/source/simulation2/serialization/BinarySerializer.cpp b/source/simulation2/serialization/BinarySerializer.cpp index ca21abb917..82225505d0 100644 --- a/source/simulation2/serialization/BinarySerializer.cpp +++ b/source/simulation2/serialization/BinarySerializer.cpp @@ -72,6 +72,13 @@ void CBinarySerializerScriptImpl::HandleScriptVal(jsval val) { m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_ARRAY); // TODO: probably should have a more efficient storage format + + // Arrays like [1, 2, ] have an 'undefined' at the end which is part of the + // length but seemingly isn't enumerated, so store the length explicitly + jsuint length = 0; + if (!JS_GetArrayLength(cx, obj, &length)) + throw PSERROR_Serialize_ScriptError("JS_GetArrayLength failed"); + m_Serializer.NumberU32_Unbounded("array length", length); } else { diff --git a/source/simulation2/serialization/StdDeserializer.cpp b/source/simulation2/serialization/StdDeserializer.cpp index d67dd18b43..7fe854bb54 100644 --- a/source/simulation2/serialization/StdDeserializer.cpp +++ b/source/simulation2/serialization/StdDeserializer.cpp @@ -113,11 +113,19 @@ jsval CStdDeserializer::ReadScriptVal(const char* UNUSED(name), JSObject* append { JSObject* obj; if (appendParent) + { obj = appendParent; + } else if (type == SCRIPT_TYPE_ARRAY) - obj = JS_NewArrayObject(cx, 0, NULL); + { + u32 length; + NumberU32_Unbounded("array length", length); + obj = JS_NewArrayObject(cx, length, NULL); + } else + { obj = JS_NewObject(cx, NULL, NULL, NULL); + } if (!obj) throw PSERROR_Deserialize_ScriptError(); diff --git a/source/simulation2/tests/test_Serializer.h b/source/simulation2/tests/test_Serializer.h index e8e8cd48a0..8df03fad3e 100644 --- a/source/simulation2/tests/test_Serializer.h +++ b/source/simulation2/tests/test_Serializer.h @@ -295,7 +295,7 @@ public: serialize.ScriptVal("script", obj); - TS_ASSERT_STREAM(stream, 115, + TS_ASSERT_STREAM(stream, 119, "\x03" // SCRIPT_TYPE_OBJECT "\x02\0\0\0" // num props "\x01\0\0\0" "x\0" // "x" @@ -303,6 +303,7 @@ public: "\x7b\0\0\0" // 123 "\x01\0\0\0" "y\0" // "y" "\x02" // SCRIPT_TYPE_ARRAY + "\x08\0\0\0" // array length "\x08\0\0\0" // num props "\x01\0\0\0" "0\0" // "0" "\x05" "\x01\0\0\0" // SCRIPT_TYPE_INT 1 @@ -400,10 +401,16 @@ public: helper_script_roundtrip("prop order 2", "var x={}; x.d=3; x.a=1; x.f=2; x.b=7; x", "({d:3, a:1, f:2, b:7})"); } + void test_script_array_sparse() + { + helper_script_roundtrip("array_sparse", "[,1,2,,4,,]", "[, 1, 2, , 4, ,]"); + } + void test_script_numbers() { const char stream[] = "\x02" // SCRIPT_TYPE_ARRAY "\x04\0\0\0" // num props + "\x04\0\0\0" // array length "\x01\0\0\0" "0\0" // "0" "\x05" "\0\0\0\x80" // SCRIPT_TYPE_INT -2147483648 (JS_INT_MIN) "\x01\0\0\0" "1\0" // "1"