<html>
    <head>
        <script src="../../resources/js-test-pre.js"></script>
        <script src="resources/serialized-script-value.js"></script>
    </head>
    <body>
        <script>

const currentVersion = 0x0d;

// Here's a little Q&D helper for future adventurers needing to rebaseline this.

function dec2hex(n) {
    var s = n.toString(16);
    if (s.length < 2)
        return "0x0" + s;
    return "0x" + s;
}

function dumpSerialization(obj)
{
    var serialized = internals.serializeObject(obj);
    var bufferView = new Uint8Array(serialized);

    var numbers = new Array();
    for (var i = 0; i < bufferView.length; ++i) {
        numbers.push(dec2hex(bufferView[i]));
    }
    var str = "";
    for (var i = 0; i < numbers.length; ++i) {
        if (i % 8 == 0)
            str += "\n    ";
        else
            str += " ";
        str += numbers[i];
        if (i != numbers.length - 1)
            str += ",";
    }
    debug(str);
}

function testSerialization(obj, values, oldFormat, serializeExceptionValue) {
    _testSerialization(1, obj, values, oldFormat, serializeExceptionValue);
}

testSerialization({foo: 'zoo', bar: {baz: 'myNewKey'}},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x80, 0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00,
    0x80, 0x7a, 0x6f, 0x6f, 0x03, 0x00, 0x00, 0x80,
    0x62, 0x61, 0x72, 0x02, 0x03, 0x00, 0x00, 0x80,
    0x62, 0x61, 0x7a, 0x10, 0x08, 0x00, 0x00, 0x80,
    0x6d, 0x79, 0x4e, 0x65, 0x77, 0x4b, 0x65, 0x79,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10,
    0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00,
    0x6f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x00,
    0x61, 0x00, 0x72, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x00, 0x62, 0x00, 0x61, 0x00, 0x7a, 0x00, 0x10,
    0x08, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x79, 0x00,
    0x4e, 0x00, 0x65, 0x00, 0x77, 0x00, 0x4b, 0x00,
    0x65, 0x00, 0x79, 0x00, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff
]);

testSerialization({foo: 'zoo', bar: 'myNewKey'},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x80, 0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00,
    0x80, 0x7a, 0x6f, 0x6f, 0x03, 0x00, 0x00, 0x80,
    0x62, 0x61, 0x72, 0x10, 0x08, 0x00, 0x00, 0x80,
    0x6d, 0x79, 0x4e, 0x65, 0x77, 0x4b, 0x65, 0x79,
    0xff, 0xff, 0xff, 0xff
],
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10,
    0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00,
    0x6f, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x00,
    0x61, 0x00, 0x72, 0x00, 0x10, 0x08, 0x00, 0x00,
    0x00, 0x6d, 0x00, 0x79, 0x00, 0x4e, 0x00, 0x65,
    0x00, 0x77, 0x00, 0x4b, 0x00, 0x65, 0x00, 0x79,
    0x00, 0xff, 0xff, 0xff, 0xff
]);

testSerialization([],
[
    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x00, 0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x00, 0xff, 0xff, 0xff, 0xff
]);
testSerialization({foo: "zoo"},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x80, 0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00,
    0x80, 0x7a, 0x6f, 0x6f, 0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x10,
    0x03, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6f, 0x00,
    0x6f, 0x00, 0xff, 0xff, 0xff, 0xff
]);
testSerialization({foo: null},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x80, 0x66, 0x6f, 0x6f, 0x04, 0xff, 0xff, 0xff,
    0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00,
    0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x04,
    0xff, 0xff, 0xff, 0xff
]);

testSerialization({},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff,
    0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0xff,
    0xff
]);

