Date: 2008-01-30 19:29
Sender: Larry Karnowski
Wait, and the file didn't attach? (I'm not very impressed with
this patch submission tool.) Here's the patch:
Index: test/test_hessian_parser.rb
=================================================================
==
--- test/test_hessian_parser.rb (revision 26)
+++ test/test_hessian_parser.rb (working copy)
@@ -34,22 +34,33 @@
assert_equal 520000, time.usec
end
def test_integer_array
- assert_equal [ 1, 2, 3 ], parse([
"r\001\000Vt\000\004[intl\000\000\000\003",
+ array = parse([ "r\001\000Vt\000\004[intl\000\000\000\0
03",
"I\000\000\000\001I\000\000\000\002I\000\000\000\003z
z" ].join)
+ assert_equal [ 1, 2, 3 ], array
+ assert_equal "[int", array.hessian_type
end
def test_array
- assert_equal [ 'sillen', 32 ], parse([
"r\001\000Vt\000\a[objectl\000\000\000\002",
+ array = parse([ "r\001\000Vt\000\a[objectl\000\000\000\
002",
"S\000\006sillenI\000\000\000 zz" ].join)
+ assert_equal [ 'sillen', 32 ], array
+ assert_equal "[object", array.hessian_type
end
def test_array_in_array
- assert_equal [ 'A list', [ 9, 3 ] ], parse([
"r\001\000Vl\000\000\000\002S\000\006",
+ array = parse([ "r\001\000Vl\000\000\000\002S\000\006&q
uot;,
"A listVt\000\022[java.lang.Integerl\000\000\000\002I
\000\000\000\t",
"I\000\000\000\003zzz" ].join)
+ assert_equal [ 'A list', [ 9, 3 ] ], array
+
+ # the outer array was not typed
+ assert !array.respond_to?("hessian_type")
+ # but the inner array was typed
+ assert_equal "[java.lang.Integer",
array[1].hessian_type
end
def test_map
- map = { 'sillen' => 32, 'numbers' => [ 1.1, 1.2, 1.3
] }
- assert_equal map, parse([
"r\001\000Mt\000\000S\000\anumbersVt\000\a[double",
+ map = parse([ "r\001\000Mt\000\000S\000\anumbersVt\000\
a[double",
"l\000\000\000\003D?\361\231\231\231\231\231\232D?\36
3333333D?",
- "\364\314\314\314\314\314\315zS\000\006sillenI\000\000\000
zz" ].join)
- end
+ "\364\314\314\314\314\314\315zS\000\006sillenI\000\000\000
zz" ].join)
+ assert_equal({ 'sillen' => 32, 'numbers' => [ 1.1,
1.2, 1.3 ] }, map)
+ assert_equal "", map.hessian_type
+ end
end
Index: lib/hessian.rb
=================================================================
==
--- lib/hessian.rb (revision 26)
+++ lib/hessian.rb (working copy)
@@ -10,6 +10,22 @@
end
end
+ class HessianTypedArray < Array
+ attr_accessor :hessian_type
+ def initialize(hessian_type, object=[])
+ @hessian_type = hessian_type
+ super(object)
+ end
+ end
+
+ class HessianTypedHash < Hash
+ attr_accessor :hessian_type
+ def initialize(hessian_type, object=nil)
+ @hessian_type = hessian_type
+ super(object)
+ end
+ end
+
class Binary
attr :data
def initialize(data)
@@ -19,8 +35,10 @@
class HessianException < RuntimeError
attr_reader :code
- def initialize(code)
+ attr_reader :details
+ def initialize(code, details)
@code = code
+ @details = details
end
end
@@ -160,22 +178,22 @@
when 'R': @refs[@data.slice!(0, 4).unpack('N')[0]]
when 'V'
# Skip type + type length (2 bytes) if specified.
- @data.slice!(0, 3 + @data.unpack('an')[1]) if @data[0,1]
== 't'
+ hessian_type = parse_hessian_type if @data[0,1] ==
't'
# Skip the list length if specified.
@data.slice!(0, 5) if @data[0,1] == 'l'
- @refs << (list = [])
+ @refs << (list = hessian_type
? HessianTypedArray.new(hessian_type) : [])
list << parse_object while @data[0,1] != 'z'
# Get rid of the 'z'.
@data.slice!(0, 1)
list
when 'M'
# Skip type + type length (2 bytes) if specified.
- @data.slice!(0, 3 + @data.unpack('an')[1]) if @data[0,1]
== 't'
- @refs << (map = {})
+ hessian_type = parse_hessian_type if @data[0,1] ==
't'
+ @refs << (map = hessian_type
? HessianTypedHash.new(hessian_type) : {})
map[parse_object()] = parse_object while @data[0,1]
!= 'z'
# Get rid of the 'z'.
@data.slice!(0, 1)
- map
+ map
else
raise "Invalid type: '#{t}'"
end
@@ -191,6 +209,13 @@
@data.slice!(0, 8).each_byte { |b| val += (b & 0xff)
<< o; o -= 8 }
val
end
+
+ def parse_hessian_type
+ @data.slice!(0,1) #remove the 't'
+ length = @data.unpack('n')[0]
+ @data.slice!(0,2) # remove the type length
+ hessian_type = @data.slice!(0, length)
+ end
def raise_exception
# Skip code description.
@@ -199,7 +224,11 @@
# Skip message description
parse_object
msg = parse_object
- raise HessianException.new(code), msg
+ # Skip details description
+ parse_object
+ details = parse_object
+
+ raise HessianException.new(code, details), msg
end
end
end |