note
nothingmuch
FWIW, why is TAPx::Parser wrapping around the stream? Why isn't a plumbing loop pulling from the stream and pushing to the parser?
<p>
Then you don't necessarily need nonblocking reads, etc at the IO level - you could push that down to POE or whatever.
<p>
[cpan://XML::Parser] has a [http://search.cpan.org/~msergeant/XML-Parser-2.34/Expat/Expat.pm#XML%3A%3AParser%3A%3AExpatNB_Methods|non blocking interface] which i've always liked due to it's simplicity - you just push strings when you have them, and it generates events. If you put in a partial string then the parser's state machine will simply be in that state waiting for more input.
<p>
This way you can have e.g. TAPx::Parser::Harness::Win32, *Socket, *POE, *Whatever, all reusing the parser without needing to model an iterator API around the various platform specific quirks.
<p>
Update: to clarify that last part - you only truely need non blocking IO if you need to parse multiple streams simultaneously, and as long as the parser has a push api flexible enough to be reentrant (multiple parsers instantiated and with their own state simultaneously) then there's no reason why it can't deliver callbacks in only when it's ready.
<p>
Update 2: [cpan://POE::Filter::XML] is written over [cpan://XML::SAX::Expat::Incremental] which is basically a SAX wrapper for the ExpatNB interface. That might be a nice example.
<p>
<div class="pmsig"><div class="pmsig-205152">
-nuffin<br>zz zZ Z Z #!perl
</div></div>
574085
574085