Changeset

9567:dbfa286cfa88

util.serialization: Add option for allowing multiple references to the same table (but not cycles)
author Kim Alvefur <zash@zash.se>
date Sat, 27 Oct 2018 12:43:03 +0200
parents 9566:dad29508d0f2
children 9568:69f589c888e7
files spec/util_serialization_spec.lua util/serialization.lua
diffstat 2 files changed, 25 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/spec/util_serialization_spec.lua	Sat Oct 27 12:40:47 2018 +0200
+++ b/spec/util_serialization_spec.lua	Sat Oct 27 12:43:03 2018 +0200
@@ -25,13 +25,27 @@
 				t[t] = { t };
 				serialization.serialize(t)
 			end);
+			-- also with multirefs allowed
+			assert.has_error(function ()
+				local t = {}
+				t[t] = { t };
+				serialization.serialize(t, { multirefs = true })
+			end);
 		end);
 
 		it("rejects multiple references to same table", function ()
 			assert.has_error(function ()
 				local t1 = {};
 				local t2 = { t1, t1 };
-				serialization.serialize(t2);
+				serialization.serialize(t2, { multirefs = false });
+			end);
+		end);
+
+		it("optionally allows multiple references to same table", function ()
+			assert.has_error(function ()
+				local t1 = {};
+				local t2 = { t1, t1 };
+				serialization.serialize(t2, { multirefs = true });
 			end);
 		end);
 
--- a/util/serialization.lua	Sat Oct 27 12:40:47 2018 +0200
+++ b/util/serialization.lua	Sat Oct 27 12:43:03 2018 +0200
@@ -120,6 +120,7 @@
 	local hex = opt.hex;
 	local freeze = opt.freeze;
 	local maxdepth = opt.maxdepth or 127;
+	local multirefs = opt.multiref;
 
 	-- serialize one table, recursively
 	-- t - table being serialized
@@ -136,7 +137,10 @@
 			return l;
 		end
 
+		-- Keep track of table loops
+		local ot = t; -- reference pre-freeze
 		o[t] = true;
+		o[ot] = true;
 
 		if freeze == true then
 			-- opportunity to do pre-serialization
@@ -200,6 +204,12 @@
 			o[l], l = s_rep(indentwith, d-1), l + 1;
 		end
 		o[l], l = tend, l +1;
+
+		if multirefs then
+			o[t] = nil;
+			o[ot] = nil;
+		end
+
 		return l;
 	end