PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Reflex/Role/Reading.pm

http://github.com/rcaputo/reflex
Perl | 233 lines | 178 code | 46 blank | 9 comment | 8 complexity | 89d3f8a98a1ed3bbe3989afebf4189a2 MD5 | raw file
  1. package Reflex::Role::Reading;
  2. # vim: ts=2 sw=2 noexpandtab
  3. use Reflex::Role;
  4. use Reflex::Event::Octets;
  5. use Reflex::Event::EOF;
  6. use Reflex::Event::Error;
  7. # The method_read parameter matches Reflex::Role::Readable's default
  8. # callback.
  9. # TODO - Any way we can coordinate this so it's obvious in the code
  10. # but not too verbose?
  11. attribute_parameter att_handle => "handle";
  12. callback_parameter cb_closed => qw( on att_handle closed );
  13. callback_parameter cb_data => qw( on att_handle data );
  14. callback_parameter cb_error => qw( on att_handle error );
  15. method_parameter method_read => qw( read att_handle _ );
  16. role {
  17. my $p = shift;
  18. my $att_handle = $p->att_handle();
  19. my $cb_closed = $p->cb_closed();
  20. my $cb_data = $p->cb_data();
  21. my $cb_error = $p->cb_error();
  22. my $method_read = $p->method_read();
  23. requires $att_handle, $cb_closed, $cb_data, $cb_error;
  24. method $method_read => sub {
  25. my ($self, $event) = @_;
  26. # TODO - Hardcoding this at 65536 isn't very flexible.
  27. my $octet_count = sysread($event->handle(), my $buffer = "", 65536);
  28. # Got data.
  29. if ($octet_count) {
  30. $self->$cb_data(
  31. Reflex::Event::Octets->new( _emitters => [ $self ], octets => $buffer )
  32. );
  33. return $octet_count;
  34. }
  35. # EOF
  36. if (defined $octet_count) {
  37. $self->$cb_closed(Reflex::Event::EOF->new( _emitters => [ $self ]));
  38. return $octet_count;
  39. }
  40. # Quelle erreur!
  41. $self->$cb_error(
  42. Reflex::Event::Error->new(
  43. _emitters => [ $self ],
  44. number => ($! + 0),
  45. string => "$!",
  46. function => "sysread",
  47. )
  48. );
  49. return; # Nothing.
  50. };
  51. };
  52. 1;
  53. __END__
  54. =head1 NAME
  55. Reflex::Role::Reading - add standard sysread() behavior to a class
  56. =head1 SYNOPSIS
  57. TODO - Changed again.
  58. package InputStreaming;
  59. use Reflex::Role;
  60. attribute_parameter handle => "handle";
  61. callback_parameter cb_data => qw( on handle data );
  62. callback_parameter cb_error => qw( on handle error );
  63. callback_parameter cb_closed => qw( on handle closed );
  64. method_parameter method_stop => qw( stop handle _ );
  65. role {
  66. my $p = shift;
  67. my $h = $p->handle();
  68. my $cb_error = $p->cb_error();
  69. my $method_read = "on_${h}_readable";
  70. method-emit_and_stop $cb_error => $p->ev_error();
  71. TODO - Changed.
  72. with 'Reflex::Role::Reading' => {
  73. handle => $h,
  74. cb_data => $p->cb_data(),
  75. cb_error => $cb_error,
  76. cb_closed => $p->cb_closed(),
  77. method_read => $method_read,
  78. };
  79. with 'Reflex::Role::Readable' => {
  80. handle => $h,
  81. cb_ready => $method_read,
  82. method_stop => $p->method_stop(),
  83. };
  84. };
  85. 1;
  86. =head1 DESCRIPTION
  87. Reflex::Role::Readable implements a standard nonblocking sysread()
  88. feature so that it may be added to classes as needed.
  89. There's a lot going on in the SYNOPSIS.
  90. Reflex::Role::Reading is consumed to read from the InputStreaming
  91. handle. The method named in $method_read is generated to read from
  92. the handle. Three callbacks may be triggered depending on the status
  93. returned by sysread(). The "cb_data" callback will be invoked when
  94. data is read from the stream. "cb_error" will be called if there's a
  95. sysread() error. "cb_closed" will be triggered if the stream closes
  96. normally.
  97. Reflex::Role::Readable is consumed to watch the handle for activity.
  98. Its "cb_ready" is invoked whenever the handle has data to be read.
  99. "cb_ready" is Reflex::Role::Reading's "method_read", so data is read
  100. when it's ready.
  101. =head2 Attribute Role Parameters
  102. =head3 handle
  103. C<handle> names an attribute holding the handle to be watched for
  104. readable data.
  105. =head2 Callback Role Parameters
  106. =head3 cb_closed
  107. C<cb_closed> names the $self method that will be called whenever
  108. C<handle> has reached the end of readable data. For sockets, this
  109. means the remote endpoint has closed or shutdown for writing.
  110. C<cb_closed> is by default the catenation of "on_", the C<handle>
  111. name, and "_closed". A handle named "XYZ" will by default trigger
  112. on_XYZ_closed() callbacks. The role defines a default callback that
  113. will emit a "closed" event and call stopped(), which is provided by
  114. Reflex::Role::Collectible.
  115. Currently the second parameter to the C<cb_closed> callback contains
  116. no parameters of note.
  117. When overriding this callback, please be sure to call stopped(), which
  118. is provided by Reflex::Role::Collectible. Calling stopped() is vital
  119. for collectible objects to be released from memory when managed by
  120. Reflex::Collection.
  121. =head3 cb_data
  122. C<cb_data> names the $self method that will be called whenever the
  123. stream for C<handle> has provided new data. By default, it's the
  124. catenation of "on_", the C<handle> name, and "_data". A handle named
  125. "XYZ" will by default trigger on_XYZ_data() callbacks. The role
  126. defines a default callback that will emit a "data" event with
  127. cb_data()'s parameters.
  128. All Reflex parameterized role calblacks are invoked with two
  129. parameters: $self and an anonymous hashref of named values specific to
  130. the callback. C<cb_data> callbacks include a single named value,
  131. C<data>, that contains the raw octets received from the filehandle.
  132. =head3 cb_error
  133. C<cb_error> names the $self method that will be called whenever the
  134. stream produces an error. By default, this method will be the
  135. catenation of "on_", the C<handle> name, and "_error". As in
  136. on_XYZ_error(), if the handle is named "XYZ". The role defines a
  137. default callback that will emit an "error" event with cb_error()'s
  138. parameters, then will call stopped() so that streams managed by
  139. Reflex::Collection will be automatically cleaned up after stopping.
  140. C<cb_error> callbacks receive two parameters, $self and an anonymous
  141. hashref of named values specific to the callback. Reflex error
  142. callbacks include three standard values. C<errfun> contains a
  143. single word description of the function that failed. C<errnum>
  144. contains the numeric value of C<$!> at the time of failure. C<errstr>
  145. holds the stringified version of C<$!>.
  146. Values of C<$!> are passed as parameters since the global variable may
  147. change before the callback can be invoked.
  148. When overriding this callback, please be sure to call stopped(), which
  149. is provided by Reflex::Role::Collectible. Calling stopped() is vital
  150. for collectible objects to be released from memory when managed by
  151. Reflex::Collection.
  152. =head2 Method Role Parameters
  153. =head3 method_read
  154. This role genrates a method to read from the handle in the attribute
  155. named in its "handle" role parameter. The "method_read" role
  156. parameter defines the name for this generated read method. By
  157. default, the read method is named after tha handle's attribute:
  158. "read_${$handle_name}".
  159. =head1 EXAMPLES
  160. TODO - I'm sure there are some.
  161. =head1 SEE ALSO
  162. L<Reflex>
  163. L<Reflex::Role>
  164. L<Reflex::Role::Writing>
  165. L<Reflex::Role::Readable>
  166. L<Reflex::Role::Streaming>
  167. L<Reflex/ACKNOWLEDGEMENTS>
  168. L<Reflex/ASSISTANCE>
  169. L<Reflex/AUTHORS>
  170. L<Reflex/BUGS>
  171. L<Reflex/BUGS>
  172. L<Reflex/CONTRIBUTORS>
  173. L<Reflex/COPYRIGHT>
  174. L<Reflex/LICENSE>
  175. L<Reflex/TODO>
  176. =cut