oxmlrpc 0.1
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/oxmlrpc.rb +2 -0
- data/lib/oxmlrpc/parser.rb +64 -0
- data/lib/oxmlrpc/serializer.rb +95 -0
- data/spec/parser_spec.rb +220 -0
- data/spec/serializer_spec.rb +47 -0
- data/spec/spec_helper.rb +6 -0
- metadata +84 -0
data/lib/oxmlrpc.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'ox'
|
2
|
+
|
3
|
+
module OXMLRPC
|
4
|
+
class Parser < ::Ox::Sax
|
5
|
+
|
6
|
+
attr_reader :rpc_method, :params
|
7
|
+
|
8
|
+
def self.parse(xml)
|
9
|
+
parser = self.new
|
10
|
+
Ox.sax_parse(parser, StringIO.new(xml))
|
11
|
+
parser
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@elements = []
|
16
|
+
@rpc_method = nil
|
17
|
+
@params = []
|
18
|
+
@array_mode = false
|
19
|
+
@struct_mode = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def start_element(name)
|
23
|
+
@elements << name
|
24
|
+
|
25
|
+
if :array == name
|
26
|
+
@array_mode = true
|
27
|
+
@params << Array.new
|
28
|
+
end
|
29
|
+
|
30
|
+
if :struct == name
|
31
|
+
@struct_mode = true
|
32
|
+
@params << Hash.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def end_element(name)
|
37
|
+
@array_mode = false if :array == name
|
38
|
+
@struct_mode = false if :struct == name
|
39
|
+
|
40
|
+
raise "Invalid XML" unless @elements.pop == name
|
41
|
+
end
|
42
|
+
|
43
|
+
def text(value)
|
44
|
+
@rpc_method = value if :methodName == @elements.last
|
45
|
+
@params.last[value] = nil if :name == @elements.last && @struct_mode
|
46
|
+
|
47
|
+
add_to_params value == 1 || value == "1" if :boolean == @elements.last
|
48
|
+
add_to_params value if [:value, :string].include?(@elements.last)
|
49
|
+
add_to_params Integer(value) if [:int, :i4].include?(@elements.last)
|
50
|
+
add_to_params Float(value) if :double == @elements.last
|
51
|
+
add_to_params Time.parse(value) if :'dateTime.iso8601' == @elements.last
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_to_params(value)
|
55
|
+
if @array_mode
|
56
|
+
@params.last << value
|
57
|
+
elsif @struct_mode
|
58
|
+
@params.last[@params.last.keys.last] = value
|
59
|
+
else
|
60
|
+
@params << value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'ox'
|
2
|
+
|
3
|
+
module OXMLRPC
|
4
|
+
class Serializer
|
5
|
+
|
6
|
+
def self.serialize(data)
|
7
|
+
self.new(data).to_rpc
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(data = {})
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_rpc
|
15
|
+
doc = Ox::Document.new(:version => '1.0')
|
16
|
+
doc << mr = Ox::Element.new('methodResponse')
|
17
|
+
mr << params = Ox::Element.new('params')
|
18
|
+
params << param = Ox::Element.new('param')
|
19
|
+
param << serialize(@data)
|
20
|
+
Ox.dump(doc, :indent => -1)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def serialize(sth)
|
26
|
+
case sth
|
27
|
+
when String then serialize_string(sth)
|
28
|
+
when Integer then serialize_integer(sth)
|
29
|
+
when Hash then serialize_hash(sth)
|
30
|
+
when Array then serialize_array(sth)
|
31
|
+
when Float then serialize_double(sth)
|
32
|
+
when TrueClass then serialize_boolean(true)
|
33
|
+
when FalseClass then serialize_boolean(false)
|
34
|
+
when Time then serialize_time(sth)
|
35
|
+
else
|
36
|
+
raise "Uknkown type"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def serialize_hash(hash)
|
41
|
+
value = Ox::Element.new('value')
|
42
|
+
value << struct = Ox::Element.new('struct')
|
43
|
+
hash.each do |key, value|
|
44
|
+
struct << member = Ox::Element.new('member')
|
45
|
+
member << (Ox::Element.new('name') << key.to_s)
|
46
|
+
member << serialize(value)
|
47
|
+
end
|
48
|
+
value
|
49
|
+
end
|
50
|
+
|
51
|
+
def serialize_array(arr)
|
52
|
+
value = Ox::Element.new('value')
|
53
|
+
value << array = Ox::Element.new('array')
|
54
|
+
array << data = Ox::Element.new('data')
|
55
|
+
arr.each do |element|
|
56
|
+
data << serialize(element)
|
57
|
+
end
|
58
|
+
value
|
59
|
+
end
|
60
|
+
|
61
|
+
def serialize_string(string)
|
62
|
+
value = Ox::Element.new('value')
|
63
|
+
value << string
|
64
|
+
value
|
65
|
+
end
|
66
|
+
|
67
|
+
def serialize_integer(integer)
|
68
|
+
value = Ox::Element.new('value')
|
69
|
+
value << int = Ox::Element.new('int')
|
70
|
+
int << integer.to_s
|
71
|
+
value
|
72
|
+
end
|
73
|
+
|
74
|
+
def serialize_double(float)
|
75
|
+
value = Ox::Element.new('value')
|
76
|
+
value << double = Ox::Element.new('double')
|
77
|
+
double << float.to_s
|
78
|
+
value
|
79
|
+
end
|
80
|
+
|
81
|
+
def serialize_boolean(boolean)
|
82
|
+
value = Ox::Element.new('value')
|
83
|
+
value << bool = Ox::Element.new('boolean')
|
84
|
+
bool << (boolean ? "1" : "0")
|
85
|
+
value
|
86
|
+
end
|
87
|
+
|
88
|
+
def serialize_time(time)
|
89
|
+
value = Ox::Element.new('value')
|
90
|
+
value << td = Ox::Element.new('dateTime.iso8601')
|
91
|
+
td << time.strftime("%Y%m%dT%H:%M:%S")
|
92
|
+
value
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe OXMLRPC::Parser do
|
4
|
+
it 'should parse simple request with <int> value' do
|
5
|
+
xml_request = %{
|
6
|
+
<?xml version="1.0"?>
|
7
|
+
<methodCall>
|
8
|
+
<methodName>examples.getStateName</methodName>
|
9
|
+
<params>
|
10
|
+
<param>
|
11
|
+
<value><int>41</int></value>
|
12
|
+
</param>
|
13
|
+
</params>
|
14
|
+
</methodCall>
|
15
|
+
}
|
16
|
+
|
17
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
18
|
+
|
19
|
+
request.rpc_method.should eq "examples.getStateName"
|
20
|
+
request.params.should eq [41]
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should parse simple request with <i4> value' do
|
24
|
+
xml_request = %{
|
25
|
+
<?xml version="1.0"?>
|
26
|
+
<methodCall>
|
27
|
+
<methodName>examples.getStateName</methodName>
|
28
|
+
<params>
|
29
|
+
<param>
|
30
|
+
<value><i4>41</i4></value>
|
31
|
+
</param>
|
32
|
+
</params>
|
33
|
+
</methodCall>
|
34
|
+
}
|
35
|
+
|
36
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
37
|
+
|
38
|
+
request.rpc_method.should eq "examples.getStateName"
|
39
|
+
request.params.should eq [41]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should parse simple request with <string> value' do
|
43
|
+
xml_request = %{
|
44
|
+
<?xml version="1.0"?>
|
45
|
+
<methodCall>
|
46
|
+
<methodName>examples.getStateName</methodName>
|
47
|
+
<params>
|
48
|
+
<param>
|
49
|
+
<value><string>41</string></value>
|
50
|
+
</param>
|
51
|
+
</params>
|
52
|
+
</methodCall>
|
53
|
+
}
|
54
|
+
|
55
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
56
|
+
|
57
|
+
request.rpc_method.should eq "examples.getStateName"
|
58
|
+
request.params.should eq ["41"]
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should parse simple request with <empty> value' do
|
62
|
+
xml_request = %{
|
63
|
+
<?xml version="1.0"?>
|
64
|
+
<methodCall>
|
65
|
+
<methodName>examples.getStateName</methodName>
|
66
|
+
<params>
|
67
|
+
<param>
|
68
|
+
<value>41</value>
|
69
|
+
</param>
|
70
|
+
</params>
|
71
|
+
</methodCall>
|
72
|
+
}
|
73
|
+
|
74
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
75
|
+
|
76
|
+
request.rpc_method.should eq "examples.getStateName"
|
77
|
+
request.params.should eq ["41"]
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should parse simple request with <int> values' do
|
81
|
+
xml_request = %{
|
82
|
+
<?xml version="1.0"?>
|
83
|
+
<methodCall>
|
84
|
+
<methodName>examples.getStateName</methodName>
|
85
|
+
<params>
|
86
|
+
<param>
|
87
|
+
<value><int>41</int></value>
|
88
|
+
</param>
|
89
|
+
<param>
|
90
|
+
<value><int>99</int></value>
|
91
|
+
</param>
|
92
|
+
</params>
|
93
|
+
</methodCall>
|
94
|
+
}
|
95
|
+
|
96
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
97
|
+
|
98
|
+
request.rpc_method.should eq "examples.getStateName"
|
99
|
+
request.params.should eq [41,99]
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should parse simple request with <bool> values' do
|
103
|
+
xml_request = %{
|
104
|
+
<?xml version="1.0"?>
|
105
|
+
<methodCall>
|
106
|
+
<methodName>examples.getStateName</methodName>
|
107
|
+
<params>
|
108
|
+
<param>
|
109
|
+
<value><boolean>0</boolean></value>
|
110
|
+
</param>
|
111
|
+
<param>
|
112
|
+
<value><boolean>1</boolean></value>
|
113
|
+
</param>
|
114
|
+
</params>
|
115
|
+
</methodCall>
|
116
|
+
}
|
117
|
+
|
118
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
119
|
+
|
120
|
+
request.rpc_method.should eq "examples.getStateName"
|
121
|
+
request.params.should eq [false,true]
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should parse simple request with <double> values' do
|
125
|
+
xml_request = %{
|
126
|
+
<?xml version="1.0"?>
|
127
|
+
<methodCall>
|
128
|
+
<methodName>examples.getStateName</methodName>
|
129
|
+
<params>
|
130
|
+
<param>
|
131
|
+
<value><double>-12.214</double></value>
|
132
|
+
</param>
|
133
|
+
</params>
|
134
|
+
</methodCall>
|
135
|
+
}
|
136
|
+
|
137
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
138
|
+
|
139
|
+
request.rpc_method.should eq "examples.getStateName"
|
140
|
+
request.params.should eq [-12.214]
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should parse simple request with <dateTime> values' do
|
144
|
+
xml_request = %{
|
145
|
+
<?xml version="1.0"?>
|
146
|
+
<methodCall>
|
147
|
+
<methodName>examples.getStateName</methodName>
|
148
|
+
<params>
|
149
|
+
<param>
|
150
|
+
<value><dateTime.iso8601>19980717T14:08:55</dateTime.iso8601></value>
|
151
|
+
</param>
|
152
|
+
</params>
|
153
|
+
</methodCall>
|
154
|
+
}
|
155
|
+
|
156
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
157
|
+
|
158
|
+
request.rpc_method.should eq "examples.getStateName"
|
159
|
+
request.params.should eq [Time.parse("19980717T14:08:55")]
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should parse simple request with <array> values' do
|
163
|
+
xml_request = %{
|
164
|
+
<?xml version="1.0"?>
|
165
|
+
<methodCall>
|
166
|
+
<methodName>examples.getStateName</methodName>
|
167
|
+
<params>
|
168
|
+
<param>
|
169
|
+
<value>
|
170
|
+
<array>
|
171
|
+
<data>
|
172
|
+
<value><int>12</int></value>
|
173
|
+
<value><string>Egypt</string></value>
|
174
|
+
<value><boolean>0</boolean></value>
|
175
|
+
<value><i4>-31</i4></value>
|
176
|
+
</data>
|
177
|
+
</array>
|
178
|
+
</value>
|
179
|
+
</param>
|
180
|
+
</params>
|
181
|
+
</methodCall>
|
182
|
+
}
|
183
|
+
|
184
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
185
|
+
|
186
|
+
request.rpc_method.should eq "examples.getStateName"
|
187
|
+
request.params.should eq [[12,"Egypt", false, -31]]
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should parse simple request with <struct> values' do
|
191
|
+
xml_request = %{
|
192
|
+
<?xml version="1.0"?>
|
193
|
+
<methodCall>
|
194
|
+
<methodName>examples.getStateName</methodName>
|
195
|
+
<params>
|
196
|
+
<param>
|
197
|
+
<value>
|
198
|
+
<struct>
|
199
|
+
<member>
|
200
|
+
<name>lowerBound</name>
|
201
|
+
<value><i4>18</i4></value>
|
202
|
+
</member>
|
203
|
+
<member>
|
204
|
+
<name>upperBound</name>
|
205
|
+
<value><i4>139</i4></value>
|
206
|
+
</member>
|
207
|
+
</struct>
|
208
|
+
</value>
|
209
|
+
</param>
|
210
|
+
</params>
|
211
|
+
</methodCall>
|
212
|
+
}
|
213
|
+
|
214
|
+
request = OXMLRPC::Parser.parse(xml_request)
|
215
|
+
|
216
|
+
request.rpc_method.should eq "examples.getStateName"
|
217
|
+
request.params.should eq [{"lowerBound" => 18, "upperBound" => 139}]
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe OXMLRPC::Serializer do
|
4
|
+
it 'should serialize <int> value' do
|
5
|
+
OXMLRPC::Serializer.serialize(12).chomp
|
6
|
+
.should eq "<methodResponse><params><param><value><int>12</int></value></param></params></methodResponse>"
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should serialize <string> value' do
|
10
|
+
OXMLRPC::Serializer.serialize("hello").chomp
|
11
|
+
.should eq "<methodResponse><params><param><value>hello</value></param></params></methodResponse>"
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should serialize <boolean> value' do
|
15
|
+
OXMLRPC::Serializer.serialize(true).chomp
|
16
|
+
.should eq "<methodResponse><params><param><value><boolean>1</boolean></value></param></params></methodResponse>"
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should serialize <double> value' do
|
20
|
+
OXMLRPC::Serializer.serialize(-12.45).chomp
|
21
|
+
.should eq "<methodResponse><params><param><value><double>-12.45</double></value></param></params></methodResponse>"
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should serialize <dateTime.iso8601> value' do
|
25
|
+
OXMLRPC::Serializer.serialize(Time.parse("19980717T14:08:55")).chomp
|
26
|
+
.should eq "<methodResponse><params><param><value><dateTime.iso8601>19980717T14:08:55</dateTime.iso8601></value></param></params></methodResponse>"
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should serialize <struct> value' do
|
30
|
+
OXMLRPC::Serializer.serialize({:x => 2, :y => "z"}).chomp
|
31
|
+
.should eq "<methodResponse><params><param><value><struct><member><name>x</name><value><int>2</int></value></member><member><name>y</name><value>z</value></member></struct></value></param></params></methodResponse>"
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should serialize <array> value' do
|
35
|
+
OXMLRPC::Serializer.serialize([12, "test"]).chomp
|
36
|
+
.should eq "<methodResponse><params><param><value><array><data><value><int>12</int></value><value>test</value></data></array></value></param></params></methodResponse>"
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should serialize <exception> value' do
|
40
|
+
pending
|
41
|
+
OXMLRPC::Serializer.serialize(StandardError.new("something wrong")).chomp
|
42
|
+
.should eq ""
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oxmlrpc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- fazibear
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ox
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Simple, lightweight and fast XML-RPC client library for ruby based on
|
47
|
+
OX XML parser.
|
48
|
+
email: fazibear@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/oxmlrpc.rb
|
54
|
+
- lib/oxmlrpc/parser.rb
|
55
|
+
- lib/oxmlrpc/serializer.rb
|
56
|
+
- spec/parser_spec.rb
|
57
|
+
- spec/serializer_spec.rb
|
58
|
+
- spec/spec_helper.rb
|
59
|
+
homepage: http://github.com/fazibear/oxmlrpc
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.23
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Fast and simple XML-RPC Client
|
83
|
+
test_files: []
|
84
|
+
has_rdoc:
|