| 
<?phpnamespace ParagonIE\CipherSweet\Transformation;
 
 use ParagonIE\CipherSweet\Contract\TransformationInterface;
 use ParagonIE\ConstantTime\Base64UrlSafe;
 use ParagonIE\ConstantTime\Binary;
 use ParagonIE\ConstantTime\Hex;
 use ParagonIE_Sodium_Core_Util as SodiumUtil;
 
 /**
 * Class Compound
 * @package ParagonIE\CipherSweet\Transformation
 */
 class Compound implements TransformationInterface
 {
 /**
 * @param mixed $input
 *
 * @return string
 * @throws \Exception
 */
 public function __invoke($input)
 {
 if (!\is_array($input)) {
 throw new \TypeError('Compound Transformation expects an array');
 }
 return (string) \json_encode($this->processArray($input));
 }
 
 /**
 * @param string $string
 * @return string
 */
 public function packString($string)
 {
 $len = Binary::safeStrlen($string);
 $l = Hex::encode(SodiumUtil::store64_le($len));
 return $l . Base64UrlSafe::encode($string);
 }
 
 /**
 * @param array $input
 * @param int $layer
 *
 * @return array|string
 * @throws \Exception
 */
 public function processArray(array $input, $layer = 0)
 {
 if ($layer > 255) {
 throw new \Exception('Too much recursion');
 }
 
 $array = [];
 /**
 * @var string|int $key
 * @var array|string|int|bool|null|float $value
 */
 foreach ($input as $key => $value) {
 if (\is_array($value)) {
 $array[$key] = $this->processArray($value, $layer + 1);
 continue;
 }
 if (\is_float($value)) {
 $array[$key] = $this->packString((string) $value);
 continue;
 }
 if (\is_string($value)) {
 $array[$key] = $this->packString($value);
 continue;
 }
 $array[$key] = $value;
 }
 
 return $array;
 }
 }
 
 |