2018-10-09 20:30:59 +08:00
|
|
|
/*
|
|
|
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2019-11-07 23:47:48 +08:00
|
|
|
const writeObject = (obj, write, values) => {
|
|
|
|
const keys = Object.keys(obj);
|
|
|
|
for (const key of keys) {
|
|
|
|
const value = obj[key];
|
|
|
|
if (
|
|
|
|
value !== null &&
|
|
|
|
typeof value === "object" &&
|
|
|
|
value.constructor &&
|
|
|
|
value.constructor === Object
|
|
|
|
) {
|
|
|
|
// nested object
|
|
|
|
write(true);
|
|
|
|
write(key);
|
|
|
|
writeObject(value, write, values);
|
|
|
|
write(false);
|
|
|
|
} else {
|
|
|
|
write(key);
|
|
|
|
values.push(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-09 20:30:59 +08:00
|
|
|
class PlainObjectSerializer {
|
|
|
|
serialize(obj, { write }) {
|
|
|
|
if (Array.isArray(obj)) {
|
|
|
|
write(obj.length);
|
|
|
|
for (const item of obj) {
|
|
|
|
write(item);
|
|
|
|
}
|
|
|
|
} else {
|
2019-11-07 23:47:48 +08:00
|
|
|
const values = [];
|
|
|
|
writeObject(obj, write, values);
|
2018-10-09 20:30:59 +08:00
|
|
|
write(null);
|
2019-11-07 23:47:48 +08:00
|
|
|
for (const value of values) {
|
|
|
|
write(value);
|
2018-10-09 20:30:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
deserialize({ read }) {
|
|
|
|
let key = read();
|
|
|
|
if (typeof key === "number") {
|
|
|
|
const array = [];
|
|
|
|
for (let i = 0; i < key; i++) {
|
|
|
|
array.push(read());
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
} else {
|
|
|
|
const keys = [];
|
2019-11-07 23:47:48 +08:00
|
|
|
let hasNested = key === true;
|
2018-10-09 20:30:59 +08:00
|
|
|
while (key !== null) {
|
|
|
|
keys.push(key);
|
|
|
|
key = read();
|
2019-11-07 23:47:48 +08:00
|
|
|
if (key === true) {
|
|
|
|
hasNested = true;
|
|
|
|
}
|
2018-10-09 20:30:59 +08:00
|
|
|
}
|
2019-11-07 23:47:48 +08:00
|
|
|
let currentObj = {};
|
|
|
|
const stack = hasNested && [];
|
|
|
|
for (let i = 0; i < keys.length; i++) {
|
|
|
|
const key = keys[i];
|
|
|
|
if (key === true) {
|
|
|
|
// enter nested object
|
|
|
|
const objectKey = keys[++i];
|
|
|
|
const newObj = {};
|
|
|
|
currentObj[objectKey] = newObj;
|
|
|
|
stack.push(currentObj);
|
|
|
|
currentObj = newObj;
|
|
|
|
} else if (key === false) {
|
|
|
|
// leave nested object
|
|
|
|
currentObj = stack.pop();
|
|
|
|
} else {
|
|
|
|
currentObj[key] = read();
|
|
|
|
}
|
2018-10-09 20:30:59 +08:00
|
|
|
}
|
2019-11-07 23:47:48 +08:00
|
|
|
return currentObj;
|
2018-10-09 20:30:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = PlainObjectSerializer;
|