Archive-BagIt

 view release on metacpan or  search on metacpan

lib/Archive/BagIt/Role/OpenSSL/Async.pm  view on Meta::CPAN

package Archive::BagIt::Role::OpenSSL::Async;
use strict;
use warnings;
use Moo;
use namespace::autoclean;
use IO::Async::Loop;
use IO::Async::Stream;
use Net::SSLeay ();
our $VERSION = '0.101'; # VERSION
# ABSTRACT: handles asynchronous digest calculation using openssl

sub BEGIN {
    Net::SSLeay::OpenSSL_add_all_digests();
    is => 'rw',

}

has 'name' => (
    required => 1,
    is       => 'ro',
);

has '_io_loop' => (
    is      => 'ro',
    lazy    => 1,
    default => sub {
        IO::Async::Loop->new
    },
);

has '_digest' => (
    is => 'ro',
    lazy => 1,
    builder => '_init_digest',
    init_arg => undef,
);

sub _init_digest {
    my ($self) = @_;
    my $md  = Net::SSLeay::EVP_get_digestbyname($self->name);
    my $digest = Net::SSLeay::EVP_MD_CTX_create();
    Net::SSLeay::EVP_DigestInit($digest, $md);
    return $digest;
}



sub calc_digest {
    my ($self, $fh, $blksize)=@_;
    my $loop = $self->_io_loop();
    my $stream = IO::Async::Stream->new(
        read_handle       => $fh,
        read_len          => 1000 * $blksize,
        on_read           => sub {
            my ($s, $buffref, $eof) = @_;
            if (defined $$buffref) {
                Net::SSLeay::EVP_DigestUpdate($self->_digest, $$buffref);
                $$buffref = undef;
            }
            return 0;
        },
        on_read_eof       => sub {
            $loop->stop();
        },
        close_on_read_eof => 0,



( run in 0.774 second using v1.01-cache-2.11-cpan-5735350b133 )