xref: /plugin/pureldap/vendor/freedsx/socket/src/FreeDSx/Socket/Queue/Asn1MessageQueue.php (revision 0b3fd2d31e4d1997548a8fbc53fa771027c4a47f)
1*0b3fd2d3SAndreas Gohr<?php
2*0b3fd2d3SAndreas Gohr/**
3*0b3fd2d3SAndreas Gohr * This file is part of the FreeDSx Socket package.
4*0b3fd2d3SAndreas Gohr *
5*0b3fd2d3SAndreas Gohr * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
6*0b3fd2d3SAndreas Gohr *
7*0b3fd2d3SAndreas Gohr * For the full copyright and license information, please view the LICENSE
8*0b3fd2d3SAndreas Gohr * file that was distributed with this source code.
9*0b3fd2d3SAndreas Gohr */
10*0b3fd2d3SAndreas Gohr
11*0b3fd2d3SAndreas Gohrnamespace FreeDSx\Socket\Queue;
12*0b3fd2d3SAndreas Gohr
13*0b3fd2d3SAndreas Gohruse FreeDSx\Asn1\Encoder\EncoderInterface;
14*0b3fd2d3SAndreas Gohruse FreeDSx\Asn1\Exception\PartialPduException;
15*0b3fd2d3SAndreas Gohruse FreeDSx\Socket\Exception\PartialMessageException;
16*0b3fd2d3SAndreas Gohruse FreeDSx\Socket\PduInterface;
17*0b3fd2d3SAndreas Gohruse FreeDSx\Socket\Socket;
18*0b3fd2d3SAndreas Gohr
19*0b3fd2d3SAndreas Gohr/**
20*0b3fd2d3SAndreas Gohr * Represents an ASN.1 based message queue using the FreeDSx ASN.1 library.
21*0b3fd2d3SAndreas Gohr *
22*0b3fd2d3SAndreas Gohr * @author Chad Sikorra <Chad.Sikorra@gmail.com>
23*0b3fd2d3SAndreas Gohr */
24*0b3fd2d3SAndreas Gohrclass Asn1MessageQueue extends MessageQueue
25*0b3fd2d3SAndreas Gohr{
26*0b3fd2d3SAndreas Gohr    /**
27*0b3fd2d3SAndreas Gohr     * @var null|string
28*0b3fd2d3SAndreas Gohr     */
29*0b3fd2d3SAndreas Gohr    protected $pduClass;
30*0b3fd2d3SAndreas Gohr
31*0b3fd2d3SAndreas Gohr    /**
32*0b3fd2d3SAndreas Gohr     * @var EncoderInterface
33*0b3fd2d3SAndreas Gohr     */
34*0b3fd2d3SAndreas Gohr    protected $encoder;
35*0b3fd2d3SAndreas Gohr
36*0b3fd2d3SAndreas Gohr    /**
37*0b3fd2d3SAndreas Gohr     * @param Socket $socket
38*0b3fd2d3SAndreas Gohr     * @param EncoderInterface $encoder
39*0b3fd2d3SAndreas Gohr     * @param null|string $pduClass
40*0b3fd2d3SAndreas Gohr     */
41*0b3fd2d3SAndreas Gohr    public function __construct(Socket $socket, EncoderInterface $encoder, ?string $pduClass = null)
42*0b3fd2d3SAndreas Gohr    {
43*0b3fd2d3SAndreas Gohr        if ($pduClass !== null && !\is_subclass_of($pduClass, PduInterface::class)) {
44*0b3fd2d3SAndreas Gohr            throw new \RuntimeException(sprintf(
45*0b3fd2d3SAndreas Gohr                'The class "%s" must implement "%s", but it does not.',
46*0b3fd2d3SAndreas Gohr                $pduClass,
47*0b3fd2d3SAndreas Gohr                PduInterface::class
48*0b3fd2d3SAndreas Gohr            ));
49*0b3fd2d3SAndreas Gohr        }
50*0b3fd2d3SAndreas Gohr        $this->encoder = $encoder;
51*0b3fd2d3SAndreas Gohr        $this->pduClass = $pduClass;
52*0b3fd2d3SAndreas Gohr        parent::__construct($socket);
53*0b3fd2d3SAndreas Gohr    }
54*0b3fd2d3SAndreas Gohr
55*0b3fd2d3SAndreas Gohr    /**
56*0b3fd2d3SAndreas Gohr     * {@inheritdoc}
57*0b3fd2d3SAndreas Gohr     */
58*0b3fd2d3SAndreas Gohr    protected function decode($bytes): Message
59*0b3fd2d3SAndreas Gohr    {
60*0b3fd2d3SAndreas Gohr        try {
61*0b3fd2d3SAndreas Gohr            $asn1 = $this->encoder->decode($bytes);
62*0b3fd2d3SAndreas Gohr            $message = new Message($asn1, $this->encoder->getLastPosition());
63*0b3fd2d3SAndreas Gohr        } catch (PartialPduException $exception) {
64*0b3fd2d3SAndreas Gohr            throw new PartialMessageException($exception->getMessage(), $exception->getCode(), $exception);
65*0b3fd2d3SAndreas Gohr        }
66*0b3fd2d3SAndreas Gohr
67*0b3fd2d3SAndreas Gohr        return $message;
68*0b3fd2d3SAndreas Gohr    }
69*0b3fd2d3SAndreas Gohr
70*0b3fd2d3SAndreas Gohr    /**
71*0b3fd2d3SAndreas Gohr     * {@inheritdoc}
72*0b3fd2d3SAndreas Gohr     */
73*0b3fd2d3SAndreas Gohr    protected function constructMessage(Message $message, ?int $id = null)
74*0b3fd2d3SAndreas Gohr    {
75*0b3fd2d3SAndreas Gohr        if ($this->pduClass === null) {
76*0b3fd2d3SAndreas Gohr            throw new \RuntimeException('You must either define a PDU class or override getPdu().');
77*0b3fd2d3SAndreas Gohr        }
78*0b3fd2d3SAndreas Gohr        $callable = [$this->pduClass, 'fromAsn1'];
79*0b3fd2d3SAndreas Gohr        if (!\is_callable($callable)) {
80*0b3fd2d3SAndreas Gohr            throw new \RuntimeException(sprintf('The class %s is not callable.', $this->pduClass));
81*0b3fd2d3SAndreas Gohr        }
82*0b3fd2d3SAndreas Gohr
83*0b3fd2d3SAndreas Gohr        return \call_user_func($callable, $message->getMessage());
84*0b3fd2d3SAndreas Gohr    }
85*0b3fd2d3SAndreas Gohr}
86