--- AnyEvent-FCP/FCP.pm 2015/08/08 04:07:28 1.13 +++ AnyEvent-FCP/FCP.pm 2015/09/05 13:26:47 1.16 @@ -71,6 +71,8 @@ use AnyEvent::Handle; use AnyEvent::Util (); +our %TOLC; # tolc cache + sub touc($) { local $_ = shift; 1 while s/((?:^|_)(?:svk|chk|uri|fcp|ds|mime|dda)(?:_|$))/\U$1/; @@ -98,6 +100,9 @@ sub new { my $class = shift; + + my $rand = join "", map chr 0x21 + rand 94, 1..40; # ~ 262 bits entropy + my $self = bless { host => $ENV{FREDHOST} || "127.0.0.1", port => $ENV{FREDPORT} || 9481, @@ -106,7 +111,8 @@ @_, queue => [], req => {}, - id => "a0", + prefix => "..:aefcpid:$rand:", + idseq => "a0", }, $class; { @@ -133,13 +139,17 @@ $self } +sub identifier { + $_[0]{prefix} . ++$_[0]{idseq} +} + sub send_msg { my ($self, $type, %kv) = @_; my $data = delete $kv{data}; if (exists $kv{id_cb}) { - my $id = $kv{identifier} ||= ++$self->{id}; + my $id = $kv{identifier} ||= $self->identifier; $self->{id}{$id} = delete $kv{id_cb}; } @@ -226,7 +236,7 @@ my $id = $kv->{identifier}; my $req = $_[0]{req}{$id} ||= {}; $cb->($self, $req, $kv); - $self->recv (request_change => $kv, $type, @extra); + $self->recv (request_changed => $kv, $type, @extra); } my $on = $self->{on}; @@ -248,26 +258,34 @@ sub on_read { my ($self) = @_; - my $type; + my ($k, $v, $type); my %kv; my $rdata; my $hdr_cb; $hdr_cb = sub { - if ($_[1] =~ /^([^=]+)=(.*)$/) { - my ($k, $v) = ($1, $2); - my @k = split /\./, tolc $k; - my $ro = \\%kv; - - while (@k) { - my $k = shift @k; - if ($k =~ /^\d+$/) { - $ro = \$$ro->[$k]; - } else { - $ro = \$$ro->{$k}; + if (($v = index $_[1], "=") >= 0) { + $k = substr $_[1], 0, $v; + $v = substr $_[1], $v + 1; + $k = ($TOLC{$k} ||= tolc $k); + + if ($k !~ /\./) { + # special case common case, for performance only + $kv{$k} = $v; + } else { + my @k = split /\./, $k; + my $ro = \\%kv; + + while (@k) { + $k = shift @k; + if ($k =~ /^\d+$/) { + $ro = \$$ro->[$k]; + } else { + $ro = \$$ro->{$k}; + } } - } - $$ro = $v; + $$ro = $v; + } $_[0]->push_read (line => $hdr_cb); } elsif ($_[1] eq "Data") { @@ -283,7 +301,7 @@ }; $self->{hdl}->push_read (line => sub { - $type = tolc $_[1]; + $type = ($TOLC{$_[1]} ||= tolc $_[1]); $_[0]->push_read (line => $hdr_cb); }); } @@ -373,7 +391,7 @@ *{$name} = sub { my $cv = AE::cv; - splice @_, 1, 0, $cv, sub { $cv->throw ($_[0]{extra_description}) }; + splice @_, 1, 0, $cv, sub { $cv->croak ($_[0]{extra_description}) }; &$sub; $cv->recv }; @@ -384,11 +402,11 @@ if (ARRAY:: eq ref $ok) { ($ok, $err) = @$ok; } elsif (UNIVERSAL::isa $ok, AnyEvent::CondVar::) { - $err = sub { $ok->throw ($_[0]{extra_description}) }; + $err = sub { $ok->croak ($_[0]{extra_description}) }; } else { my $bt = Carp::longmess ""; $err = sub { - die "$_[0]{extra_description}$bt"; + die "$_[0]{code_description} ($_[0]{extra_description})$bt"; }; } @@ -543,16 +561,27 @@ _txn get_plugin_info => sub { my ($self, $ok, $err, $name, $detailed) = @_; + my $id = $self->identifier; + $self->send_msg (get_plugin_info => + identifier => $id, plugin_name => $name, detailed => $detailed ? "true" : "false", - id_cb => sub { - my ($self, $type, $kv, $rdata) = @_; - - $ok->($kv); - 1 - }, ); + $self->on (sub { + my ($self, $type, $kv) = @_; + + if ($kv->{identifier} eq $id) { + if ($type eq "get_plugin_info") { + $ok->($kv); + } else { + $err->($kv, $type); + } + return; + } + + 1 + }); }; =item $status = $fcp->client_get ($uri, $identifier, %kv)