Skip to content

Instantly share code, notes, and snippets.

@zoffixznet

zoffixznet/p6.p6 Secret

Last active April 12, 2017 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoffixznet/344a158837d5a1bd5d02b83e744675ce to your computer and use it in GitHub Desktop.
Save zoffixznet/344a158837d5a1bd5d02b83e744675ce to your computer and use it in GitHub Desktop.
use MONKEY;
augment class IO::Path {
method slurp3(IO::Path:D:) {
# We have two paths:
# 1) No args given; we open and slurp with just nqp ops. We also
# use a `try` on nqp::open to fail in the fast path if open fails.
# In that specific case we'll read the slow path and obtain proper
# Failure that we'll return
# 2) In slow path, just pop open IO::Handle and then have two branches:
# if we have file size, steal handle's $!PIO attr and read from it
# with nqp ops; otherwise, forward to IO::Handle.slurp
my $PIO;
nqp::if(
nqp::iseq_i(nqp::elems(nqp::getattr(%_,Map,'$!storage')),0)
&& ($PIO := try nqp::open(self.absolute,"r")),
nqp::stmts(
($_ := nqp::p6box_s(nqp::readallfh($PIO))),
nqp::closefh($PIO),
$_), # <-- we've succeeed in fast-path; that's the data
nqp::if(
nqp::istype(
(my $handle := IO::Handle.new(:path(self)).open(
:enc(%_<enc>), :bin(%_<bin>), :mode<ro>)),
Failure,),
$handle, # our open failed; return the Failure object here,
nqp::stmts(
($PIO := nqp::getattr($handle, IO::Handle, '$!PIO')),
nqp::if( %_<bin>,
nqp::if(
(my int $size = Rakudo::Internals.FILETEST-S(self.absolute)),
($_ := nqp::readfh($PIO, buf8.new, $size)),
nqp::stmts(
($_ := buf8.new),
nqp::while(
nqp::elems(
my $buf := nqp::readfh($PIO, buf8.new, 0x100000)),
.append($buf),
))),
($_ := nqp::p6box_s(nqp::readallfh($PIO)))),
nqp::closefh($PIO),
$_))) # <-- we've succeeded in slow-path; that's the data
}
}
'/tmp/meow'.IO.spurt: 'bar';
$ = '/tmp/meow'.IO.slurp3: :bin for ^3000;
say "no crash";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment