1. my class Supply { ... }
  2. my class Rakudo::Internals::VMBackedDecoder is repr('Decoder') {
  3. method new(str $encoding, :$translate-nl) {
  4. nqp::decoderconfigure(nqp::create(self), $encoding,
  5. $translate-nl ?? nqp::hash('translate_newlines', 1) !! nqp::null())
  6. }
  7. method add-bytes(Blob:D $bytes --> Nil) {
  8. nqp::decoderaddbytes(self, nqp::decont($bytes));
  9. }
  10. method consume-available-chars(--> Str:D) {
  11. nqp::decodertakeavailablechars(self)
  12. }
  13. method consume-all-chars(--> Str:D) {
  14. nqp::decodertakeallchars(self)
  15. }
  16. method consume-exactly-chars(int $chars --> Str) {
  17. my str $result = nqp::decodertakechars(self, $chars);
  18. nqp::isnull_s($result) ?? Str !! $result
  19. }
  20. method set-line-separators(@seps --> Nil) {
  21. my $sep-strs := nqp::list_s();
  22. nqp::push_s($sep-strs, .Str) for @seps;
  23. nqp::decodersetlineseps(self, $sep-strs);
  24. }
  25. method consume-line-chars(Bool:D :$chomp = False, Bool:D :$eof = False --> Str) {
  26. my str $line = nqp::decodertakeline(self, $chomp, $eof);
  27. nqp::isnull_s($line) ?? Str !! $line
  28. }
  29. method is-empty() {
  30. nqp::decoderempty(self)
  31. }
  32. method bytes-available() {
  33. nqp::decoderbytesavailable(self)
  34. }
  35. method consume-exactly-bytes(int $bytes --> Blob) {
  36. nqp::ifnull(nqp::decodertakebytes(self, buf8.new, $bytes), Blob)
  37. }
  38. }
  39. augment class Rakudo::Internals {
  40. method BYTE_SUPPLY_DECODER(Supply:D $bin-supply, Str:D $enc, :$translate-nl) {
  41. my $norm-enc = self.NORMALIZE_ENCODING($enc);
  42. supply {
  43. my $decoder = Rakudo::Internals::VMBackedDecoder.new($norm-enc, :$translate-nl);
  44. whenever $bin-supply {
  45. $decoder.add-bytes($_);
  46. my $available = $decoder.consume-available-chars();
  47. emit $available if $available ne '';
  48. LAST {
  49. # XXX The `with` is required due to a bug where the
  50. # LAST phaser is not properly scoped if we don't get
  51. # any bytes. Since that means there's nothing to emit
  52. # anyway, we'll not worry about this case for now.
  53. #
  54. # --- or at least that was the the idea before we fixed
  55. # that bug: https://irclog.perlgeek.de/perl6/2016-12-07#i_13698178
  56. # and tried removing the `with` in 58cdfd8, but then the error
  57. # `No such method 'consume-all-chars' for invocant of type 'Any`
  58. # started popping up on Proc::Async tests, so...
  59. # there may be some other bug affecting this?
  60. with $decoder {
  61. my $rest = .consume-all-chars();
  62. emit $rest if $rest ne '';
  63. }
  64. }
  65. }
  66. }
  67. }
  68. }