| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | const path = require("path"); | 
					
						
							| 
									
										
										
										
											2019-08-09 20:42:59 +08:00
										 |  |  | const fs = require("fs"); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | const BinaryMiddleware = require("../lib/serialization/BinaryMiddleware"); | 
					
						
							|  |  |  | const FileMiddleware = require("../lib/serialization/FileMiddleware"); | 
					
						
							|  |  |  | const Serializer = require("../lib/serialization/Serializer"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const serializer = new Serializer([ | 
					
						
							|  |  |  | 	new BinaryMiddleware(), | 
					
						
							| 
									
										
										
										
											2019-08-09 20:42:59 +08:00
										 |  |  | 	new FileMiddleware(fs) | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | const rawSerializer = new Serializer([new FileMiddleware(fs)]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const lazySizes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const captureSize = async data => { | 
					
						
							|  |  |  | 	let size = 0; | 
					
						
							|  |  |  | 	let lazySize = 0; | 
					
						
							|  |  |  | 	for (const b of data) { | 
					
						
							|  |  |  | 		if (Buffer.isBuffer(b)) { | 
					
						
							|  |  |  | 			size += b.length; | 
					
						
							|  |  |  | 		} else if (typeof b === "function") { | 
					
						
							|  |  |  | 			const i = lazySizes.length; | 
					
						
							|  |  |  | 			lazySizes.push(undefined); | 
					
						
							|  |  |  | 			const r = await captureSize(await b()); | 
					
						
							|  |  |  | 			lazySize += r.size + r.lazySize; | 
					
						
							|  |  |  | 			// eslint-disable-next-line require-atomic-updates
 | 
					
						
							|  |  |  | 			lazySizes[i] = r; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return { size, lazySize }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | const ESCAPE = null; | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | const ESCAPE_ESCAPE_VALUE = null; | 
					
						
							|  |  |  | const ESCAPE_END_OBJECT = true; | 
					
						
							|  |  |  | const ESCAPE_UNDEFINED = false; | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | const printData = async (data, indent) => { | 
					
						
							|  |  |  | 	if (!Array.isArray(data)) throw new Error("Not an array"); | 
					
						
							|  |  |  | 	if (Buffer.isBuffer(data[0])) { | 
					
						
							|  |  |  | 		for (const b of data) { | 
					
						
							|  |  |  | 			if (typeof b === "function") { | 
					
						
							|  |  |  | 				const innerData = await b(); | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 				const info = lazySizes.shift(); | 
					
						
							|  |  |  | 				const sizeInfo = `${(info.size / 1048576).toFixed(2)} MiB + ${( | 
					
						
							|  |  |  | 					info.lazySize / 1048576 | 
					
						
							|  |  |  | 				).toFixed(2)} lazy MiB`;
 | 
					
						
							|  |  |  | 				console.log(`${indent}= lazy ${sizeInfo} {`); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 				await printData(innerData, indent + "  "); | 
					
						
							|  |  |  | 				console.log(`${indent}}`); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				console.log(`${indent}= ${b.toString("hex")}`); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 	const referencedValues = new Map(); | 
					
						
							|  |  |  | 	const referencedTypes = new Map(); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:54:13 +08:00
										 |  |  | 	let currentReference = 0; | 
					
						
							|  |  |  | 	let currentTypeReference = 0; | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 	let i = 0; | 
					
						
							|  |  |  | 	const read = () => { | 
					
						
							|  |  |  | 		return data[i++]; | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 	const printLine = content => { | 
					
						
							|  |  |  | 		console.log(`${indent}${content}`); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	printLine(`Version: ${read()}`); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 	while (i < data.length) { | 
					
						
							|  |  |  | 		const item = read(); | 
					
						
							|  |  |  | 		if (item === ESCAPE) { | 
					
						
							|  |  |  | 			const nextItem = read(); | 
					
						
							|  |  |  | 			if (nextItem === ESCAPE_ESCAPE_VALUE) { | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 				printLine("null"); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 			} else if (nextItem === ESCAPE_UNDEFINED) { | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 				printLine("undefined"); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 			} else if (nextItem === ESCAPE_END_OBJECT) { | 
					
						
							|  |  |  | 				indent = indent.slice(0, indent.length - 2); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 				printLine(`} = #${currentReference++}`); | 
					
						
							|  |  |  | 			} else if (typeof nextItem === "number" && nextItem < 0) { | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 				const ref = currentReference + nextItem; | 
					
						
							|  |  |  | 				const value = referencedValues.get(ref); | 
					
						
							|  |  |  | 				if (value) { | 
					
						
							|  |  |  | 					printLine( | 
					
						
							|  |  |  | 						`Reference ${nextItem} => ${JSON.stringify(value)} #${ref}` | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					printLine(`Reference ${nextItem} => #${ref}`); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2018-10-10 15:54:13 +08:00
										 |  |  | 				const request = nextItem; | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 				if (typeof request === "number") { | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 					const ref = currentTypeReference - request; | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 					printLine( | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 						`Object (Reference ${request} => ${referencedTypes.get( | 
					
						
							|  |  |  | 							ref | 
					
						
							|  |  |  | 						)} @${ref}) {`
 | 
					
						
							| 
									
										
										
										
											2018-10-10 15:54:13 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 					const name = read(); | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 					referencedTypes.set(currentTypeReference, `${request} / ${name}`); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 					printLine( | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 						`Object (${request} / ${name} @${currentTypeReference++}) {` | 
					
						
							| 
									
										
										
										
											2018-10-10 15:54:13 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 				indent += "  "; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (typeof item === "string") { | 
					
						
							| 
									
										
										
										
											2018-10-10 16:24:44 +08:00
										 |  |  | 			if (item !== "") { | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 				referencedValues.set(currentReference, item); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 				printLine(`${JSON.stringify(item)} = #${currentReference++}`); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:24:44 +08:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 				printLine('""'); | 
					
						
							| 
									
										
										
										
											2018-10-10 16:24:44 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 		} else if (Buffer.isBuffer(item)) { | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 			printLine(`buffer ${item.toString("hex")} = #${currentReference++}`); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 		} else if (typeof item === "function") { | 
					
						
							|  |  |  | 			const innerData = await item(); | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 			const info = lazySizes.shift(); | 
					
						
							|  |  |  | 			const sizeInfo = `${(info.size / 1048576).toFixed(2)} MiB + ${( | 
					
						
							|  |  |  | 				info.lazySize / 1048576 | 
					
						
							|  |  |  | 			).toFixed(2)} lazy MiB`;
 | 
					
						
							|  |  |  | 			printLine(`lazy ${sizeInfo} {`); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 			await printData(innerData, indent + "  "); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:55:06 +08:00
										 |  |  | 			printLine(`}`); | 
					
						
							| 
									
										
										
										
											2018-10-10 15:54:13 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2018-10-10 16:25:05 +08:00
										 |  |  | 			printLine(`${item}`); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const filename = process.argv[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | (async () => { | 
					
						
							|  |  |  | 	const structure = await rawSerializer.deserialize({ | 
					
						
							|  |  |  | 		filename: path.resolve(filename) | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	const info = await captureSize(structure); | 
					
						
							|  |  |  | 	const sizeInfo = `${(info.size / 1048576).toFixed(2)} MiB + ${( | 
					
						
							|  |  |  | 		info.lazySize / 1048576 | 
					
						
							|  |  |  | 	).toFixed(2)} lazy MiB`;
 | 
					
						
							|  |  |  | 	console.log(`${filename} ${sizeInfo}:`); | 
					
						
							| 
									
										
										
										
											2018-10-09 20:30:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-20 15:06:03 +08:00
										 |  |  | 	const data = await serializer.deserialize({ | 
					
						
							|  |  |  | 		filename: path.resolve(filename) | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	await printData(data, ""); | 
					
						
							|  |  |  | })(); |