jsog 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/jsog.rb +101 -0
- metadata +45 -0
data/lib/jsog.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class JSOG
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Convert a (Hash) object graph with potential cyclic references into a simpler structure
|
8
|
+
# which contains @id and @ref references.
|
9
|
+
#
|
10
|
+
# @param obj [Hash] the object graph to convert
|
11
|
+
# @return [Hash] an object graph with @ref instead of duplicate references
|
12
|
+
def encode(obj)
|
13
|
+
return do_encode(obj, {})
|
14
|
+
end
|
15
|
+
|
16
|
+
# Convert a (Hash) object graph that was encoded with encode() back to a normal structure
|
17
|
+
# with cyclic references.
|
18
|
+
#
|
19
|
+
# @param obj [Hash] an object graph that was created with encode()
|
20
|
+
# @return [Hash] an object graph with direct references instead of @ref
|
21
|
+
def decode(obj)
|
22
|
+
return do_decode(obj, {})
|
23
|
+
end
|
24
|
+
|
25
|
+
# Just like JSON.parse(), but reads JSOG. JSON is safe too.
|
26
|
+
def parse(str)
|
27
|
+
return decode(JSON.parse(str))
|
28
|
+
end
|
29
|
+
|
30
|
+
# Just like JSON.dump(), but outputs JSOG.
|
31
|
+
def dump(obj)
|
32
|
+
return JSON.dump(encode(obj))
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def do_encode(original, sofar)
|
39
|
+
if original.is_a?(Array)
|
40
|
+
return encode_array(original, sofar)
|
41
|
+
elsif original.is_a?(Hash)
|
42
|
+
return encode_object(original, sofar)
|
43
|
+
else
|
44
|
+
return original
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def encode_object(original, sofar)
|
49
|
+
original_id = original.object_id.to_s
|
50
|
+
|
51
|
+
if sofar.has_key?(original_id)
|
52
|
+
return { '@ref' => original_id }
|
53
|
+
end
|
54
|
+
|
55
|
+
result = sofar[original_id] = { '@id' => original_id }
|
56
|
+
|
57
|
+
original.each do |key, value|
|
58
|
+
result[key] = do_encode(value, sofar)
|
59
|
+
end
|
60
|
+
|
61
|
+
return result
|
62
|
+
end
|
63
|
+
|
64
|
+
def encode_array(original, sofar)
|
65
|
+
return original.map { |val| encode(val, sofar) }
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
|
70
|
+
def do_decode(encoded, found)
|
71
|
+
if encoded.is_a?(Array)
|
72
|
+
return decode_array(encoded, found)
|
73
|
+
elsif encoded.is_a?(Hash)
|
74
|
+
return decode_object(encoded, found)
|
75
|
+
else
|
76
|
+
return encoded
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def decode_object(encoded, found)
|
81
|
+
ref = encoded['@ref']
|
82
|
+
return found[ref.to_s] if ref # be defensive if someone uses numbers in violation of the spec
|
83
|
+
|
84
|
+
result = {}
|
85
|
+
|
86
|
+
id = encoded['@id']
|
87
|
+
found[id.to_s] = result if id # be defensive if someone uses numbers in violation of the spec
|
88
|
+
|
89
|
+
encoded.each do |key, value|
|
90
|
+
result[key] = do_decode(value, found)
|
91
|
+
end
|
92
|
+
|
93
|
+
return result
|
94
|
+
end
|
95
|
+
|
96
|
+
def decode_array(encoded, found)
|
97
|
+
return encoded.map { |value| decode(value, found) }
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jsog
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeff Schnitzer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Library to serialize and deserialize object graphs in the JSOG format
|
15
|
+
email: jeff@infohazard.org
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/jsog.rb
|
21
|
+
homepage: https://github.com/stickfigure/jsog-ruby
|
22
|
+
licenses: []
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 1.8.24
|
42
|
+
signing_key:
|
43
|
+
specification_version: 3
|
44
|
+
summary: JSOG serializer and deserializer
|
45
|
+
test_files: []
|