return LATEST_SERIALIZATION_HEADER .. result, count\r
end\r
\r
-\r
---- Loads the schematic in `value` into a node list in the latest format.\r
-- Contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile)\r
-- by ChillCode, available under the MIT license.\r
+local function deserialize_workaround(content)\r
+ local nodes\r
+ if not jit then\r
+ nodes = minetest.deserialize(content)\r
+ else\r
+ -- XXX: This is a filthy hack that works surprisingly well\r
+ -- in LuaJIT, `minetest.deserialize` will fail due to the register limit\r
+ nodes = {}\r
+ content = content:gsub("^%s*return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data\r
+ -- remove string contents strings while preserving their length\r
+ local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)\r
+ local startpos, startpos1 = 1, 1\r
+ local endpos\r
+ while true do -- go through each individual node entry (except the last)\r
+ startpos, endpos = escaped:find("},%s*{", startpos)\r
+ if not startpos then\r
+ break\r
+ end\r
+ local current = content:sub(startpos1, startpos)\r
+ local entry = minetest.deserialize("return " .. current)\r
+ table.insert(nodes, entry)\r
+ startpos, startpos1 = endpos, endpos\r
+ end\r
+ local entry = minetest.deserialize("return " .. content:sub(startpos1)) -- process the last entry\r
+ table.insert(nodes, entry)\r
+ end\r
+ return nodes\r
+end\r
+\r
+--- Loads the schematic in `value` into a node list in the latest format.\r
-- @return A node list in the latest format, or nil on failure.\r
local function load_schematic(value)\r
local version, header, content = worldedit.read_header(value)\r
})\r
end\r
elseif version == 4 or version == 5 then -- Nested table format\r
- if not jit then\r
- -- This is broken for larger tables in the current version of LuaJIT\r
- nodes = minetest.deserialize(content)\r
- else\r
- -- XXX: This is a filthy hack that works surprisingly well - in LuaJIT, `minetest.deserialize` will fail due to the register limit\r
- nodes = {}\r
- content = content:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1) -- remove the starting and ending values to leave only the node data\r
- local escaped = content:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)\r
- local startpos, startpos1, endpos = 1, 1\r
- while true do -- go through each individual node entry (except the last)\r
- startpos, endpos = escaped:find("},%s*{", startpos)\r
- if not startpos then\r
- break\r
- end\r
- local current = content:sub(startpos1, startpos)\r
- local entry = minetest.deserialize("return " .. current)\r
- table.insert(nodes, entry)\r
- startpos, startpos1 = endpos, endpos\r
- end\r
- local entry = minetest.deserialize("return " .. content:sub(startpos1)) -- process the last entry\r
- table.insert(nodes, entry)\r
- end\r
+ nodes = deserialize_workaround(content)\r
else\r
return nil\r
end\r