Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Start to port over socket stuff from master. This doesn't quite work …
…yet, but builds. Also will need to fix up packages.
  • Loading branch information
jnthn committed Aug 8, 2011
1 parent 8fd1a35 commit e0867f0
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 4 deletions.
32 changes: 32 additions & 0 deletions src/core/IO/Socket.pm
@@ -0,0 +1,32 @@
my role Socket {
has $!PIO;
has $!buffer = '';

method recv (Int $bufsize = $Inf) {
fail('Socket not available') unless $!PIO;
my $received;
while $bufsize > $!buffer.bytes {
$received = nqp::p6box_s($!PIO.recv());
last unless $received.chars;
$!buffer ~= $received;
}
if $bufsize == $Inf {
$received = $!buffer;
$!buffer = '';
} else {
$received = $!buffer.substr(0, $bufsize);
$!buffer .= substr($bufsize);
}
return $received;
}

method send (Str $string) {
fail("Not connected") unless $!PIO;
return nqp::p6bool($!PIO.send($string));
}

method close () {
fail("Not connected!") unless $!PIO;
return nqp::p6bool($!PIO.close());
}
}
106 changes: 106 additions & 0 deletions src/core/IO/Socket/INET.pm
@@ -0,0 +1,106 @@
my module PIO {
constant PF_LOCAL = 0;
constant PF_UNIX = 1;
constant PF_INET = 2;
constant PF_INET6 = 3;
constant PF_MAX = 4;
constant SOCK_PACKET = 0;
constant SOCK_STREAM = 1;
constant SOCK_DGRAM = 2;
constant SOCK_RAW = 3;
constant SOCK_RDM = 4;
constant SOCK_SEQPACKET = 5;
constant SOCK_MAX = 6;
constant PROTO_TCP = 6;
constant PROTO_UDP = 17;
}

my class INET does Socket {
has Str $.host;
has Int $.port = 80;
has Str $.localhost;
has Int $.localport;
has Int $.listen;
has $.family = PIO::PF_INET;
has $.proto = PIO::PROTO_TCP;
has $.type = PIO::SOCK_STREAM;

my sub v4-split($uri) {
return $uri.split(':', 2);
}

my sub v6-split($uri) {
my ($host, $port) = ($uri ~~ /^'[' (.+) ']' \: (\d+)$/)[0,1];
return $host ?? ($host, $port) !! $uri;
}

method new (*%args is copy) {
fail "Nothing given for new socket to connect or bind to" unless %args<host> || %args<listen>;

if %args<host> {
my ($host, $port) = %args<family> && %args<family> == PIO::PF_INET6()
?? v6-split(%args<host>)
!! v4-split(%args<host>);
if $port {
%args<port> //= $port;
%args<host> = $host;
}
}
if %args<localhost> {
my ($peer, $port) = %args<family> && %args<family> == PIO::PF_INET6()
?? v6-split(%args<localhost>)
!! v4-split(%args<localhost>);
if $port {
%args<localport> //= $port;
%args<localhost> = $peer;
}
}

#TODO: Learn what protocols map to which socket types and then determine which is needed.
self.bless(*, |%args);
}

submethod BUILD {
my $PIO := Q:PIR { %r = root_new ['parrot';'Socket'] };
$PIO.socket($.family, $.type, $.proto);
#Quoting perl5's SIO::INET:
#If Listen is defined then a listen socket is created, else if the socket type,
#which is derived from the protocol, is SOCK_STREAM then connect() is called.
if $.listen || $.localhost || $.localport {
my $addr := $PIO.sockaddr($.localhost || "0.0.0.0", $.localport || 0);
$PIO.bind($addr);
}

if $.listen {
$PIO.listen($.listen);
}
elsif $.type == PIO::SOCK_STREAM() {
my $addr := $PIO.sockaddr($.host, $.port);
$PIO.connect($addr);
}

nqp::bindattr(self, INET, '$!PIO', $PIO);
self;
}

method get() {
nqp::p6box_s(nqp::getattr(self, INET, '$!PIO').readline).chomp
}

method lines() {
gather { take self.get() };
}

method accept() {
return nqp::p6bool(nqp::getattr(self, INET, '$!PIO').accept());
}

method remote_address() {
return nqp::p6box_s(nqp::getattr(self, INET, '$!PIO').remote_address());
}

method local_address() {
return nqp::p6box_s(nqp::getattr(self, INET, '$!PIO').local_address());
}
}
11 changes: 7 additions & 4 deletions tools/build/Makefile.in
Expand Up @@ -147,6 +147,11 @@ CORE_SOURCES = \
src/core/Any.pm \
src/core/Code.pm \
src/core/WhateverCode.pm \
src/core/Block.pm \
src/core/Routine.pm \
src/core/Sub.pm \
src/core/Method.pm \
src/core/Submethod.pm \
src/core/Attribute.pm \
src/core/Junction.pm \
src/core/Cool.pm \
Expand Down Expand Up @@ -177,12 +182,10 @@ CORE_SOURCES = \
src/core/Hash.pm \
src/core/Parameter.pm \
src/core/Signature.pm \
src/core/Block.pm \
src/core/Routine.pm \
src/core/Sub.pm \
src/core/Method.pm \
src/core/IO.pm \
src/core/IO/ArgFiles.pm \
src/core/IO/Socket.pm \
src/core/IO/Socket/INET.pm \
src/core/Rat.pm \
src/core/Complex.pm \
src/core/Exception.pm \
Expand Down

0 comments on commit e0867f0

Please sign in to comment.