File-KDBX

 view release on metacpan or  search on metacpan

lib/File/KDBX/IO.pm  view on Meta::CPAN

package File::KDBX::IO;
# ABSTRACT: Base IO class for KDBX-related streams

use warnings;
use strict;

use Devel::GlobalDestruction;
use File::KDBX::Constants qw(:bool);
use File::KDBX::Util qw(:class :empty);
use List::Util qw(sum0);
use Ref::Util qw(is_blessed_ref is_ref is_scalarref);
use Symbol qw(gensym);
use namespace::clean;

extends 'IO::Handle';

our $VERSION = '0.906'; # VERSION

sub _croak { require Carp; goto &Carp::croak }

my %ATTRS = (
    _append_output  => 0,
    _buffer_in      => sub { [] },
    _buffer_out     => sub { [] },
    _error          => undef,
    _fh             => undef,
    _mode           => '',
);
while (my ($attr, $default) = each %ATTRS) {
    no strict 'refs'; ## no critic (ProhibitNoStrict)
    *$attr = sub {
        my $self = shift;
        *$self->{$attr} = shift if @_;
        *$self->{$attr} //= (ref $default eq 'CODE') ? $default->($self) : $default;
    };
}

sub new {
    my $class = shift || (caller)[0];
    my $self = bless gensym, ref($class) || $class;
    tie *$self, $self if 5.005 <= $];
    return $self;
}

sub DESTROY {
    return if in_global_destruction;
    local ($., $@, $!, $^E, $?);
    my $self = shift;
    $self->close;
}

sub close {
    my $self = shift;
    my $fh = $self->_fh // return TRUE;
    $self->_POPPED($fh);
    $self->_fh(undef);
    return $fh->close;
}
sub eof {
    my $self = shift;
    return FALSE if @{$self->_buffer_in};
    my $fh = $self->_fh // return TRUE;
    local *$self->{_error} = *$self->{_error};
    my $char = $self->getc || return TRUE;
    $self->ungetc($char);
}
sub read { shift->sysread(@_) }
sub print {
    my $self = shift;
    for my $buf (@_) {
        return FALSE if !$self->write($buf, length($buf));



( run in 1.137 second using v1.01-cache-2.11-cpan-39bf76dae61 )