testSerialization(undefined,
[
    currentVersion, 0x00, 0x00, 0x00, 0x03
],
[
    0x03, 0x00, 0x00, 0x00, 0x03
]);
testSerialization(true,
[
    currentVersion, 0x00, 0x00, 0x00, 0x09
],
[
    0x03, 0x00, 0x00, 0x00, 0x09
]);
testSerialization(false,
[
    currentVersion, 0x00, 0x00, 0x00, 0x08
],
[
    0x03, 0x00, 0x00, 0x00, 0x08
]);
testSerialization(new Array(100),
[
    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00,
    0x00, 0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x00,
    0x00, 0xff, 0xff, 0xff, 0xff
]);
testSerialization(10,
[
    currentVersion, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x00, 0x00,
    0x00
],
[
    0x03, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x00, 0x00,
    0x00
]);
testSerialization(-10,
[
    currentVersion, 0x00, 0x00, 0x00, 0x05, 0xf6, 0xff, 0xff,
    0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x05, 0xf6, 0xff, 0xff,
    0xff
]);
testSerialization(Math.pow(2,30),
[
    currentVersion, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x40
],
[
    0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
    0x40
]);
testSerialization(Math.pow(2,55),
[
    currentVersion, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x60, 0x43,
],
[
    0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x60, 0x43,
]);
testSerialization(1.23,
[
    currentVersion, 0x00, 0x00, 0x00, 0x0a, 0xae, 0x47, 0xe1,
    0x7a, 0x14, 0xae, 0xf3, 0x3f
],
[
    0x03, 0x00, 0x00, 0x00, 0x0a, 0xae, 0x47, 0xe1,
    0x7a, 0x14, 0xae, 0xf3, 0x3f
]);
testSerialization("",
[
    currentVersion, 0x00, 0x00, 0x00, 0x11
],
[
    0x03, 0x00, 0x00, 0x00, 0x11
]);
testSerialization("abc",
[
    currentVersion, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00,
    0x80, 0x61, 0x62, 0x63
],
[
    0x03, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00,
    0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00
]);
testSerialization({integer: 123},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00,
    0x80, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72,
    0x05, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
    0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x07, 0x00, 0x00,
    0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65,
    0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x05,
    0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
]);
testSerialization({string: "str"},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00,
    0x80, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x10,
    0x03, 0x00, 0x00, 0x80, 0x73, 0x74, 0x72, 0xff,
    0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00,
    0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69,
    0x00, 0x6e, 0x00, 0x67, 0x00, 0x10, 0x03, 0x00,
    0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00,
    0xff, 0xff, 0xff, 0xff
]);
testSerialization({list: [1,2,3]},
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
    0x80, 0x6c, 0x69, 0x73, 0x74, 0x01, 0x03, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01,
    0x00, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00,
    0x02, 0x00, 0x00, 0x00, 0x05, 0x03, 0x00, 0x00,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00,
    0x00, 0x6c, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74,
    0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x05,
    0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
    0x05, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff
]);
testSerialization(null,
[
    currentVersion, 0x00, 0x00, 0x00, 0x04
],
[
    0x03, 0x00, 0x00, 0x00, 0x04
]);
testSerialization(/abc/,
[
    currentVersion, 0x00, 0x00, 0x00, 0x12, 0x03, 0x00, 0x00,
    0x80, 0x61, 0x62, 0x63, 0x00, 0x00, 0x00, 0x80
],
[
    0x03, 0x00, 0x00, 0x00, 0x12, 0x03, 0x00, 0x00,
    0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x00,
    0x00, 0x00, 0x00
]);

var innerObject = {hello: "there"};
var outerObject = {inner: innerObject};
outerObject['outer'] = innerObject;
testSerialization(outerObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
    0x80, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x02, 0x05,
    0x00, 0x00, 0x80, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
    0x10, 0x05, 0x00, 0x00, 0x80, 0x74, 0x68, 0x65,
    0x72, 0x65, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00,
    0x00, 0x80, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x13,
    0x01, 0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
    0x00, 0x69, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x65,
    0x00, 0x72, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00,
    0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00,
    0x6f, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x74,
    0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65,
    0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0x00,
    0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65,
    0x00, 0x72, 0x00, 0x13, 0x01, 0xff, 0xff, 0xff,
    0xff
]);
testSerialization(innerObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
    0x80, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x10, 0x05,
    0x00, 0x00, 0x80, 0x74, 0x68, 0x65, 0x72, 0x65,
    0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00,
    0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c,
    0x00, 0x6f, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00,
    0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00,
    0x65, 0x00, 0xff, 0xff, 0xff, 0xff
]);

