Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Switch socket .get to use streaming decoder.
Therefore hopefully removing the last place that the VM-provided char
I/O on sockets is used.
  • Loading branch information
jnthn authored and zoffixznet committed May 26, 2017
1 parent bac02c5 commit a6ece95
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
39 changes: 31 additions & 8 deletions src/core/IO/Socket.pm
Expand Up @@ -6,8 +6,10 @@ my role IO::Socket {
has Rakudo::Internals::VMBackedDecoder $!decoder;

method !ensure-decoder(--> Nil) {
$!decoder.DEFINITE or
$!decoder := Rakudo::Internals::VMBackedDecoder.new($!encoding)
unless $!decoder.DEFINITE {
$!decoder := Rakudo::Internals::VMBackedDecoder.new($!encoding);
$!decoder.set-line-separators($!nl-in);
}
}

# The if bin is true, will return Buf, Str otherwise
Expand Down Expand Up @@ -44,16 +46,37 @@ my role IO::Socket {
$res
}

method nl-in is rw {
Proxy.new(
FETCH => { $!nl-in },
STORE => -> $, $nl-in {
$!nl-in = $nl-in;
with $!decoder {
.set-line-separators($!nl-in.list);
}
$nl-in
}
)
}

method get() {
my Mu $io := nqp::getattr(self, $?CLASS, '$!PIO');
nqp::setencoding($io, Rakudo::Internals.NORMALIZE_ENCODING($!encoding));
Rakudo::Internals.SET_LINE_ENDING_ON_HANDLE($io, $!nl-in);
my str $line = nqp::readlinechompfh($io);
if nqp::chars($line) || !nqp::eoffh($io) {
self!ensure-decoder();
my Str $line = $!decoder.consume-line-chars(:chomp);
if $line.DEFINITE {
$line
}
else {
Nil
loop {
my $read = nqp::readfh($!PIO, nqp::decont(buf8.new), 65535);
$!decoder.add-bytes($read);
$line = $!decoder.consume-line-chars(:chomp);
last if $line.DEFINITE;
if $read == 0 {
$line = $!decoder.consume-line-chars(:chomp, :eof);
last;
}
}
$line.DEFINITE ?? $line !! Nil
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/core/Rakudo/Internals/VMBackedDecoder.pm
Expand Up @@ -22,6 +22,17 @@ my class Rakudo::Internals::VMBackedDecoder is repr('Decoder') {
my str $result = nqp::decodertakechars(self, $chars);
nqp::isnull_s($result) ?? Str !! $result
}

method set-line-separators(@seps --> Nil) {
my $sep-strs := nqp::list_s();
nqp::push_s($sep-strs, .Str) for @seps;
nqp::decodersetlineseps(self, $sep-strs);
}

method consume-line-chars(Bool:D :$chomp = False, Bool:D :$eof = False --> Str) {
my str $line = nqp::decodertakeline(self, $chomp, $eof);
nqp::isnull_s($line) ?? Str !! $line
}
}

augment class Rakudo::Internals {
Expand Down

0 comments on commit a6ece95

Please sign in to comment.