ox 1.5.4 → 1.5.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ox might be problematic. Click here for more details.
- data/README.md +21 -3
- data/ext/ox/dump.c +64 -42
- data/ext/ox/extconf.rb +34 -2
- data/ext/ox/gen_load.c +13 -13
- data/ext/ox/obj_load.c +31 -28
- data/ext/ox/ox.c +41 -31
- data/ext/ox/ox.h +20 -13
- data/ext/ox/parse.c +1 -0
- data/ext/ox/sax.c +323 -26
- data/lib/ox.rb +1 -2
- data/lib/ox/element.rb +1 -1
- data/lib/ox/sax.rb +24 -11
- data/lib/ox/version.rb +1 -1
- metadata +4 -50
- data/test/Sample.graffle +0 -2318
- data/test/bench.rb +0 -53
- data/test/bug1.rb +0 -24
- data/test/bug2.rb +0 -38
- data/test/bug3.rb +0 -21
- data/test/cache16_test.rb +0 -17
- data/test/cache8_test.rb +0 -17
- data/test/cache_test.rb +0 -17
- data/test/files.rb +0 -29
- data/test/func.rb +0 -652
- data/test/gen_sample.rb +0 -22
- data/test/obj_sample.rb +0 -19
- data/test/ox/change.rb +0 -16
- data/test/ox/dir.rb +0 -21
- data/test/ox/doc.rb +0 -39
- data/test/ox/file.rb +0 -33
- data/test/ox/group.rb +0 -18
- data/test/ox/hasprops.rb +0 -18
- data/test/ox/layer.rb +0 -14
- data/test/ox/line.rb +0 -22
- data/test/ox/oval.rb +0 -12
- data/test/ox/rect.rb +0 -12
- data/test/ox/shape.rb +0 -37
- data/test/ox/text.rb +0 -23
- data/test/parse_cmp.rb +0 -261
- data/test/perf.rb +0 -91
- data/test/perf_gen.rb +0 -237
- data/test/perf_mars.rb +0 -114
- data/test/perf_obj.rb +0 -124
- data/test/perf_pod.rb +0 -88
- data/test/perf_sax.rb +0 -233
- data/test/perf_write.rb +0 -80
- data/test/sample.rb +0 -55
- data/test/sample/change.rb +0 -14
- data/test/sample/dir.rb +0 -19
- data/test/sample/doc.rb +0 -36
- data/test/sample/file.rb +0 -48
- data/test/sample/group.rb +0 -16
- data/test/sample/hasprops.rb +0 -16
- data/test/sample/layer.rb +0 -12
- data/test/sample/line.rb +0 -20
- data/test/sample/oval.rb +0 -10
- data/test/sample/rect.rb +0 -10
- data/test/sample/shape.rb +0 -35
- data/test/sample/text.rb +0 -20
- data/test/sax_test.rb +0 -468
- data/test/test.rb +0 -70
data/test/gen_sample.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'ox'
|
3
|
-
|
4
|
-
doc = Ox::Document.new(:version => '1.0')
|
5
|
-
|
6
|
-
top = Ox::Element.new('top')
|
7
|
-
top[:name] = 'sample'
|
8
|
-
doc << top
|
9
|
-
|
10
|
-
mid = Ox::Element.new('middle')
|
11
|
-
mid[:name] = 'second'
|
12
|
-
top << mid
|
13
|
-
|
14
|
-
bot = Ox::Element.new('bottom')
|
15
|
-
bot[:name] = 'third'
|
16
|
-
mid << bot
|
17
|
-
|
18
|
-
xml = Ox.dump(doc)
|
19
|
-
puts xml
|
20
|
-
|
21
|
-
doc2 = Ox.parse(xml)
|
22
|
-
puts "Same? #{doc == doc2}"
|
data/test/obj_sample.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'ox'
|
3
|
-
|
4
|
-
class Sample
|
5
|
-
attr_accessor :a, :b, :c
|
6
|
-
|
7
|
-
def initialize(a, b, c)
|
8
|
-
@a = a
|
9
|
-
@b = b
|
10
|
-
@c = c
|
11
|
-
end
|
12
|
-
end # File
|
13
|
-
|
14
|
-
# Create Object
|
15
|
-
obj = Sample.new(1, "bee", ['x', :y, 7.0])
|
16
|
-
# Now dump the Object to an XML String.
|
17
|
-
xml = Ox.dump(obj)
|
18
|
-
# Convert the object back into a Sample Object.
|
19
|
-
obj2 = Ox.parse_obj(xml)
|
data/test/ox/change.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
|
2
|
-
module Test
|
3
|
-
module Ox
|
4
|
-
class Change
|
5
|
-
attr_accessor :time
|
6
|
-
attr_accessor :user
|
7
|
-
attr_accessor :comment
|
8
|
-
|
9
|
-
def initialize(comment=nil, time=nil, user=nil)
|
10
|
-
@user = user || ENV['USER']
|
11
|
-
@time = time || Time.now
|
12
|
-
@comment = comment
|
13
|
-
end
|
14
|
-
end # Change
|
15
|
-
end # Ox
|
16
|
-
end # Test
|
data/test/ox/dir.rb
DELETED
data/test/ox/doc.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'test/ox/hasprops'
|
3
|
-
require 'test/ox/group'
|
4
|
-
require 'test/ox/layer'
|
5
|
-
require 'test/ox/line'
|
6
|
-
require 'test/ox/shape'
|
7
|
-
require 'test/ox/oval'
|
8
|
-
require 'test/ox/rect'
|
9
|
-
require 'test/ox/text'
|
10
|
-
require 'test/ox/change'
|
11
|
-
|
12
|
-
module Test
|
13
|
-
module Ox
|
14
|
-
class Doc
|
15
|
-
include HasProps
|
16
|
-
|
17
|
-
attr_accessor :title
|
18
|
-
attr_accessor :create_time
|
19
|
-
attr_accessor :user
|
20
|
-
# Hash of layers in the document indexed by layer name.
|
21
|
-
attr_reader :layers
|
22
|
-
attr_reader :change_history
|
23
|
-
|
24
|
-
def initialize(title)
|
25
|
-
@title = title
|
26
|
-
@user = ENV['USER']
|
27
|
-
@create_time = Time.now
|
28
|
-
@layers = { }
|
29
|
-
@change_history = []
|
30
|
-
end
|
31
|
-
|
32
|
-
def add_change(comment, time=nil, user=nil)
|
33
|
-
@change_history << Change.new(comment, time, user)
|
34
|
-
end
|
35
|
-
|
36
|
-
end # Doc
|
37
|
-
end # Ox
|
38
|
-
end # Test
|
39
|
-
|
data/test/ox/file.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'etc'
|
3
|
-
|
4
|
-
module Test
|
5
|
-
module Ox
|
6
|
-
|
7
|
-
class File
|
8
|
-
attr_accessor :name, :ctime, :mtime, :size, :owner, :group, :permissions
|
9
|
-
|
10
|
-
def initialize(filename)
|
11
|
-
@name = ::File.basename(filename)
|
12
|
-
stat = ::File.stat(filename)
|
13
|
-
@ctime = stat.ctime
|
14
|
-
@mtime = stat.mtime
|
15
|
-
@size = stat.size
|
16
|
-
@owner = Etc.getpwuid(stat.uid).name
|
17
|
-
@group = Etc.getgrgid(stat.gid).name
|
18
|
-
@permissions = {
|
19
|
-
:user => [(0 != (stat.mode & 0x0100)) ? 'r' : '-',
|
20
|
-
(0 != (stat.mode & 0x0080)) ? 'w' : '-',
|
21
|
-
(0 != (stat.mode & 0x0040)) ? 'x' : '-'].join(''),
|
22
|
-
:group => [(0 != (stat.mode & 0x0020)) ? 'r' : '-',
|
23
|
-
(0 != (stat.mode & 0x0010)) ? 'w' : '-',
|
24
|
-
(0 != (stat.mode & 0x0008)) ? 'x' : '-'].join(''),
|
25
|
-
:other => [(0 != (stat.mode & 0x0004)) ? 'r' : '-',
|
26
|
-
(0 != (stat.mode & 0x0002)) ? 'w' : '-',
|
27
|
-
(0 != (stat.mode & 0x0001)) ? 'x' : '-'].join('')
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
end # File
|
32
|
-
end # Ox
|
33
|
-
end # Test
|
data/test/ox/group.rb
DELETED
data/test/ox/hasprops.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
|
2
|
-
module Test
|
3
|
-
module Ox
|
4
|
-
module HasProps
|
5
|
-
|
6
|
-
def add_prop(key, value)
|
7
|
-
@props = { } unless self.instance_variable_defined?(:@props)
|
8
|
-
@props[key] = value
|
9
|
-
end
|
10
|
-
|
11
|
-
def props
|
12
|
-
@props = { } unless self.instance_variable_defined?(:@props)
|
13
|
-
@props
|
14
|
-
end
|
15
|
-
|
16
|
-
end # HashProps
|
17
|
-
end # Ox
|
18
|
-
end # Test
|
data/test/ox/layer.rb
DELETED
data/test/ox/line.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Test
|
2
|
-
module Ox
|
3
|
-
|
4
|
-
class Line
|
5
|
-
include HasProps
|
6
|
-
|
7
|
-
attr_accessor :x, :y, :dx, :dy
|
8
|
-
attr_accessor :color
|
9
|
-
attr_accessor :thick
|
10
|
-
|
11
|
-
def initialize(x, y, dx, dy, thick, color)
|
12
|
-
@x = x
|
13
|
-
@y = y
|
14
|
-
@dx = dx
|
15
|
-
@dy = dy
|
16
|
-
@thick = thick
|
17
|
-
@color = color
|
18
|
-
end
|
19
|
-
|
20
|
-
end # Line
|
21
|
-
end # Ox
|
22
|
-
end # Test
|
data/test/ox/oval.rb
DELETED
data/test/ox/rect.rb
DELETED
data/test/ox/shape.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
|
2
|
-
module Test
|
3
|
-
module Ox
|
4
|
-
class Shape
|
5
|
-
include HasProps
|
6
|
-
|
7
|
-
attr_accessor :bounds
|
8
|
-
attr_accessor :color
|
9
|
-
attr_accessor :border, :border_color
|
10
|
-
|
11
|
-
def initialize(left, top, wide, high, color=nil)
|
12
|
-
@bounds = [[left, top], [left + wide, top + high]]
|
13
|
-
@color = color
|
14
|
-
@border = 1
|
15
|
-
@border_color = :black
|
16
|
-
end
|
17
|
-
|
18
|
-
def left
|
19
|
-
@bounds[0][0]
|
20
|
-
end
|
21
|
-
|
22
|
-
def top
|
23
|
-
@bounds[0][1]
|
24
|
-
end
|
25
|
-
|
26
|
-
def width
|
27
|
-
@bounds[1][0] - @bounds[0][0]
|
28
|
-
end
|
29
|
-
|
30
|
-
def height
|
31
|
-
@bounds[1][1] - @bounds[0][1]
|
32
|
-
end
|
33
|
-
|
34
|
-
end # Shape
|
35
|
-
end # Ox
|
36
|
-
end # Test
|
37
|
-
|
data/test/ox/text.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
|
2
|
-
module Test
|
3
|
-
module Ox
|
4
|
-
|
5
|
-
class Text < Shape
|
6
|
-
attr_accessor :text
|
7
|
-
attr_accessor :font
|
8
|
-
attr_accessor :font_size
|
9
|
-
attr_accessor :just
|
10
|
-
attr_accessor :text_color
|
11
|
-
|
12
|
-
def initialize(text, left, top, wide, high, color=nil)
|
13
|
-
super(left, top, wide, high, color)
|
14
|
-
@text = text
|
15
|
-
@font = 'helvetica'
|
16
|
-
@font_size = 14
|
17
|
-
@just = 'left'
|
18
|
-
@text_color = 'black'
|
19
|
-
end
|
20
|
-
|
21
|
-
end # Text
|
22
|
-
end # Ox
|
23
|
-
end # Test
|
data/test/parse_cmp.rb
DELETED
@@ -1,261 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby -wW1
|
2
|
-
|
3
|
-
$: << '../lib'
|
4
|
-
$: << '../ext'
|
5
|
-
|
6
|
-
require 'optparse'
|
7
|
-
require 'stringio'
|
8
|
-
require 'ox'
|
9
|
-
|
10
|
-
$verbose = 0
|
11
|
-
$iter = 100
|
12
|
-
|
13
|
-
opts = OptionParser.new
|
14
|
-
opts.on("-v", "increase verbosity") { $verbose += 1 }
|
15
|
-
opts.on("-i", "--iterations [Int]", Integer, "iterations") { |i| $iter = i }
|
16
|
-
opts.on("-h", "--help", "Show this display") { puts opts; Process.exit!(0) }
|
17
|
-
files = opts.parse(ARGV)
|
18
|
-
|
19
|
-
### XML conversion to Hash using in memory Ox parsing ###
|
20
|
-
|
21
|
-
def node_to_dict(element)
|
22
|
-
dict = Hash.new
|
23
|
-
key = nil
|
24
|
-
element.nodes.each do |n|
|
25
|
-
raise "A dict can only contain elements." unless n.is_a?(::Ox::Element)
|
26
|
-
if key.nil?
|
27
|
-
raise "Expected a key, not a #{n.name}." unless 'key' == n.name
|
28
|
-
key = first_text(n)
|
29
|
-
else
|
30
|
-
dict[key] = node_to_value(n)
|
31
|
-
key = nil
|
32
|
-
end
|
33
|
-
end
|
34
|
-
dict
|
35
|
-
end
|
36
|
-
|
37
|
-
def node_to_array(element)
|
38
|
-
a = Array.new
|
39
|
-
element.nodes.each do |n|
|
40
|
-
a.push(node_to_value(n))
|
41
|
-
end
|
42
|
-
a
|
43
|
-
end
|
44
|
-
|
45
|
-
def node_to_value(node)
|
46
|
-
raise "A dict can only contain elements." unless node.is_a?(::Ox::Element)
|
47
|
-
case node.name
|
48
|
-
when 'key'
|
49
|
-
raise "Expected a value, not a key."
|
50
|
-
when 'string'
|
51
|
-
value = first_text(node)
|
52
|
-
when 'dict'
|
53
|
-
value = node_to_dict(node)
|
54
|
-
when 'array'
|
55
|
-
value = node_to_array(node)
|
56
|
-
when 'integer'
|
57
|
-
value = first_text(node).to_i
|
58
|
-
when 'real'
|
59
|
-
value = first_text(node).to_f
|
60
|
-
when 'true'
|
61
|
-
value = true
|
62
|
-
when 'false'
|
63
|
-
value = false
|
64
|
-
else
|
65
|
-
raise "#{node.name} is not a know element type."
|
66
|
-
end
|
67
|
-
value
|
68
|
-
end
|
69
|
-
|
70
|
-
def first_text(node)
|
71
|
-
node.nodes.each do |n|
|
72
|
-
return n if n.is_a?(String)
|
73
|
-
end
|
74
|
-
nil
|
75
|
-
end
|
76
|
-
|
77
|
-
def parse_gen(xml)
|
78
|
-
doc = Ox.parse(xml)
|
79
|
-
plist = doc.root
|
80
|
-
dict = nil
|
81
|
-
plist.nodes.each do |n|
|
82
|
-
if n.is_a?(::Ox::Element)
|
83
|
-
dict = node_to_dict(n)
|
84
|
-
break
|
85
|
-
end
|
86
|
-
end
|
87
|
-
dict
|
88
|
-
end
|
89
|
-
|
90
|
-
### XML conversion to Hash using Ox SAX parser ###
|
91
|
-
|
92
|
-
class Handler
|
93
|
-
def initialize()
|
94
|
-
@key = nil
|
95
|
-
@type = nil
|
96
|
-
@plist = nil
|
97
|
-
@stack = []
|
98
|
-
end
|
99
|
-
|
100
|
-
def text(value)
|
101
|
-
last = @stack.last
|
102
|
-
if last.is_a?(Hash) and @key.nil?
|
103
|
-
raise "Expected a key, not #{@type} with a value of #{value}." unless :key == @type
|
104
|
-
@key = value
|
105
|
-
else
|
106
|
-
append(value)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def start_element(name)
|
111
|
-
if :dict == name
|
112
|
-
dict = Hash.new
|
113
|
-
append(dict)
|
114
|
-
@stack.push(dict)
|
115
|
-
elsif :array == name
|
116
|
-
a = Array.new
|
117
|
-
append(a)
|
118
|
-
@stack.push(a)
|
119
|
-
elsif :true == name
|
120
|
-
append(true)
|
121
|
-
elsif :false == name
|
122
|
-
append(false)
|
123
|
-
else
|
124
|
-
@type = name
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def end_element(name)
|
129
|
-
@stack.pop if :dict == name or :array == name
|
130
|
-
end
|
131
|
-
|
132
|
-
def plist
|
133
|
-
@plist
|
134
|
-
end
|
135
|
-
|
136
|
-
def append(value)
|
137
|
-
unless value.is_a?(Array) or value.is_a?(Hash)
|
138
|
-
case @type
|
139
|
-
when :string
|
140
|
-
# ignore
|
141
|
-
when :key
|
142
|
-
# ignore
|
143
|
-
when :integer
|
144
|
-
value = value.to_i
|
145
|
-
when :real
|
146
|
-
value = value.to_f
|
147
|
-
end
|
148
|
-
end
|
149
|
-
last = @stack.last
|
150
|
-
if last.is_a?(Hash)
|
151
|
-
raise "Expected a key, not with a value of #{value}." if @key.nil?
|
152
|
-
last[@key] = value
|
153
|
-
@key = nil
|
154
|
-
elsif last.is_a?(Array)
|
155
|
-
last.push(value)
|
156
|
-
elsif last.nil?
|
157
|
-
@plist = value
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
def parse_sax(xml)
|
164
|
-
io = StringIO.new(xml)
|
165
|
-
start = Time.now
|
166
|
-
handler = Handler.new()
|
167
|
-
Ox.sax_parse(handler, io)
|
168
|
-
handler.plist
|
169
|
-
end
|
170
|
-
|
171
|
-
### XML conversion to Hash using Ox Object parsing with gsub! replacements ###
|
172
|
-
|
173
|
-
def convert_parse_obj(xml)
|
174
|
-
xml = plist_to_obj_xml(xml)
|
175
|
-
::Ox.load(xml, :mode => :object)
|
176
|
-
end
|
177
|
-
|
178
|
-
### XML conversion to Hash using Ox Object parsing after gsub! replacements ###
|
179
|
-
|
180
|
-
def parse_obj(xml)
|
181
|
-
::Ox.load(xml, :mode => :object)
|
182
|
-
end
|
183
|
-
|
184
|
-
def plist_to_obj_xml(xml)
|
185
|
-
xml = xml.gsub(%{<plist version="1.0">
|
186
|
-
}, '')
|
187
|
-
xml.gsub!(%{
|
188
|
-
</plist>}, '')
|
189
|
-
{ '<dict>' => '<h>',
|
190
|
-
'</dict>' => '</h>',
|
191
|
-
'<dict/>' => '<h/>',
|
192
|
-
'<array>' => '<a>',
|
193
|
-
'</array>' => '</a>',
|
194
|
-
'<array/>' => '<a/>',
|
195
|
-
'<string>' => '<s>',
|
196
|
-
'</string>' => '</s>',
|
197
|
-
'<string/>' => '<s/>',
|
198
|
-
'<key>' => '<s>',
|
199
|
-
'</key>' => '</s>',
|
200
|
-
'<integer>' => '<i>',
|
201
|
-
'</integer>' => '</i>',
|
202
|
-
'<integer/>' => '<i/>',
|
203
|
-
'<real>' => '<f>',
|
204
|
-
'</real>' => '</f>',
|
205
|
-
'<real/>' => '<f/>',
|
206
|
-
'<true/>' => '<y/>',
|
207
|
-
'<false/>' => '<n/>',
|
208
|
-
}.each do |pat,rep|
|
209
|
-
xml.gsub!(pat, rep)
|
210
|
-
end
|
211
|
-
xml
|
212
|
-
end
|
213
|
-
|
214
|
-
files.each do |filename|
|
215
|
-
xml = File.read(filename)
|
216
|
-
|
217
|
-
if 0 < $verbose
|
218
|
-
d1 = parse_gen(xml)
|
219
|
-
d2 = parse_sax(xml)
|
220
|
-
d3 = convert_parse_obj(xml)
|
221
|
-
puts "--- It is #{d1 == d2 and d2 == d3} that all parsers yield the same Hash. ---"
|
222
|
-
end
|
223
|
-
|
224
|
-
start = Time.now
|
225
|
-
$iter.times do
|
226
|
-
parse_gen(xml)
|
227
|
-
end
|
228
|
-
gen_time = Time.now - start
|
229
|
-
|
230
|
-
start = Time.now
|
231
|
-
$iter.times do
|
232
|
-
parse_sax(xml)
|
233
|
-
end
|
234
|
-
sax_time = Time.now - start
|
235
|
-
|
236
|
-
start = Time.now
|
237
|
-
$iter.times do
|
238
|
-
convert_parse_obj(xml)
|
239
|
-
end
|
240
|
-
conv_obj_time = Time.now - start
|
241
|
-
|
242
|
-
xml = plist_to_obj_xml(xml)
|
243
|
-
start = Time.now
|
244
|
-
$iter.times do
|
245
|
-
parse_obj(xml)
|
246
|
-
end
|
247
|
-
obj_time = Time.now - start
|
248
|
-
|
249
|
-
puts "In memory parsing and conversion took #{gen_time} for #{$iter} iterations."
|
250
|
-
puts "SAX parsing and conversion took #{sax_time} for #{$iter} iterations."
|
251
|
-
puts "XML gsub Object parsing and conversion took #{conv_obj_time} for #{$iter} iterations."
|
252
|
-
puts "Object parsing and conversion took #{obj_time} for #{$iter} iterations."
|
253
|
-
end
|
254
|
-
|
255
|
-
# Results for a run:
|
256
|
-
#
|
257
|
-
# > parse_cmp.rb Sample.graffle -i 1000
|
258
|
-
# In memory parsing and conversion took 4.135701 for 1000 iterations.
|
259
|
-
# SAX parsing and conversion took 3.731695 for 1000 iterations.
|
260
|
-
# XML gsub Object parsing and conversion took 3.292397 for 1000 iterations.
|
261
|
-
# Object parsing and conversion took 0.808877 for 1000 iterations.
|