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