1<?php 2/** 3 * This file is part of the FreeDSx ASN1 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\Asn1\Type; 12 13use function array_merge; 14use function usort; 15 16/** 17 * Used between the Set type and Encoder. 18 * 19 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 20 */ 21trait SetTrait 22{ 23 /** 24 * X.680 Sec 8.4. A set is canonical when: 25 * - Universal classes first. 26 * - Application classes second. 27 * - Context specific classes third. 28 * - Private classes last. 29 * - Within each group of classes above, tag numbers should be ordered in ascending order. 30 * 31 * @param AbstractType ...$set 32 * @return AbstractType[] 33 */ 34 protected function canonicalize(AbstractType ...$set): array 35 { 36 $children = [ 37 AbstractType::TAG_CLASS_UNIVERSAL => [], 38 AbstractType::TAG_CLASS_APPLICATION => [], 39 AbstractType::TAG_CLASS_CONTEXT_SPECIFIC => [], 40 AbstractType::TAG_CLASS_PRIVATE => [], 41 ]; 42 43 # Group them by their respective class type. 44 foreach ($set as $child) { 45 $children[$child->getTagClass()][] = $child; 46 } 47 48 # Sort the classes by tag number. 49 foreach ($children as $class => $type) { 50 usort($children[$class], function ($a, $b) { 51 /* @var AbstractType $a 52 * @var AbstractType $b */ 53 return ($a->getTagNumber() < $b->getTagNumber()) ? -1 : 1; 54 }); 55 } 56 57 return array_merge( 58 $children[AbstractType::TAG_CLASS_UNIVERSAL], 59 $children[AbstractType::TAG_CLASS_APPLICATION], 60 $children[AbstractType::TAG_CLASS_CONTEXT_SPECIFIC], 61 $children[AbstractType::TAG_CLASS_PRIVATE] 62 ); 63 } 64} 65