ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-FCP/FCP.pm
(Generate patch)

Comparing cvsroot/Net-FCP/FCP.pm (file contents):
Revision 1.33 by root, Sun May 16 00:19:38 2004 UTC vs.
Revision 1.39 by root, Tue Nov 28 15:18:17 2006 UTC

13 13
14=head1 DESCRIPTION 14=head1 DESCRIPTION
15 15
16See L<http://freenet.sourceforge.net/index.php?page=fcp> for a description 16See L<http://freenet.sourceforge.net/index.php?page=fcp> for a description
17of what the messages do. I am too lazy to document all this here. 17of what the messages do. I am too lazy to document all this here.
18
19The module uses L<AnyEvent> to find a suitable Event module.
18 20
19=head1 WARNING 21=head1 WARNING
20 22
21This module is alpha. While it probably won't destroy (much :) of your 23This module is alpha. While it probably won't destroy (much :) of your
22data, it currently falls short of what it should provide (intelligent uri 24data, it currently falls short of what it should provide (intelligent uri
23following, splitfile downloads, healing...) 25following, splitfile downloads, healing...)
24 26
25=head2 IMPORT TAGS 27=head2 IMPORT TAGS
26 28
27Nothing much can be "imported" from this module right now. There are, 29Nothing much can be "imported" from this module right now.
28however, certain "import tags" that can be used to select the event model
29to be used.
30
31Event models are implemented as modules under the C<Net::FCP::Event::xyz>
32class, where C<xyz> is the event model to use. The default is C<Event> (or
33later C<Auto>).
34
35The import tag to use is named C<event=xyz>, e.g. C<event=Event>,
36C<event=Glib> etc.
37
38You should specify the event module to use only in the main program.
39
40If no event model has been specified, FCP tries to autodetect it on first
41use (e.g. first transaction), in this order: Coro, Event, Glib, Tk.
42 30
43=head2 FREENET BASICS 31=head2 FREENET BASICS
44 32
45Ok, this section will not explain any freenet basics to you, just some 33Ok, this section will not explain any freenet basics to you, just some
46problems I found that you might want to avoid: 34problems I found that you might want to avoid:
72 60
73package Net::FCP; 61package Net::FCP;
74 62
75use Carp; 63use Carp;
76 64
77$VERSION = 0.7; 65$VERSION = '1.0';
78 66
79no warnings; 67no warnings;
68
69use AnyEvent;
80 70
81use Net::FCP::Metadata; 71use Net::FCP::Metadata;
82use Net::FCP::Util qw(tolc touc xeh); 72use Net::FCP::Util qw(tolc touc xeh);
83
84our $EVENT = Net::FCP::Event::Auto::;
85
86sub import {
87 shift;
88
89 for (@_) {
90 if (/^event=(\w+)$/) {
91 $EVENT = "Net::FCP::Event::$1";
92 eval "require $EVENT";
93 }
94 }
95 die $@ if $@;
96}
97 73
98=item $fcp = new Net::FCP [host => $host][, port => $port][, progress => \&cb] 74=item $fcp = new Net::FCP [host => $host][, port => $port][, progress => \&cb]
99 75
100Create a new virtual FCP connection to the given host and port (default 76Create a new virtual FCP connection to the given host and port (default
101127.0.0.1:8481, or the environment variables C<FREDHOST> and C<FREDPORT>). 77127.0.0.1:8481, or the environment variables C<FREDHOST> and C<FREDPORT>).
406 382
407sub new { 383sub new {
408 my $class = shift; 384 my $class = shift;
409 my $self = bless { @_ }, $class; 385 my $self = bless { @_ }, $class;
410 386
411 $self->{signal} = $EVENT->new_signal; 387 $self->{signal} = AnyEvent->condvar;
412 388
413 $self->{fcp}{txn}{$self} = $self; 389 $self->{fcp}{txn}{$self} = $self;
414 390
415 my $attr = ""; 391 my $attr = "";
416 my $data = delete $self->{attr}{data}; 392 my $data = delete $self->{attr}{data};
428 404
429 socket my $fh, PF_INET, SOCK_STREAM, 0 405 socket my $fh, PF_INET, SOCK_STREAM, 0
430 or Carp::croak "unable to create new tcp socket: $!"; 406 or Carp::croak "unable to create new tcp socket: $!";
431 binmode $fh, ":raw"; 407 binmode $fh, ":raw";
432 fcntl $fh, F_SETFL, O_NONBLOCK; 408 fcntl $fh, F_SETFL, O_NONBLOCK;
433 connect $fh, (sockaddr_in $self->{fcp}{port}, inet_aton $self->{fcp}{host}) 409 connect $fh, (sockaddr_in $self->{fcp}{port}, inet_aton $self->{fcp}{host});
434 and !$!{EWOULDBLOCK}
435 and !$!{EINPROGRESS}
436 and Carp::croak "FCP::txn: unable to connect to $self->{fcp}{host}:$self->{fcp}{port}: $!\n"; 410# and Carp::croak "FCP::txn: unable to connect to $self->{fcp}{host}:$self->{fcp}{port}: $!\n";
437 411
438 $self->{sbuf} = 412 $self->{sbuf} =
439 "\x00\x00\x00\x02" 413 "\x00\x00\x00\x02"
440 . (Net::FCP::touc $self->{type}) 414 . (Net::FCP::touc $self->{type})
441 . "\012$attr$data"; 415 . "\012$attr$data";
442 416
443 #shutdown $fh, 1; # freenet buggy?, well, it's java... 417 #shutdown $fh, 1; # freenet buggy?, well, it's java...
444 418
445 $self->{fh} = $fh; 419 $self->{fh} = $fh;
446 420
447 $self->{w} = $EVENT->new_from_fh ($fh) 421 $self->{w} = AnyEvent->io (fh => $fh, poll => 'w', cb => sub { $self->fh_ready_w });
448 ->cb (sub { $self->fh_ready_w })
449 ->poll (0, 1, 1);
450 422
451 $self; 423 $self;
452} 424}
453 425
454=item $txn = $txn->cb ($coderef) 426=item $txn = $txn->cb ($coderef)
490 $self; 462 $self;
491} 463}
492 464
493=item $txn->cancel (%attr) 465=item $txn->cancel (%attr)
494 466
495Cancels the operation with a C<cancel> exception anf the given attributes 467Cancels the operation with a C<cancel> exception and the given attributes
496(consider at least giving the attribute C<reason>). 468(consider at least giving the attribute C<reason>).
497 469
498UNTESTED. 470UNTESTED.
499 471
500=cut 472=cut
513 485
514 if ($len > 0) { 486 if ($len > 0) {
515 substr $self->{sbuf}, 0, $len, ""; 487 substr $self->{sbuf}, 0, $len, "";
516 unless (length $self->{sbuf}) { 488 unless (length $self->{sbuf}) {
517 fcntl $self->{fh}, F_SETFL, 0; 489 fcntl $self->{fh}, F_SETFL, 0;
518 $self->{w}->cb(sub { $self->fh_ready_r })->poll (1, 0, 1); 490 $self->{w} = AnyEvent->io (fh => $self->{fh}, poll => 'r', cb => sub { $self->fh_ready_r });
519 } 491 }
520 } elsif (defined $len) { 492 } elsif (defined $len) {
521 $self->throw (Net::FCP::Exception->new (network_error => { reason => "unexpected end of file while writing" })); 493 $self->throw (Net::FCP::Exception->new (network_error => { reason => "unexpected end of file while writing" }));
522 } else { 494 } else {
523 $self->throw (Net::FCP::Exception->new (network_error => { reason => "$!" })); 495 $self->throw (Net::FCP::Exception->new (network_error => { reason => "$!" }));
525} 497}
526 498
527sub fh_ready_r { 499sub fh_ready_r {
528 my ($self) = @_; 500 my ($self) = @_;
529 501
530 if (sysread $self->{fh}, $self->{buf}, 65536, length $self->{buf}) { 502 if (sysread $self->{fh}, $self->{buf}, 16384 + 1024, length $self->{buf}) {
531 for (;;) { 503 for (;;) {
532 if ($self->{datalen}) { 504 if ($self->{datalen}) {
533 #warn "expecting new datachunk $self->{datalen}, got ".(length $self->{buf})."\n";#d# 505 #warn "expecting new datachunk $self->{datalen}, got ".(length $self->{buf})."\n";#d#
534 if (length $self->{buf} >= $self->{datalen}) { 506 if (length $self->{buf} >= $self->{datalen}) {
535 $self->rcv_data (substr $self->{buf}, 0, delete $self->{datalen}, ""); 507 $self->rcv_data (substr $self->{buf}, 0, delete $self->{datalen}, "");
588 my ($self, $result) = @_; 560 my ($self, $result) = @_;
589 561
590 unless (exists $self->{result}) { 562 unless (exists $self->{result}) {
591 $self->{result} = $result; 563 $self->{result} = $result;
592 $self->{cb}->($self) if exists $self->{cb}; 564 $self->{cb}->($self) if exists $self->{cb};
593 $self->{signal}->send; 565 $self->{signal}->broadcast;
594 } 566 }
595} 567}
596 568
597sub eof { 569sub eof {
598 my ($self) = @_; 570 my ($self) = @_;
838 810
839=head1 BUGS 811=head1 BUGS
840 812
841=head1 AUTHOR 813=head1 AUTHOR
842 814
843 Marc Lehmann <pcg@goof.com> 815 Marc Lehmann <schmorp@schmorp.de>
844 http://www.goof.com/pcg/marc/ 816 http://home.schmorp.de/
845 817
846=cut 818=cut
847 819
848package Net::FCP::Event::Auto; 8201
849 821
850my @models = (
851 [Coro => Coro::Event::],
852 [Event => Event::],
853 [Glib => Glib::],
854 [Tk => Tk::],
855);
856
857sub AUTOLOAD {
858 $AUTOLOAD =~ s/.*://;
859
860 for (@models) {
861 my ($model, $package) = @$_;
862 if (defined ${"$package\::VERSION"}) {
863 $EVENT = "Net::FCP::Event::$model";
864 eval "require $EVENT"; die if $@;
865 goto &{"$EVENT\::$AUTOLOAD"};
866 }
867 }
868
869 for (@models) {
870 my ($model, $package) = @$_;
871 $EVENT = "Net::FCP::Event::$model";
872 if (eval "require $EVENT") {
873 goto &{"$EVENT\::$AUTOLOAD"};
874 }
875 }
876
877 die "No event module selected for Net::FCP and autodetect failed. Install any of these: Coro, Event, Glib or Tk.";
878}
879
8801;
881

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines