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