var unicodeObject = {a: 'a', u: String.fromCharCode(0x03B1,0x03B2), d: 42};
testSerialization(unicodeObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
    0x80, 0x61, 0x10, 0xfe, 0xff, 0xff, 0xff, 0x00,
    0x01, 0x00, 0x00, 0x80, 0x75, 0x10, 0x02, 0x00,
    0x00, 0x00, 0xb1, 0x03, 0xb2, 0x03, 0x01, 0x00,
    0x00, 0x80, 0x64, 0x05, 0x2a, 0x00, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
    0x00, 0x61, 0x00, 0x10, 0xfe, 0xff, 0xff, 0xff,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x75, 0x00, 0x10,
    0x02, 0x00, 0x00, 0x00, 0xb1, 0x03, 0xb2, 0x03,
    0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x05, 0x2a,
    0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
]);
unicodeObject.a = 'ab';
testSerialization(unicodeObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
    0x80, 0x61, 0x10, 0x02, 0x00, 0x00, 0x80, 0x61,
    0x62, 0x01, 0x00, 0x00, 0x80, 0x75, 0x10, 0x02,
    0x00, 0x00, 0x00, 0xb1, 0x03, 0xb2, 0x03, 0x01,
    0x00, 0x00, 0x80, 0x64, 0x05, 0x2a, 0x00, 0x00,
    0x00, 0xff, 0xff, 0xff, 0xff
],
[
    0x03, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
    0x00, 0x61, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00,
    0x61, 0x00, 0x62, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x75, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0xb1,
    0x03, 0xb2, 0x03, 0x01, 0x00, 0x00, 0x00, 0x64,
    0x00, 0x05, 0x2a, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff
]);

var arrayObject = [];
arrayObject['a'] = true;
arrayObject['b'] = false;
arrayObject['foo'] = 123;
arrayObject['bar'] = 456;
arrayObject[''] = null;
testSerialization(arrayObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
    0x00, 0xfd, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
    0x80, 0x61, 0x09, 0x01, 0x00, 0x00, 0x80, 0x62,
    0x08, 0x03, 0x00, 0x00, 0x80, 0x66, 0x6f, 0x6f,
    0x05, 0x7b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
    0x80, 0x62, 0x61, 0x72, 0x05, 0xc8, 0x01, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0xff, 0xff,
    0xff, 0xff
]);

arrayObject[0] = 'foo';
arrayObject[1] = 'bar';
testSerialization(arrayObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
    0x00, 0x80, 0x66, 0x6f, 0x6f, 0x01, 0x00, 0x00,
    0x00, 0x10, 0x03, 0x00, 0x00, 0x80, 0x62, 0x61,
    0x72, 0xfd, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00,
    0x80, 0x61, 0x09, 0x01, 0x00, 0x00, 0x80, 0x62,
    0x08, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x05, 0x7b,
    0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x01,
    0x05, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x04, 0xff, 0xff, 0xff, 0xff
]);

var mapObject = new Map;
mapObject.set(1,2)
mapObject.set(1.5, {})
mapObject.set(mapObject, "foo")
mapObject.set("bar", new String("bar"))
mapObject.expando = {};

testSerialization(mapObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x1e, 0x07, 0x05, 0x02,
    0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xf8, 0x3f, 0x02, 0xff, 0xff, 0xff,
    0xff, 0x13, 0x00, 0x10, 0x03, 0x00, 0x00, 0x80,
    0x66, 0x6f, 0x6f, 0x10, 0x03, 0x00, 0x00, 0x80,
    0x62, 0x61, 0x72, 0x1a, 0xfe, 0xff, 0xff, 0xff,
    0x01, 0x1f, 0x07, 0x00, 0x00, 0x80, 0x65, 0x78,
    0x70, 0x61, 0x6e, 0x64, 0x6f, 0x02, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff
]);

var setObject = new Set;
setObject.add(1)
setObject.add(1.5)
setObject.add(setObject)
setObject.add("bar")
setObject.add(new String("bar"))
setObject.expando = {};

testSerialization(setObject,
[
    currentVersion, 0x00, 0x00, 0x00, 0x1d, 0x07, 0x0a, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, 0x13,
    0x00, 0x10, 0x03, 0x00, 0x00, 0x80, 0x62, 0x61,
    0x72, 0x1a, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x20,
    0x07, 0x00, 0x00, 0x80, 0x65, 0x78, 0x70, 0x61,
    0x6e, 0x64, 0x6f, 0x02, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff
]);

testSerialization(function(){}, [], null, DOMException.DATA_CLONE_ERR);

successfullyParsed = true;
        </script>
        <script src="../../resources/js-test-post.js"></script>
    </body>
</html>
