1. my role IO::Socket does IO {
  2. has $!PIO;
  3. # JVM has a buffer here; Moar does enough buffering of its own
  4. # and gets it much more correct when bytes cross boundaries, so we use its.
  5. # if bin is true, will return Buf, Str otherwise
  6. method recv (Cool $chars = Inf, :$bin? = False) {
  7. fail('Socket not available') unless $!PIO;
  8. if $bin {
  9. nqp::readfh($!PIO, nqp::decont(buf8.new),
  10. $chars == Inf ?? 1048576 !! $chars.Int);
  11. }
  12. else {
  13. nqp::p6box_s(nqp::readcharsfh($!PIO,
  14. $chars == Inf ?? 1048576 !! $chars.Int));
  15. }
  16. }
  17. method read(IO::Socket:D: Int(Cool) $bufsize) {
  18. fail('Socket not available') unless $!PIO;
  19. my int $toread = $bufsize;
  20. my $res := nqp::readfh($!PIO,buf8.new,$toread);
  21. while nqp::elems($res) < $toread {
  22. my $buf := nqp::readfh($!PIO,buf8.new,$toread - nqp::elems($res));
  23. nqp::elems($buf)
  24. ?? $res.append($buf)
  25. !! return $res
  26. }
  27. $res
  28. }
  29. method poll(Int $bitmask, $seconds) {
  30. die 'Socket.poll is NYI'
  31. }
  32. method print (Str(Cool) $string --> True) {
  33. fail("Not connected") unless $!PIO;
  34. nqp::printfh($!PIO, nqp::unbox_s($string));
  35. }
  36. method put (Str(Cool) $string --> True) {
  37. fail("Not connected") unless $!PIO;
  38. nqp::printfh($!PIO, nqp::unbox_s($string));
  39. nqp::printfh($!PIO, nqp::unbox_s("\n")); # XXX should be $!nl-out
  40. }
  41. method write(Blob:D $buf --> True) {
  42. fail('Socket not available') unless $!PIO;
  43. nqp::writefh($!PIO, nqp::decont($buf));
  44. }
  45. method close (--> True) {
  46. fail("Not connected!") unless $!PIO;
  47. nqp::closefh($!PIO);
  48. $!PIO := nqp::null;
  49. }
  50. method native-descriptor(::?CLASS:D:) {
  51. nqp::filenofh($!PIO)
  52. }
  53. }