-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjson-circular.js
78 lines (73 loc) · 1.85 KB
/
json-circular.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
var self;
module.exports = exports = self = {};
self.magicMarkerName = "@internal-ref";
self.deserializationError = {"@internal-error": "Invalid Deserialization Reference"};
self.stringify = function(obj, replacer){
var returnStr = JSON.stringify(self.preprocess(obj), replacer);
self.postprocess(obj);
return returnStr;
};
self.parse = function(str, reviver){
return self.postprocess(JSON.parse(str, reviver));
};
self.preprocess = function(obj){
var visited = [obj];
var paths = [""];
var path = "";
var process = function(lobj, lpath){
for(var k in lobj){
var localpath = lpath;
if(localpath != "")
localpath += ".";
localpath += k;
if(typeof(lobj[k]) == "object"){
if(visited.indexOf(lobj[k]) >= 0){
var targetPath = paths[visited.indexOf(lobj[k])];
lobj[k] = {};
lobj[k][self.magicMarkerName] = targetPath;
}else{
visited.push(lobj[k]);
paths.push(localpath);
process(lobj[k], localpath);
}
}
}
};
process(obj, path);
return obj;
};
self.postprocess = function(obj){
var fetchTargetRef = function(lobj, targetPath){
if(targetPath.indexOf('.') >= 0){
var pathFragment = targetPath.substr(0, targetPath.indexOf('.'));
if(pathFragment in lobj){
var newPath = targetPath.substr(targetPath.indexOf('.')+1);
return fetchTargetRef(lobj[pathFragment], newPath);
}else{
return self.deserializationError;
}
}else{
if(targetPath == ""){
return lobj;
}else if(targetPath in lobj){
return lobj[targetPath];
}else{
return self.deserializationError;
}
}
};
var process = function(lobj){
for(var k in lobj){
if(typeof(lobj[k]) == "object"){
if(self.magicMarkerName in lobj[k]){
var targetPath = lobj[k][self.magicMarkerName];
lobj[k] = fetchTargetRef(obj, targetPath);
}else{
process(lobj[k]);
}
}
}
};
process(obj);
return obj;
};