Skip Menu |

This queue is for tickets about the Net-DBus CPAN distribution.

Report information
The Basics
Id: 73313
Status: resolved
Priority: 0/
Queue: Net-DBus

People
Owner: Nobody in particular
Requestors: hugosenari [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: Can't parse type with a(asaasay)
Hi, I have problem to call methods from zeitgeist that have signature a(asaasay). I think the problem is in Introspector.pm:_parse_type when parse type with "aa..." (array of array of anything) In my tests I solved this changing in sub _parse_type: if ($current->[0] eq "array") { $current = pop @cont; } by: while ($current->[0] eq "array"){ $current = pop @cont; } Thanks for this nice module.
Subject: parse_type.pl
use Data::Dumper; our %simple_type_map = ( "byte" => ord('y'), "bool" => ord('b'), "double" => ord('d'), "string" => ord('s'), "int16" => ord('n'), "uint16" => ord('q'), "int32" => ord('i'), "uint32" => ord('u'), "int64" => ord('x'), "uint64" => ord('t'), "objectpath" => ord('o'), "signature" => ord('g'), ); our %simple_type_rev_map = ( ord('y') => "byte", ord('b') => "bool", ord('d') => "double", ord('s') => "string", ord('n') => "int16", ord('q') => "uint16", ord('i') => "int32", ord('u') => "uint32", ord('x') => "int64", ord('t') => "uint64", ord('o') => "objectpath", ord('g') => "signature", ); sub _parse_type { my $sig = shift; print "parsing type\n"; my $root = []; my $current = $root; my @cont; while (my $type = shift @{$sig}) { if (exists $simple_type_rev_map{ord($type)}) { push @{$current}, $simple_type_rev_map{ord($type)}; while ($current->[0] eq "array"){ #if ($current->[0] eq "array") { $current = pop @cont; #} } } else { if ($type eq "(") { my $new = ["struct"]; push @{$current}, $new; push @cont, $current; $current = $new; } elsif ($type eq "a") { my $new = ["array"]; push @cont, $current; push @{$current}, $new; $current = $new; } elsif ($type eq "{") { if ($current->[0] ne "array") { die "dict must only occur within an array"; } $current->[0] = "dict"; } elsif ($type eq ")") { die "unexpected end of struct" unless $current->[0] eq "struct"; $current = pop @cont; while ($current->[0] eq "array") { $current = pop @cont; } } elsif ($type eq "}") { die "unexpected end of dict" unless $current->[0] eq "dict"; $current = pop @cont; while ($current->[0] eq "array") { $current = pop @cont; } } elsif ($type eq "v") { push @{$current}, ["variant"]; while ($current->[0] eq "array") { $current = pop @cont; } } else { die "unknown type sig '$type'"; } } } print "$type\n"; print "current: ", Dumper($current); print "cont: ", Dumper(@cont); print "\n============================================================\n"; return @{$root}; } _parse_type(["a","(","a","a","s","a","a","s","a","y",")"]); #_parse_type(["(","a","a","s","a","a","s","a","y",")"]); #_parse_type(["a","(","a","s","a","a","a","a","a","a","s","a","y",")"]); #$type = "a(asaasay)"; #print _parse_type(@type);
From: hugosenari [...] gmail.com
Adding another file, maybe help you to test. On Fri Dec 16 06:00:01 2011, hugosenari wrote: Show quoted text
> Hi, > > I have problem to call methods from zeitgeist that have signature > a(asaasay). > > I think the problem is in Introspector.pm:_parse_type when parse type > with "aa..." (array of array of anything) > > In my tests I solved this changing in sub _parse_type: > if ($current->[0] eq "array") { > $current = pop @cont; > } > > by: > while ($current->[0] eq "array"){ > $current = pop @cont; > } > > > > Thanks for this nice module.
Subject: parse_type_zeitgeist.pl
use Net::DBus; use Net::DBus ':typing'; use Data::Dumper; my $bus=Net::DBus->session; # Get a handle to the Zeitgeist service my $zeitgeist = $bus->get_service("org.gnome.zeitgeist.Engine"); # Get the device manager my $logger = $zeitgeist->get_object("/org/gnome/zeitgeist/log/activity", "org.gnome.zeitgeist.Log"); $value = dbus_array([dbus_uint32(1)]); $logger->GetEvents($value); print Dumper( $logger->GetEvents( $value ) ); #http://zeitgeist-project.com/docs/0.7.1/dbus_api.html
From: hugosenari [...] gmail.com
My patch with solution and tests On Fri Dec 16 06:05:32 2011, hugosenari wrote: Show quoted text
> Adding another file, maybe help you to test. > > On Fri Dec 16 06:00:01 2011, hugosenari wrote:
> > Hi, > > > > I have problem to call methods from zeitgeist that have signature > > a(asaasay). > > > > I think the problem is in Introspector.pm:_parse_type when parse type > > with "aa..." (array of array of anything) > > > > In my tests I solved this changing in sub _parse_type: > > if ($current->[0] eq "array") { > > $current = pop @cont; > > } > > > > by: > > while ($current->[0] eq "array"){ > > $current = pop @cont; > > } > > > > > > > > Thanks for this nice module.
>
Subject: Net-DBus-1.0.0-arrayofarray.patch
diff -ruN /home/hugosenari/devel/perldbus/Net-DBus-1.0.0-orig/lib/Net/DBus/Binding/Introspector.pm Net-DBus-1.0.0-new/lib/Net/DBus/Binding/Introspector.pm --- /home/hugosenari/devel/perldbus/Net-DBus-1.0.0-orig/lib/Net/DBus/Binding/Introspector.pm 2011-06-30 18:32:04.000000000 -0300 +++ Net-DBus-1.0.0-new/lib/Net/DBus/Binding/Introspector.pm 2012-01-10 03:46:41.279667971 -0200 @@ -768,7 +768,7 @@ while (my $type = shift @{$sig}) { if (exists $simple_type_rev_map{ord($type)}) { push @{$current}, $simple_type_rev_map{ord($type)}; - if ($current->[0] eq "array") { + while ($current->[0] eq "array") { $current = pop @cont; } } else { @@ -791,19 +791,19 @@ die "unexpected end of struct" unless $current->[0] eq "struct"; $current = pop @cont; - if ($current->[0] eq "array") { + while ($current->[0] eq "array") { $current = pop @cont; } } elsif ($type eq "}") { die "unexpected end of dict" unless $current->[0] eq "dict"; $current = pop @cont; - if ($current->[0] eq "array") { + while ($current->[0] eq "array") { $current = pop @cont; } } elsif ($type eq "v") { push @{$current}, ["variant"]; - if ($current->[0] eq "array") { + while ($current->[0] eq "array") { $current = pop @cont; } } else { diff -ruN /home/hugosenari/devel/perldbus/Net-DBus-1.0.0-orig/t/80-object-introspect-types.t Net-DBus-1.0.0-new/t/80-object-introspect-types.t --- /home/hugosenari/devel/perldbus/Net-DBus-1.0.0-orig/t/80-object-introspect-types.t 1969-12-31 21:00:00.000000000 -0300 +++ Net-DBus-1.0.0-new/t/80-object-introspect-types.t 2012-01-10 04:42:33.134758855 -0200 @@ -0,0 +1,160 @@ +# -*- perl -*- +use Test::More tests => 13; + +use strict; +use warnings; + +BEGIN { + use_ok('Net::DBus::Binding::Introspector'); +}; + +local $/ = undef; +my $xml = <DATA>; + +my $introspector = Net::DBus::Binding::Introspector->new(object_path => "/net/dbus/binding/introspector", + xml => $xml); + +isa_ok($introspector, "Net::DBus::Binding::Introspector"); + +ok($introspector->has_interface("org.freedesktop.DBus.Introspectable"), + "org.freedesktop.DBus.Introspectable interface present"); + +ok($introspector->has_interface("net.dbus.binding.Introspector"), + "net.dbus.binding.Introspector interface present"); + + + +ok($introspector->has_method("WithoutArgs"), "WithoutArgs method present"); +ok($introspector->has_method("WithArg"), "WithArg method present"); +ok($introspector->has_method("WithoutInArg"), "WithoutInArg method present"); +ok($introspector->has_method("WithArgs"), "WithArgs method present"); +ok($introspector->has_method("AllTypeOfArgs"), "AllTypeOfArgs method present"); +ok($introspector->has_method("ComplexTypeOfArgs"), "ComplexTypeOfArgs method present"); +ok($introspector->has_signal("BrianSignal"), "BrianSignal signal present"); +ok($introspector->has_property("ReadProperty"), "ReadProperty property present"); +ok($introspector->has_property("ReadWriteProperty"), "ReadWriteProperty property present"); + +#TODO: Verify if this is valid +#ok($introspector->has_interface("net.dbus.binding.introspector.Child"), +# "net.dbus.binding.introspector.Child interface present"); +#ok($introspector->has_method("ChildNodeMethod"), "ChildNodeMethod method present"); +#ok($introspector->has_signal("ChildNodeSignal"), "ChildNodeSignal signal present"); +#ok($introspector->has_property("ChildNodeProperty"), "ChildNodeProperty property present"); + +__DATA__ + +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<!-- + This interface try to test most of dbus variations +--> +<node> + <interface name="org.freedesktop.DBus.Introspectable"> + <method name="Introspect"> + <arg type="s" name="xml_data" direction="out"/> + </method> + </interface> + <interface name="net.dbus.binding.Introspector"> + + <!-- methods --> + <method name="WithoutArgs"/> + <method name="WithArg"> + <arg type="b" name="some_arg"/> + </method> + <method name="WithoutInArg"> + <arg type="b" name="result" direction="out"/> + </method> + <method name="WithArgs"> + <arg type="b" name="some_arg"/> + <arg type="b" name="result" direction="out"/> + </method> + + <method name="AllTypeOfArgs"> + <!-- to test if lib can parse all possible simple types --> + <arg type="y" name="some_byte_arg" direction="in"/> + <arg type="b" name="some_arg" direction="in"/> + <arg type="n" name="some_int16_arg" direction="in"/> + <arg type="q" name="some_uint16_arg" direction="in"/> + <arg type="i" name="some_int32_arg" direction="in"/> + <arg type="u" name="some_uint32_arg" direction="in"/> + <arg type="x" name="some_int64_arg" direction="in"/> + <arg type="t" name="some_uint64_arg" direction="in"/> + <arg type="d" name="some_double_arg" direction="in"/> + <arg type="s" name="some_string_arg" direction="in"/> + <arg type="o" name="some_object_path_arg" direction="in"/> + <!-- #TODO: unknow type unix file descriptor --> + <!--arg type="h" name="some_unix_fd_arg" direction="in"/--> + <arg type="b" name="result" direction="out"/> + </method> + + <method name="ComplexTypeOfArgs"> + <!-- to test if lib can parse possible complex types --> + <!-- array tests --> + <arg type="ay" name="array_byte_arg" direction="in"/> + <arg type="ab" name="array_arg" direction="in"/> + <arg type="an" name="array_int16_arg" direction="in"/> + <arg type="aq" name="array_uint16_arg" direction="in"/> + <arg type="ai" name="array_int32_arg" direction="in"/> + <arg type="au" name="array_uint32_arg" direction="in"/> + <arg type="ax" name="array_int64_arg" direction="in"/> + <arg type="at" name="array_uint64_arg" direction="in"/> + <arg type="ad" name="array_double_arg" direction="in"/> + <arg type="as" name="array_string_arg" direction="in"/> + <arg type="ao" name="array_object_path_arg" direction="in"/> + <!--arg type="ah" name="array_unix_fd_arg" direction="in"/--> + <arg type="aaaaaaab" name="array_array_arg" direction="in"/> + <!-- structure tests --> + <arg type="(y)" name="struct_byte_arg" direction="in"/> + <arg type="(b)" name="struct_arg" direction="in"/> + <arg type="(n)" name="struct_int16_arg" direction="in"/> + <arg type="(q)" name="struct_uint16_arg" direction="in"/> + <arg type="(i)" name="struct_int32_arg" direction="in"/> + <arg type="(u)" name="struct_uint32_arg" direction="in"/> + <arg type="(x)" name="struct_int64_arg" direction="in"/> + <arg type="(t)" name="struct_uint64_arg" direction="in"/> + <arg type="(d)" name="struct_double_arg" direction="in"/> + <arg type="(s)" name="struct_string_arg" direction="in"/> + <arg type="(o)" name="struct_object_path_arg" direction="in"/> + <!--arg type="(h)" name="struct_unix_fd_arg" direction="in"/--> + <arg type="(ybnqiuxtdso)" name="struct_arg" direction="in"/> + <!--arg type="(ybnqiuxtdsoh)" name="struct_arg" direction="in"/--> + <arg type="a(aaaaaab)" name="struct_array_arg" direction="in"/> + <arg type="aa(aa(aa(aa(aa(aa(aab))))))" name="struct_array_array_arg" direction="in"/> + <!-- dict tests --> + <arg type="a{yy}" name="dict_byte_arg" direction="in"/> + <arg type="a{bb}" name="dict_arg" direction="in"/> + <arg type="a{nn}" name="dict_int16_arg" direction="in"/> + <arg type="a{qq}" name="dict_uint16_arg" direction="in"/> + <arg type="a{ii}" name="dict_int32_arg" direction="in"/> + <arg type="a{uu}" name="dict_uint32_arg" direction="in"/> + <arg type="a{xx}" name="dict_int64_arg" direction="in"/> + <arg type="a{tt}" name="dict_uint64_arg" direction="in"/> + <arg type="a{dd}" name="dict_double_arg" direction="in"/> + <arg type="a{ss}" name="dict_string_arg" direction="in"/> + <arg type="a{oo}" name="dict_object_path_arg" direction="in"/> + <!--arg type="a{hh}" name="dict_unix_fd_arg" direction="in"/--> + <arg type="a(a(a{yy}aa{bb}a{nn}a{qq}a(a{ii}a{uu}a{xx})aa{tt}a{dd}aa{ss}a{oo}))" name="struct_arg" direction="in"/> + <!--arg type="a(a(a{yy}aa{bb}a{nn}a{qq}a(a{ii}a{uu}a{xx})aa{tt}a{dd}aa{ss}a{oo}a{hh}))" name="struct_arg" direction="in"/--> + + <arg type="a(asaasay)" name="result" direction="out"/> + </method> + + <!-- signals --> + <signal name="BrianSignal"> + <arg name="he_is_messiah" type="b"/> + </signal> + + <!-- properties --> + <property type="b" name="ReadProperty" access="read"/> + <property type="b" name="ReadWriteProperty" access="readwrite"/> + </interface> + <!-- node name="child_node"> + <interface name="net.dbus.binding.introspector.Child"> + <method name="ChildNodeMethod"></method> + <signal name="ChildNodeSignal"> + <arg name="child_node_signal" type="b"/> + </signal> + <property type="b" name="ChildNodeProperty" access="read"/> + </interface> + </node--> +</node> \ No newline at end of file
Thanks for your patch, I can confirm the proposed fix is good. I've refactored the code to make testing a little easier. So this is fixed in two commits. commit 691fe9556102a7d64020f44cd57106c179f510c7 Author: Hugo Senari <hugosenari@gmail.com> Date: Sun Apr 7 19:20:09 2013 +0100 Fix handling of nested arrays/dicts/etc Signatures like a(asaasay) where no correctly handled, because not enough state was popped when closing compound types. RT #73313 commit 8723a36e4897fc2c5e4ced7798731dd18b39eb34 Author: Daniel P. Berrange <dan@berrange.com> Date: Sun Apr 7 19:13:07 2013 +0100 Move type parsing / formatting into Net::DBus::Binding::Type class Create a new class dedicated to parsing/formatting type strings, to allow for easier testing of functionality Signed-off-by: Daniel P. Berrange <dan@berrange.com>
This is now resolved in the 1.1.0 release