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

use strict;

use Carp;
use Digest::MD5;
use Digest::SHA1;

use PGP::Unpackable;
use PGP::Packet::Pubkey;
use PGP::Packet::Subkey;
use PGP::Packet::Userid;
use PGP::Packet::Signature;

BEGIN {
    no strict 'refs';

    foreach my $accessor (qw(ctag bodyref packetref)) {
	*{$accessor} = sub {
	    my ($this) = @_;
	    $this-&gt;{$accessor};
	};
    }
};

sub new {
    my ($classname, $ctag, $bodyref, $packetref) = @_;

    bless {
	"ctag" =&gt; $ctag,
	"bodyref" =&gt; $bodyref,
	"packetref" =&gt; $packetref,
    }, $classname;
}

sub next {
    my ($uring) = @_;

    my ($ctag, $bodyref);

    if ($uring-&gt;remaining == 0) {
	return(undef);
    }

    my $begin = $uring-&gt;offset();

    my $ptag = $uring-&gt;unpackC();

    if (($ptag &amp; 0xc0) == 0x80) {
	# old (2.6.x) format

	$ctag = ($ptag &amp; 0x3c) &gt;&gt; 2;
	my $ltype = ($ptag &amp; 0x03);

	my $plen;

	if ($ltype == 0) {
	    $plen = $uring-&gt;unpackC();
	} elsif ($ltype == 1) {
	    $plen = $uring-&gt;unpack("n");
	} elsif ($ltype == 2) {
	    $plen = $uring-&gt;unpack("N");
	} elsif ($ltype == 3) {
	    $plen = $uring-&gt;remaining();
	}

	$bodyref = \$uring-&gt;unpacka($plen);
    } elsif (($ptag &amp; 0xc0) == 0xc0) {
	# new (5.x) packet format

	$ctag = ($ptag &amp; 0x3f);

	my $plen;

	while(1) {
	    my $lbyte = $uring-&gt;unpackC();

	    if ($lbyte &lt; 192) {
		$plen = $lbyte;
		last;
	    } elsif ($lbyte &lt; 224) {
		my $octet = $uring-&gt;unpackC();
		$plen = (($lbyte - 192) &lt;&lt; 8) + $octet + 192;
		last;
	    } elsif ($lbyte == 255) {
		$plen = $uring-&gt;unpack("N");
		last;
	    } else {
		$plen = (1 &lt;&lt; ($lbyte &amp; 0x1f));
		$$bodyref .= $uring-&gt;unpacka($plen);
	    }
	}

	$$bodyref .= $uring-&gt;unpacka($plen);
    }

    my $end = $uring-&gt;offset();

    my $packetref = \$uring-&gt;substr($begin, $end-$begin);

    if ($ctag == 6) {
	return PGP::Packet::Pubkey-&gt;new($bodyref, $packetref);
    } elsif ($ctag == 14) {
	return PGP::Packet::Subkey-&gt;new($bodyref, $packetref);
    } elsif ($ctag == 13) {
	return PGP::Packet::Userid-&gt;new($bodyref, $packetref);
    } elsif ($ctag == 2) {
	return PGP::Packet::Signature-&gt;new($bodyref, $packetref);
    } else {
	return PGP::Packet-&gt;new($ctag, $bodyref, $packetref);
    }
}

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