<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package PGP::Unpackable;

use strict;

use Carp;

sub new {
    my ($class, $strref) = @_;

    bless {
	"strref" =&gt; $strref,
	"offset" =&gt; 0,
    };
}

sub strref {
    my ($self) = @_;

    $self-&gt;{"strref"};
}

sub offset {
    my ($self) = @_;

    $self-&gt;{"offset"};
}

sub remaining {
    my ($self) = @_;

    length(${$self-&gt;{"strref"}}) - $self-&gt;{"offset"};
}

sub unpack {
    my ($self, $unpackstr) = @_;

    my $length = length(pack($unpackstr));

    my ($offset, $strref) = @$self{"offset","strref"};

    if ($offset+$length &gt; length($$strref)) {
	confess("unpack past end of string");
    }

    $self-&gt;{"offset"} += $length;

    unpack($unpackstr, substr($$strref, $offset, $length));
}

sub unpackC {
    my ($self) = @_;
    my ($offset, $strref) = @$self{"offset","strref"};

    if ($offset &gt;= length($$strref)) {
	confess("unpackC past end of string");
    }

    $self-&gt;{"offset"}++;

    ord(substr($$strref,$offset,1));
}

sub unpacka {
    my ($self, $length) = @_;
    my ($offset, $strref) = @$self{"offset","strref"};

    if ($offset+$length &gt; length($$strref)) {
	confess("unpacka past end of string");
    }

    $self-&gt;{"offset"} += $length;

    substr($$strref,$offset,$length);
}

sub skip {
    my ($self, $length) = @_;

    my ($offset, $strref) = @$self{"offset","strref"};

    if ($offset+$length &gt; length($$strref)) {
	confess("skip past end of string");
    }

    $self-&gt;{"offset"} += $length;
}

sub unpack_mpi {
    my ($self) = @_;
    
    my $ret = {};

    $ret-&gt;{"length"} = $self-&gt;unpack("n");
    $ret-&gt;{"bits"} = $self-&gt;unpacka(int(($ret-&gt;{"length"}+7)/8));

    return($ret);
}

sub substr {
    my ($self, $start, $length) = @_;

    substr(${$self-&gt;{"strref"}}, $start, $length);
}

sub replace {
    my ($self, $start, $length, $data) = @_;

    my ($offset, $strref) = @$self{"offset","strref"};

    if (($start &lt; $offset) &amp;&amp; ($offset &lt; ($start+$length))) {
	$self-&gt;{"offset"} = $start;
    } elsif ($offset &gt;= ($start+$length)) {
	$self-&gt;{"offset"} += (length($data)-$length);
    }

    substr($ {$self-&gt;{"strref"}}, $start, $length) = $data;
}

sub remove {
    my ($self, $start, $length) = @_;

    $self-&gt;replace($start, $length, "");
}

1;
</pre></body></html>