Author: Adam Pioterek <adam.pioterek@protonmail.ch>
converter update
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/.gitignore b/.gitignore index 6c517bdb02e4158ac3924af5074446f05d2dea04..dfe10db2d6deb883ba88648f45e0651c51cce9a2 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ app/release/ research/localonly database/timetable* +converter/*.gz +converter/metadata.yml diff --git a/converter/vendor/composer/autoload_classmap.php b/converter/vendor/composer/autoload_classmap.php index 7a91153b0d8ea10bc693176a81d8a9eb96883a76..959ab8faf2a06dc4f46903bf7c1d6218f41fb785 100644 --- a/converter/vendor/composer/autoload_classmap.php +++ b/converter/vendor/composer/autoload_classmap.php @@ -3,7 +3,7 @@ // autoload_classmap.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); -$baseDir = dirname($vendorDir); +$baseDir = dirname(dirname(dirname($vendorDir))).'/website/gtfs'; return array( ); diff --git a/converter/vendor/composer/autoload_files.php b/converter/vendor/composer/autoload_files.php index f2c5f7003902c4e3f6fd67da4f975b7a4a8ab8c4..dc1a8d5ffec0f60ac94d61f6dc16ee213098eda9 100644 --- a/converter/vendor/composer/autoload_files.php +++ b/converter/vendor/composer/autoload_files.php @@ -3,7 +3,7 @@ // autoload_files.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); -$baseDir = dirname($vendorDir); +$baseDir = dirname(dirname(dirname($vendorDir))).'/website/gtfs'; return array( '04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php', diff --git a/converter/vendor/composer/autoload_namespaces.php b/converter/vendor/composer/autoload_namespaces.php index b7fc0125dbca56fd7565ad62097672a59473e64e..3a85d7df304b65558395f0423c8d1cd2b2181805 100644 --- a/converter/vendor/composer/autoload_namespaces.php +++ b/converter/vendor/composer/autoload_namespaces.php @@ -3,7 +3,7 @@ // autoload_namespaces.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); -$baseDir = dirname($vendorDir); +$baseDir = dirname(dirname(dirname($vendorDir))).'/website/gtfs'; return array( ); diff --git a/converter/vendor/composer/autoload_psr4.php b/converter/vendor/composer/autoload_psr4.php index b265c64a22f6691ca4a508347bd3dee43b9b19e7..1d39498b9506a86a7eaeeae06099ed6b4dea551a 100644 --- a/converter/vendor/composer/autoload_psr4.php +++ b/converter/vendor/composer/autoload_psr4.php @@ -3,7 +3,8 @@ // autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); -$baseDir = dirname($vendorDir); +$baseDir = dirname(dirname(dirname($vendorDir))).'/website/gtfs'; return array( + 'MessagePack\\' => array($vendorDir . '/rybakit/msgpack/src'), ); diff --git a/converter/vendor/composer/autoload_static.php b/converter/vendor/composer/autoload_static.php index ceacdbcf7cc756781ce678ce5c449a2c02f10974..96502139ec65ab19707937d7379dfa4a53694201 100644 --- a/converter/vendor/composer/autoload_static.php +++ b/converter/vendor/composer/autoload_static.php @@ -10,9 +10,25 @@ public static $files = array ( '04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php', ); + public static $prefixLengthsPsr4 = array ( + 'M' => + array ( + 'MessagePack\\' => 12, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'MessagePack\\' => + array ( + 0 => __DIR__ . '/..' . '/rybakit/msgpack/src', + ), + ); + public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit20779732fc1476ab9a7ca99a0cccc491::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit20779732fc1476ab9a7ca99a0cccc491::$prefixDirsPsr4; }, null, ClassLoader::class); } diff --git a/converter/vendor/composer/installed.json b/converter/vendor/composer/installed.json index 2804f0d8662e715d44557f72183e614a6c8a2e5b..9570f3d38efe96e514e0edd6b15b7ceca856e502 100644 --- a/converter/vendor/composer/installed.json +++ b/converter/vendor/composer/installed.json @@ -50,5 +50,53 @@ "spyc", "yaml", "yml" ] + }, + { + "name": "rybakit/msgpack", + "version": "v0.5.1", + "version_normalized": "0.5.1.0", + "source": { + "type": "git", + "url": "https://github.com/rybakit/msgpack.php.git", + "reference": "837963c0b9481085c5a1c9bf0d15dcf472dce2d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rybakit/msgpack.php/zipball/837963c0b9481085c5a1c9bf0d15dcf472dce2d1", + "reference": "837963c0b9481085c5a1c9bf0d15dcf472dce2d1", + "shasum": "" + }, + "require": { + "php": "^7.1.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.11", + "phpunit/phpunit": "^7.1" + }, + "time": "2018-05-24T12:30:13+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MessagePack\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eugene Leonovich", + "email": "gen.work@gmail.com" + } + ], + "description": "A pure PHP implementation of the MessagePack serialization format.", + "keywords": [ + "messagepack", + "msgpack", + "pure", + "streaming" + ] } ] diff --git a/converter/vendor/rybakit/msgpack/.gitignore b/converter/vendor/rybakit/msgpack/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..66f09add7e697bfa79bcddb4099594c470c27114 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/.gitignore @@ -0,0 +1,4 @@ +/vendor/ +/composer.lock +/coverage.* +/phpunit.xml diff --git a/converter/vendor/rybakit/msgpack/.php_cs.dist b/converter/vendor/rybakit/msgpack/.php_cs.dist new file mode 100644 index 0000000000000000000000000000000000000000..7848e43a13bbe79a5f3929d23686864ab040bf0f --- /dev/null +++ b/converter/vendor/rybakit/msgpack/.php_cs.dist @@ -0,0 +1,90 @@ +<?php + +namespace MessagePack; + +use PhpCsFixer\Config; +use PhpCsFixer\Fixer\FixerInterface; +use PhpCsFixer\Fixer\FunctionNotation\NativeFunctionInvocationFixer; +use PhpCsFixer\Tokenizer\Tokens; + +final class FilterableFixer implements FixerInterface +{ + private $fixer; + private $pathRegex; + + public function __construct(FixerInterface $fixer, string $pathRegex) + { + $this->fixer = $fixer; + $this->pathRegex = $pathRegex; + } + + public function isCandidate(Tokens $tokens) : bool + { + return $this->fixer->isCandidate($tokens); + } + + public function isRisky() : bool + { + return $this->fixer->isRisky(); + } + + public function fix(\SplFileInfo $file, Tokens $tokens) : void + { + $this->fixer->fix($file, $tokens); + } + + public function getName() : string + { + return 'MessagePack/'.$this->fixer->getName(); + } + + public function getPriority() : int + { + return $this->fixer->getPriority(); + } + + public function supports(\SplFileInfo $file) : bool + { + if (1 !== preg_match($this->pathRegex, $file->getRealPath())) { + return false; + } + + return $this->fixer->supports($file); + } +}; + +$header = <<<EOF +This file is part of the rybakit/msgpack.php package. + +(c) Eugene Leonovich <gen.work@gmail.com> + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; + +return Config::create() + ->setUsingCache(false) + ->setRiskyAllowed(true) + ->registerCustomFixers([ + new FilterableFixer(new NativeFunctionInvocationFixer(), '/\bsrc\b/'), + ]) + ->setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => ['operators' => ['=' => null, '=>' => null]], + 'MessagePack/native_function_invocation' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'ordered_imports' => true, + 'phpdoc_order' => true, + 'phpdoc_align' => false, + 'return_type_declaration' => ['space_before' => 'one'], + 'strict_comparison' => true, + 'header_comment' => [ + 'header' => $header, + 'location' => 'after_declare_strict', + 'separate' => 'both', + ], + ]) +; diff --git a/converter/vendor/rybakit/msgpack/.travis.yml b/converter/vendor/rybakit/msgpack/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..1007fe052af5501a6be02be7b8de850f0214018c --- /dev/null +++ b/converter/vendor/rybakit/msgpack/.travis.yml @@ -0,0 +1,31 @@ +sudo: required + +language: bash + +services: + - docker + +env: + - PHP_RUNTIME='php:7.1-cli' CHECK_CS=1 + - PHP_RUNTIME='php:7.2-cli' PHPUNIT_OPTS='--coverage-text --coverage-clover=coverage.clover' + - PHP_RUNTIME='hhvm/hhvm:nightly' + +matrix: + allow_failures: + - env: PHP_RUNTIME='hhvm/hhvm:nightly' + fast_finish: true + +install: + - ./dockerfile.sh | tee /dev/tty | docker build -t msgpack - + +script: + - docker run --rm -v $(pwd):/msgpack -w /msgpack -e PHPUNIT_OPTS="$PHPUNIT_OPTS" msgpack + - if [[ -n "$CHECK_CS" ]]; then + docker run --rm -v $(pwd):/msgpack -w /msgpack msgpack php vendor/bin/php-cs-fixer fix --dry-run --diff --verbose .; + fi + +after_script: + - if [[ -f coverage.clover ]]; then + curl -sSOL https://scrutinizer-ci.com/ocular.phar && + docker run --rm -v $(pwd):/msgpack -w /msgpack msgpack php ocular.phar code-coverage:upload --format=php-clover coverage.clover; + fi diff --git a/converter/vendor/rybakit/msgpack/LICENSE b/converter/vendor/rybakit/msgpack/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..bb5b55667d8a28a1dcea280b1ce828f17ccdc6c8 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2018 Eugene Leonovich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/converter/vendor/rybakit/msgpack/README.md b/converter/vendor/rybakit/msgpack/README.md new file mode 100644 index 0000000000000000000000000000000000000000..43b5c84da7e19b9e2a3ecab1547e0a509e5543d9 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/README.md @@ -0,0 +1,651 @@ +# msgpack.php + +A pure PHP implementation of the [MessagePack](https://msgpack.org/) serialization format. + +[![Build Status](https://travis-ci.org/rybakit/msgpack.php.svg?branch=master)](https://travis-ci.org/rybakit/msgpack.php) +[![Code Coverage](https://scrutinizer-ci.com/g/rybakit/msgpack.php/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/rybakit/msgpack.php/?branch=master) + + +## Features + + * Fully compliant with the latest [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md), + including **bin**, **str** and **ext** types + * Supports [streaming unpacking](#unpacking) + * Supports [unsigned 64-bit integers handling](#unpacking-options) + * Supports [object serialization](#type-transformers) + * [Fully tested](https://travis-ci.org/rybakit/msgpack.php) + * [Relatively fast](#performance) + + +## Table of contents + + * [Installation](#installation) + * [Usage](#usage) + * [Packing](#packing) + * [Packing options](#packing-options) + * [Unpacking](#unpacking) + * [Unpacking options](#unpacking-options) + * [Extensions](#extensions) + * [Type transformers](#type-transformers) + * [Exceptions](#exceptions) + * [Tests](#tests) + * [Performance](#performance) + * [License](#license) + + +## Installation + +The recommended way to install the library is through [Composer](http://getcomposer.org): + +```sh +composer require rybakit/msgpack +``` + +> *The minimum PHP version requirement is 7.1.1. If you need support for older PHP versions (or HHVM), please use +> the [0.3.1](https://github.com/rybakit/msgpack.php/tree/v0.3.1) version of this library.* + + +## Usage + +### Packing + +To pack values you can either use an instance of a `Packer`: + +```php +use MessagePack\Packer; + +$packer = new Packer(); + +... + +$packed = $packer->pack($value); +``` + +or call a static method on the `MessagePack` class: + +```php +use MessagePack\MessagePack; + +... + +$packed = MessagePack::pack($value); +``` + +In the examples above, the method `pack` automatically packs a value depending on its type. But not all PHP types +can be uniquely translated to MessagePack types. For example, the MessagePack format defines `map` and `array` types, +which are represented by a single `array` type in PHP. By default, the packer will pack a PHP array as a MessagePack +array if it has sequential numeric keys, starting from `0` and as a MessagePack map otherwise: + +```php +$mpArr1 = $packer->pack([1, 2]); // MP array [1, 2] +$mpArr2 = $packer->pack([0 => 1, 1 => 2]); // MP array [1, 2] +$mpMap1 = $packer->pack([0 => 1, 2 => 3]); // MP map {0: 1, 2: 3} +$mpMap2 = $packer->pack([1 => 2, 2 => 3]); // MP map {1: 2, 2: 3} +$mpMap3 = $packer->pack(['foo' => 1, 'bar' => 2]); // MP map {foo: 1, bar: 2} +``` + +However, sometimes you need to pack a sequential array as a MessagePack map. +To do this, use the `packMap` method: + +```php +$mpMap = $packer->packMap([1, 2]); // {0: 1, 1: 2} +``` + +Here is a list of type-specific packing methods: + +```php +$packer->packNil(); // MP nil +$packer->packBool(true); // MP bool +$packer->packInt(42); // MP int +$packer->packFloat(M_PI); // MP float +$packer->packStr('foo'); // MP str +$packer->packBin("\x80"); // MP bin +$packer->packArray([1, 2]); // MP array +$packer->packMap([1, 2]); // MP map +$packer->packExt(1, "\xaa"); // MP ext +``` + +> *Check the ["Type transformers"](#type-transformers) section below on how to pack custom types.* + + +#### Packing options + +The `Packer` object supports a number of bitmask-based options for fine-tuning the packing +process (defaults are in bold): + +| Name | Description | +| ------------------ | ------------------------------------------------------------- | +| FORCE_STR | Forces PHP strings to be packed as MessagePack UTF-8 strings | +| FORCE_BIN | Forces PHP strings to be packed as MessagePack binary data | +| **DETECT_STR_BIN** | Detects MessagePack str/bin type automatically | +| | | +| FORCE_ARR | Forces PHP arrays to be packed as MessagePack arrays | +| FORCE_MAP | Forces PHP arrays to be packed as MessagePack maps | +| **DETECT_ARR_MAP** | Detects MessagePack array/map type automatically | +| | | +| FORCE_FLOAT32 | Forces PHP floats to be packed as 32-bits MessagePack floats | +| **FORCE_FLOAT64** | Forces PHP floats to be packed as 64-bits MessagePack floats | + +> *The type detection mode (`DETECT_STR_BIN`/`DETECT_ARR_MAP`) adds some overhead which can be noticed when you pack +> large (16- and 32-bit) arrays or strings. However, if you know the value type in advance (for example, you only +> work with UTF-8 strings or/and associative arrays), you can eliminate this overhead by forcing the packer to use +> the appropriate type, which will save it from running the auto-detection routine. Another option is to explicitly +> specify the value type. The library provides 2 auxiliary classes for this, `Map` and `Binary`. +> Check the ["Type transformers"](#type-transformers) section below for details.* + +Examples: + +```php +use MessagePack\Packer; +use MessagePack\PackOptions; + +// pack PHP strings to MP strings, PHP arrays to MP maps +// and PHP 64-bit floats (doubles) to MP 32-bit floats +$packer = new Packer(PackOptions::FORCE_STR | PackOptions::FORCE_MAP | PackOptions::FORCE_FLOAT32); + +// pack PHP strings to MP binaries and PHP arrays to MP arrays +$packer = new Packer(PackOptions::FORCE_BIN | PackOptions::FORCE_ARR); + +// these will throw MessagePack\Exception\InvalidOptionException +$packer = new Packer(PackOptions::FORCE_STR | PackOptions::FORCE_BIN); +$packer = new Packer(PackOptions::FORCE_FLOAT32 | PackOptions::FORCE_FLOAT64); +``` + + +### Unpacking + +To unpack data you can either use an instance of a `BufferUnpacker`: + +```php +use MessagePack\BufferUnpacker; + +$unpacker = new BufferUnpacker(); + +... + +$unpacker->reset($packed); +$value = $unpacker->unpack(); +``` + +or call a static method on the `MessagePack` class: + +```php +use MessagePack\MessagePack; + +... + +$value = MessagePack::unpack($packed); +``` + +If the packed data is received in chunks (e.g. when reading from a stream), use the `tryUnpack` method, which attempts +to unpack data and returns an array of unpacked messages (if any) instead of throwing an `InsufficientDataException`: + +```php +while ($chunk = ...) { + $unpacker->append($chunk); + if ($messages = $unpacker->tryUnpack()) { + return $messages; + } +} +``` + +Besides the above methods `BufferUnpacker` provides type-specific unpacking methods, namely: + +```php +$unpacker->unpackNil(); // PHP null +$unpacker->unpackBool(); // PHP bool +$unpacker->unpackInt(); // PHP int +$unpacker->unpackFloat(); // PHP float +$unpacker->unpackStr(); // PHP UTF-8 string +$unpacker->unpackBin(); // PHP binary string +$unpacker->unpackArray(); // PHP sequential array +$unpacker->unpackMap(); // PHP associative array +$unpacker->unpackExt(); // PHP Ext class +``` + + +#### Unpacking options + +The `BufferUnpacker` object supports a number of bitmask-based options for fine-tuning the unpacking process (defaults +are in bold): + +| Name | Description | +| ------------------- | ---------------------------------------------------------- | +| BIGINT_AS_EXCEPTION | Throws an exception on integer overflow <sup>[1]</sup> | +| BIGINT_AS_GMP | Converts overflowed integers to GMP objects <sup>[2]</sup> | +| **BIGINT_AS_STR** | Converts overflowed integers to strings | + +> *1. The binary MessagePack format has unsigned 64-bit as its largest integer data type, +> but PHP does not support such integers, which means that an overflow can occur during unpacking.* +> +> *2. Make sure that the [GMP](http://php.net/manual/en/book.gmp.php) extension is enabled.* + + +Examples: + +```php +use MessagePack\BufferUnpacker; +use MessagePack\UnpackOptions; + +$packedUint64 = "\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff"; + +$unpacker = new BufferUnpacker($packedUint64); +var_dump($unpacker->unpack()); // string(20) "18446744073709551615" + +$unpacker = new BufferUnpacker($packedUint64, UnpackOptions::BIGINT_AS_GMP); +var_dump($unpacker->unpack()); // object(GMP) {...} + +$unpacker = new BufferUnpacker($packedUint64, UnpackOptions::BIGINT_AS_EXCEPTION); +$unpacker->unpack(); // throws MessagePack\Exception\IntegerOverflowException +``` + + +### Extensions + +To define application-specific types use the `Ext` class: + +```php +use MessagePack\Ext; +use MessagePack\MessagePack; + +$packed = MessagePack::pack(new Ext(42, "\xaa")); +$ext = MessagePack::unpack($packed); + +var_dump($ext->type === 42); // bool(true) +var_dump($ext->data === "\xaa"); // bool(true) +``` + + +### Type transformers + +In addition to [the basic types](https://github.com/msgpack/msgpack/blob/master/spec.md#type-system), +the library provides functionality to serialize and deserialize arbitrary types. In order to support a custom +type you need to create and register a transformer. The transformer should implement either or both the `Packable` +and/or the `Unpackable` interface. + +The purpose of `Packable` transformers is to serialize a specific value to one of the basic MessagePack types. A good +example of such a transformer is a `MapTransformer` that comes with the library. It serializes `Map` objects (which +are simple wrappers around PHP arrays) to MessagePack maps. This is useful when you want to explicitly mark that +a given PHP array must be packed as a MessagePack map, without triggering the type's auto-detection routine. + +> *More types and type transformers can be found in [src/Type](src/Type) +> and [src/TypeTransformer](src/TypeTransformer) directories.* + +The implementation is trivial: + +```php +namespace MessagePack\TypeTransformer; + +use MessagePack\Packer; +use MessagePack\Type\Map; + +class MapTransformer implements Packable +{ + public function pack(Packer $packer, $value) : ?string + { + return $value instanceof Map + ? $packer->packMap($value->map) + : null; + } +} +``` + +Once `MapTransformer` is registered, you can pack `Map` objects: + +```php +use MessagePack\Packer; +use MessagePack\PackOptions; +use MessagePack\Type\Map; +use MessagePack\TypeTransformer\MapTransformer; + +$packer = new Packer(PackOptions::FORCE_ARR); +$packer->registerTransformer(new MapTransformer()); + +$packed = $packer->pack([ + [1, 2, 3], // MP array + new Map([1, 2, 3]), // MP map +]); +``` + +Transformers implementing the `Unpackable` interface are intended for unpacking +[extension types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types). +For example, the code below shows how to create a transformer that allows you to work transparently with `DateTime` +objects: + +```php +use MessagePack\BufferUnpacker; +use MessagePack\Packer; +use MessagePack\TypeTransformer\Packable; +use MessagePack\TypeTransformer\Unpackable; + +class DateTimeTransformer implements Packable, Unpackable +{ + private $type; + + public function __construct(int $type) + { + $this->type = $type; + } + + public function getType() : int + { + return $this->type; + } + + public function pack(Packer $packer, $value) : ?string + { + if (!$value instanceof \DateTimeInterface) { + return null; + } + + return $packer->packExt($this->type, + $packer->packStr($value->format(\DateTime::RFC3339)) + ); + } + + public function unpack(BufferUnpacker $unpacker, int $extLength) + { + return new \DateTimeImmutable($unpacker->unpackStr()); + } +} +``` + +Register `DateTimeTransformer` for both the packer and the unpacker with a unique extension type (an integer from 0 +to 127) and you are ready to go: + +```php +use App\MessagePack\DateTimeTransformer; +use MessagePack\BufferUnpacker; +use MessagePack\Packer; + +$transformer = new DateTimeTransformer(42); + +$packer = new Packer(); +$packer->registerTransformer($transformer); + +$unpacker = new BufferUnpacker(); +$unpacker->registerTransformer($transformer); + +$packed = $packer->pack(new DateTimeImmutable()); +$date = $unpacker->reset($packed)->unpack(); +``` + +> *More type transformer examples can be found in the [examples](examples) directory.* + + +## Exceptions + +If an error occurs during packing/unpacking, a `PackingFailedException` or `UnpackingFailedException` will be thrown, +respectively. + +In addition, there are two more exceptions that can be thrown during unpacking: + + * `InsufficientDataException` + * `IntegerOverflowException` + +An `InvalidOptionException` will be thrown in case an invalid option (or a combination of mutually exclusive options) +is used. + + +## Tests + +Run tests as follows: + +```sh +vendor/bin/phpunit +``` + +Also, if you already have Docker installed, you can run the tests in a docker container. +First, create a container: + +```sh +./dockerfile.sh | docker build -t msgpack - +``` + +The command above will create a container named `msgpack` with PHP 7.2 runtime. +You may change the default runtime by defining the `PHP_RUNTIME` environment variable: + +```sh +PHP_RUNTIME='php:7.1-cli' ./dockerfile.sh | docker build -t msgpack - +``` + +> *See a list of various runtimes [here](.travis.yml#L8).* + +Then run the unit tests: + +```sh +docker run --rm --name msgpack -v $(pwd):/msgpack -w /msgpack msgpack +``` + + +#### Performance + +To check performance, run: + +```sh +php -n -dpcre.jit=1 -dzend_extension=opcache.so -dopcache.enable_cli=1 tests/bench.php +``` + +This command will output something like: + +``` +Filter: MessagePack\Tests\Perf\Filter\ListFilter +Rounds: 3 +Iterations: 100000 + +============================================= +Test/Target Packer BufferUnpacker +--------------------------------------------- +nil .................. 0.0041 ........ 0.0158 +false ................ 0.0046 ........ 0.0166 +true ................. 0.0042 ........ 0.0158 +7-bit uint #1 ........ 0.0066 ........ 0.0129 +7-bit uint #2 ........ 0.0066 ........ 0.0131 +7-bit uint #3 ........ 0.0067 ........ 0.0134 +5-bit sint #1 ........ 0.0068 ........ 0.0153 +5-bit sint #2 ........ 0.0068 ........ 0.0153 +5-bit sint #3 ........ 0.0067 ........ 0.0152 +8-bit uint #1 ........ 0.0088 ........ 0.0223 +8-bit uint #2 ........ 0.0088 ........ 0.0226 +8-bit uint #3 ........ 0.0090 ........ 0.0224 +16-bit uint #1 ....... 0.0120 ........ 0.0304 +16-bit uint #2 ....... 0.0125 ........ 0.0306 +16-bit uint #3 ....... 0.0122 ........ 0.0301 +32-bit uint #1 ....... 0.0140 ........ 0.0358 +32-bit uint #2 ....... 0.0138 ........ 0.0358 +32-bit uint #3 ....... 0.0141 ........ 0.0365 +64-bit uint #1 ....... 0.0159 ........ 0.0361 +64-bit uint #2 ....... 0.0157 ........ 0.0363 +64-bit uint #3 ....... 0.0157 ........ 0.0362 +8-bit int #1 ......... 0.0089 ........ 0.0251 +8-bit int #2 ......... 0.0090 ........ 0.0259 +8-bit int #3 ......... 0.0094 ........ 0.0255 +16-bit int #1 ........ 0.0121 ........ 0.0304 +16-bit int #2 ........ 0.0121 ........ 0.0306 +16-bit int #3 ........ 0.0121 ........ 0.0305 +32-bit int #1 ........ 0.0141 ........ 0.0364 +32-bit int #2 ........ 0.0146 ........ 0.0377 +32-bit int #3 ........ 0.0145 ........ 0.0369 +64-bit int #1 ........ 0.0142 ........ 0.0359 +64-bit int #2 ........ 0.0143 ........ 0.0360 +64-bit int #3 ........ 0.0147 ........ 0.0360 +64-bit int #4 ........ 0.0142 ........ 0.0358 +64-bit float #1 ...... 0.0148 ........ 0.0363 +64-bit float #2 ...... 0.0152 ........ 0.0351 +64-bit float #3 ...... 0.0147 ........ 0.0353 +fix string #1 ........ 0.0176 ........ 0.0143 +fix string #2 ........ 0.0197 ........ 0.0234 +fix string #3 ........ 0.0197 ........ 0.0250 +fix string #4 ........ 0.0238 ........ 0.0254 +8-bit string #1 ...... 0.0245 ........ 0.0333 +8-bit string #2 ...... 0.0297 ........ 0.0345 +8-bit string #3 ...... 0.0372 ........ 0.0343 +16-bit string #1 ..... 0.0392 ........ 0.0411 +16-bit string #2 ..... 3.2959 ........ 0.3091 +32-bit string ........ 3.2918 ........ 0.3149 +wide char string #1 .. 0.0203 ........ 0.0248 +wide char string #2 .. 0.0262 ........ 0.0323 +8-bit binary #1 ...... 0.0206 ........ 0.0309 +8-bit binary #2 ...... 0.0217 ........ 0.0332 +8-bit binary #3 ...... 0.0219 ........ 0.0335 +16-bit binary ........ 0.0255 ........ 0.0405 +32-bit binary ........ 0.3719 ........ 0.3212 +fix array #1 ......... 0.0070 ........ 0.0147 +fix array #2 ......... 0.0288 ........ 0.0445 +fix array #3 ......... 0.0513 ........ 0.0599 +16-bit array #1 ...... 0.1540 ........ 0.1718 +16-bit array #2 ........... S ............. S +32-bit array .............. S ............. S +complex array ........ 0.2138 ........ 0.2679 +fix map #1 ........... 0.0999 ........ 0.1239 +fix map #2 ........... 0.0429 ........ 0.0507 +fix map #3 ........... 0.0503 ........ 0.0721 +fix map #4 ........... 0.0458 ........ 0.0604 +16-bit map #1 ........ 0.2516 ........ 0.3197 +16-bit map #2 ............. S ............. S +32-bit map ................ S ............. S +complex map .......... 0.2972 ........ 0.3501 +fixext 1 ............. 0.0146 ........ 0.0403 +fixext 2 ............. 0.0148 ........ 0.0422 +fixext 4 ............. 0.0148 ........ 0.0426 +fixext 8 ............. 0.0165 ........ 0.0427 +fixext 16 ............ 0.0156 ........ 0.0422 +8-bit ext ............ 0.0197 ........ 0.0494 +16-bit ext ........... 0.0234 ........ 0.0576 +32-bit ext ........... 0.3674 ........ 0.3327 +============================================= +Total 9.4513 4.5950 +Skipped 4 4 +Failed 0 0 +Ignored 0 0 +``` + +You may change default benchmark settings by defining the following environment variables: + + * `MP_BENCH_TARGETS` (pure_p, pure_ps, pure_pa, pure_psa, pure_bu, pecl_p, pecl_u) + * `MP_BENCH_ITERATIONS`/`MP_BENCH_DURATION` + * `MP_BENCH_ROUNDS` + * `MP_BENCH_TESTS` + +For example: + +```sh +export MP_BENCH_TARGETS=pure_p +export MP_BENCH_ITERATIONS=1000000 +export MP_BENCH_ROUNDS=5 +# a comma separated list of test names +export MP_BENCH_TESTS='complex array, complex map' +# or a group name +# export MP_BENCH_TESTS='-@slow' // @pecl_comp +# or a regexp +# export MP_BENCH_TESTS='/complex (array|map)/' +php -n -dpcre.jit=1 -dzend_extension=opcache.so -dopcache.enable_cli=1 tests/bench.php +``` + +Another example, benchmarking both the library and the [msgpack pecl extension](https://pecl.php.net/package/msgpack): + +```sh +MP_BENCH_TARGETS=pure_ps,pure_bu,pecl_p,pecl_u \ +php -n -dpcre.jit=1 -dextension=msgpack.so -dzend_extension=opcache.so -dopcache.enable_cli=1 tests/bench.php +``` + +Output: + +``` +Filter: MessagePack\Tests\Perf\Filter\ListFilter +Rounds: 3 +Iterations: 100000 + +====================================================================================== +Test/Target Packer (force_str) BufferUnpacker msgpack_pack msgpack_unpack +-------------------------------------------------------------------------------------- +nil ............................. 0.0040 ........ 0.0158 ...... 0.0065 ........ 0.0052 +false ........................... 0.0046 ........ 0.0158 ...... 0.0064 ........ 0.0051 +true ............................ 0.0045 ........ 0.0158 ...... 0.0065 ........ 0.0051 +7-bit uint #1 ................... 0.0066 ........ 0.0130 ...... 0.0065 ........ 0.0054 +7-bit uint #2 ................... 0.0067 ........ 0.0129 ...... 0.0065 ........ 0.0052 +7-bit uint #3 ................... 0.0065 ........ 0.0129 ...... 0.0065 ........ 0.0052 +5-bit sint #1 ................... 0.0067 ........ 0.0153 ...... 0.0065 ........ 0.0054 +5-bit sint #2 ................... 0.0067 ........ 0.0152 ...... 0.0065 ........ 0.0053 +5-bit sint #3 ................... 0.0068 ........ 0.0154 ...... 0.0065 ........ 0.0054 +8-bit uint #1 ................... 0.0087 ........ 0.0223 ...... 0.0066 ........ 0.0057 +8-bit uint #2 ................... 0.0088 ........ 0.0223 ...... 0.0066 ........ 0.0057 +8-bit uint #3 ................... 0.0087 ........ 0.0222 ...... 0.0067 ........ 0.0057 +16-bit uint #1 .................. 0.0120 ........ 0.0295 ...... 0.0068 ........ 0.0057 +16-bit uint #2 .................. 0.0118 ........ 0.0296 ...... 0.0069 ........ 0.0057 +16-bit uint #3 .................. 0.0119 ........ 0.0297 ...... 0.0068 ........ 0.0057 +32-bit uint #1 .................. 0.0138 ........ 0.0358 ...... 0.0067 ........ 0.0056 +32-bit uint #2 .................. 0.0137 ........ 0.0358 ...... 0.0066 ........ 0.0058 +32-bit uint #3 .................. 0.0138 ........ 0.0358 ...... 0.0068 ........ 0.0057 +64-bit uint #1 .................. 0.0140 ........ 0.0362 ...... 0.0067 ........ 0.0056 +64-bit uint #2 .................. 0.0140 ........ 0.0364 ...... 0.0067 ........ 0.0056 +64-bit uint #3 .................. 0.0141 ........ 0.0362 ...... 0.0066 ........ 0.0057 +8-bit int #1 .................... 0.0089 ........ 0.0251 ...... 0.0068 ........ 0.0057 +8-bit int #2 .................... 0.0090 ........ 0.0252 ...... 0.0066 ........ 0.0056 +8-bit int #3 .................... 0.0089 ........ 0.0251 ...... 0.0066 ........ 0.0056 +16-bit int #1 ................... 0.0120 ........ 0.0304 ...... 0.0067 ........ 0.0057 +16-bit int #2 ................... 0.0120 ........ 0.0314 ...... 0.0069 ........ 0.0059 +16-bit int #3 ................... 0.0124 ........ 0.0314 ...... 0.0070 ........ 0.0058 +32-bit int #1 ................... 0.0144 ........ 0.0372 ...... 0.0067 ........ 0.0056 +32-bit int #2 ................... 0.0139 ........ 0.0364 ...... 0.0068 ........ 0.0056 +32-bit int #3 ................... 0.0139 ........ 0.0364 ...... 0.0067 ........ 0.0056 +64-bit int #1 ................... 0.0143 ........ 0.0363 ...... 0.0067 ........ 0.0058 +64-bit int #2 ................... 0.0142 ........ 0.0363 ...... 0.0068 ........ 0.0057 +64-bit int #3 ................... 0.0143 ........ 0.0366 ...... 0.0067 ........ 0.0058 +64-bit int #4 ................... 0.0142 ........ 0.0364 ...... 0.0067 ........ 0.0057 +64-bit float #1 ................. 0.0148 ........ 0.0353 ...... 0.0066 ........ 0.0057 +64-bit float #2 ................. 0.0152 ........ 0.0356 ...... 0.0066 ........ 0.0057 +64-bit float #3 ................. 0.0147 ........ 0.0355 ...... 0.0066 ........ 0.0057 +fix string #1 ................... 0.0082 ........ 0.0143 ...... 0.0069 ........ 0.0057 +fix string #2 ................... 0.0101 ........ 0.0234 ...... 0.0069 ........ 0.0070 +fix string #3 ................... 0.0101 ........ 0.0256 ...... 0.0071 ........ 0.0072 +fix string #4 ................... 0.0102 ........ 0.0255 ...... 0.0068 ........ 0.0067 +8-bit string #1 ................. 0.0122 ........ 0.0335 ...... 0.0068 ........ 0.0068 +8-bit string #2 ................. 0.0127 ........ 0.0337 ...... 0.0069 ........ 0.0069 +8-bit string #3 ................. 0.0127 ........ 0.0337 ...... 0.0102 ........ 0.0069 +16-bit string #1 ................ 0.0161 ........ 0.0403 ...... 0.0103 ........ 0.0074 +16-bit string #2 ................ 0.3583 ........ 0.3081 ...... 0.3529 ........ 0.2745 +32-bit string ................... 0.3609 ........ 0.3168 ...... 0.3511 ........ 0.2749 +wide char string #1 ............. 0.0098 ........ 0.0248 ...... 0.0068 ........ 0.0070 +wide char string #2 ............. 0.0122 ........ 0.0324 ...... 0.0069 ........ 0.0069 +8-bit binary #1 ...................... I ............. I ........... F ............. I +8-bit binary #2 ...................... I ............. I ........... F ............. I +8-bit binary #3 ...................... I ............. I ........... F ............. I +16-bit binary ........................ I ............. I ........... F ............. I +32-bit binary ........................ I ............. I ........... F ............. I +fix array #1 .................... 0.0070 ........ 0.0146 ...... 0.0152 ........ 0.0069 +fix array #2 .................... 0.0292 ........ 0.0444 ...... 0.0175 ........ 0.0165 +fix array #3 .................... 0.0422 ........ 0.0617 ...... 0.0196 ........ 0.0209 +16-bit array #1 ................. 0.1536 ........ 0.1716 ...... 0.0321 ........ 0.0449 +16-bit array #2 ...................... S ............. S ........... S ............. S +32-bit array ......................... S ............. S ........... S ............. S +complex array ........................ I ............. I ........... F ............. F +fix map #1 ........................... I ............. I ........... F ............. I +fix map #2 ...................... 0.0331 ........ 0.0502 ...... 0.0171 ........ 0.0188 +fix map #3 ........................... I ............. I ........... F ............. I +fix map #4 ........................... I ............. I ........... F ............. I +16-bit map #1 ................... 0.2506 ........ 0.3160 ...... 0.0330 ........ 0.0689 +16-bit map #2 ........................ S ............. S ........... S ............. S +32-bit map ........................... S ............. S ........... S ............. S +complex map ..................... 0.2679 ........ 0.3518 ...... 0.0659 ........ 0.0753 +fixext 1 ............................. I ............. I ........... F ............. F +fixext 2 ............................. I ............. I ........... F ............. F +fixext 4 ............................. I ............. I ........... F ............. F +fixext 8 ............................. I ............. I ........... F ............. F +fixext 16 ............................ I ............. I ........... F ............. F +8-bit ext ............................ I ............. I ........... F ............. F +16-bit ext ........................... I ............. I ........... F ............. F +32-bit ext ........................... I ............. I ........... F ............. F +====================================================================================== +Total 2.0227 2.9568 1.2268 1.0765 +Skipped 4 4 4 4 +Failed 0 0 17 9 +Ignored 17 17 0 8 +``` + +> *Note that the msgpack extension (0.5.2+, 2.0) doesn't support **ext**, **bin** and UTF-8 **str** types.* + + +## License + +The library is released under the MIT License. See the bundled [LICENSE](LICENSE) file for details. diff --git a/converter/vendor/rybakit/msgpack/composer.json b/converter/vendor/rybakit/msgpack/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..92968b54dc6c267e4bc15419c1900d3cff189f14 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/composer.json @@ -0,0 +1,36 @@ +{ + "name": "rybakit/msgpack", + "description": "A pure PHP implementation of the MessagePack serialization format.", + "keywords": ["msgpack", "messagepack", "pure", "streaming"], + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Eugene Leonovich", + "email": "gen.work@gmail.com" + } + ], + "require": { + "php": "^7.1.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.11", + "phpunit/phpunit": "^7.1" + }, + "autoload": { + "psr-4": { + "MessagePack\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "MessagePack\\Tests\\": "tests/" + } + }, + "config": { + "preferred-install": { + "*": "dist" + }, + "sort-packages": true + } +} diff --git a/converter/vendor/rybakit/msgpack/dockerfile.sh b/converter/vendor/rybakit/msgpack/dockerfile.sh new file mode 100755 index 0000000000000000000000000000000000000000..13c77138708a5fb2b46a52c415e04692c5bca6a1 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/dockerfile.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +if [[ -z "$PHP_RUNTIME" ]] ; then + PHP_RUNTIME='php:7.2-cli' +fi + +RUN_CMDS='' + +if [[ $PHP_RUNTIME == php* ]]; then + RUN_CMDS="$RUN_CMDS && \\\\\n docker-php-ext-install zip mbstring" + RUN_CMDS="$RUN_CMDS && \\\\\n apt-get install -y libgmp-dev" + RUN_CMDS="$RUN_CMDS && \\\\\n ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h && docker-php-ext-install gmp" +else + RUN_CMDS="$RUN_CMDS && \\\\\n echo 'hhvm.php7.all = 1' >> /etc/hhvm/php.ini" +fi + +if [[ $PHPUNIT_OPTS =~ (^|[[:space:]])--coverage-[[:alpha:]] ]]; then + RUN_CMDS="$RUN_CMDS && \\\\\n git clone https://github.com/xdebug/xdebug.git /usr/src/php/ext/xdebug" + RUN_CMDS="$RUN_CMDS && \\\\\n echo xdebug >> /usr/src/php-available-exts && docker-php-ext-install xdebug" +fi + +echo -e " +FROM $PHP_RUNTIME + +RUN apt-get update && apt-get install -y git curl zlib1g-dev${RUN_CMDS} + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + +ENV PATH=~/.composer/vendor/bin:\$PATH + +CMD if [ ! -f composer.lock ]; then composer install; fi && vendor/bin/phpunit\${PHPUNIT_OPTS:+ }\$PHPUNIT_OPTS +" diff --git a/converter/vendor/rybakit/msgpack/examples/MessagePack/ArrayIteratorTransformer.php b/converter/vendor/rybakit/msgpack/examples/MessagePack/ArrayIteratorTransformer.php new file mode 100644 index 0000000000000000000000000000000000000000..92e6e85a56a1b479a018c2d5f8f59675d6b12afc --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/MessagePack/ArrayIteratorTransformer.php @@ -0,0 +1,60 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App\MessagePack; + +use MessagePack\BufferUnpacker; +use MessagePack\Packer; +use MessagePack\TypeTransformer\Packable; +use MessagePack\TypeTransformer\Unpackable; + +class ArrayIteratorTransformer implements Packable, Unpackable +{ + private $type; + + public function __construct($type) + { + $this->type = $type; + } + + public function getType() : int + { + return $this->type; + } + + public function pack(Packer $packer, $value) : ?string + { + if (!$value instanceof \ArrayIterator) { + return null; + } + + $data = ''; + $size = 0; + foreach ($value as $item) { + $data .= $packer->pack($item); + ++$size; + } + + return $packer->packExt($this->type, + $packer->packArrayHeader($size). + $data + ); + } + + public function unpack(BufferUnpacker $unpacker, int $extLength) + { + $size = $unpacker->unpackArrayHeader(); + + while ($size--) { + yield $unpacker->unpack(); + } + } +} diff --git a/converter/vendor/rybakit/msgpack/examples/MessagePack/DateTimeTransformer.php b/converter/vendor/rybakit/msgpack/examples/MessagePack/DateTimeTransformer.php new file mode 100644 index 0000000000000000000000000000000000000000..ac7e39904a562321b63b3d2ed687467910b353e4 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/MessagePack/DateTimeTransformer.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App\MessagePack; + +use MessagePack\BufferUnpacker; +use MessagePack\Packer; +use MessagePack\TypeTransformer\Packable; +use MessagePack\TypeTransformer\Unpackable; + +class DateTimeTransformer implements Packable, Unpackable +{ + private $type; + + public function __construct(int $type) + { + $this->type = $type; + } + + public function getType() : int + { + return $this->type; + } + + public function pack(Packer $packer, $value) : ?string + { + if (!$value instanceof \DateTimeInterface) { + return null; + } + + return $packer->packExt($this->type, + $packer->packStr($value->format(\DateTime::RFC3339)) + ); + } + + public function unpack(BufferUnpacker $unpacker, int $extLength) + { + return new \DateTimeImmutable($unpacker->unpackStr()); + } +} diff --git a/converter/vendor/rybakit/msgpack/examples/MessagePack/PackedMap.php b/converter/vendor/rybakit/msgpack/examples/MessagePack/PackedMap.php new file mode 100644 index 0000000000000000000000000000000000000000..745c510ce1f057a97d873d487823b2b5d52ae89d --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/MessagePack/PackedMap.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App\MessagePack; + +final class PackedMap +{ + public $map; + public $schema; + + public function __construct(array $map, array $schema) + { + $this->map = $map; + $this->schema = $schema; + } +} diff --git a/converter/vendor/rybakit/msgpack/examples/MessagePack/PackedMapTransformer.php b/converter/vendor/rybakit/msgpack/examples/MessagePack/PackedMapTransformer.php new file mode 100644 index 0000000000000000000000000000000000000000..797e9f30158ccaaed089d3b53f07daf1a597db78 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/MessagePack/PackedMapTransformer.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App\MessagePack; + +use MessagePack\BufferUnpacker; +use MessagePack\Packer; +use MessagePack\TypeTransformer\Packable; +use MessagePack\TypeTransformer\Unpackable; + +class PackedMapTransformer implements Packable, Unpackable +{ + private $type; + + public function __construct($type) + { + $this->type = $type; + } + + public function getType() : int + { + return $this->type; + } + + public function pack(Packer $packer, $value) : ?string + { + if (!$value instanceof PackedMap) { + return null; + } + + $data = ''; + $size = 0; + foreach ($value->map as $item) { + foreach ($value->schema as $key => $type) { + $data .= $packer->{'pack'.$type}($item[$key]); + } + ++$size; + } + + return $packer->packExt($this->type, + $packer->packMap($value->schema). + $packer->packArrayHeader($size). + $data + ); + } + + public function unpack(BufferUnpacker $unpacker, int $extLength) + { + $schema = $unpacker->unpackMap(); + $size = $unpacker->unpackArrayHeader(); + + $items = []; + for ($i = 0; $i < $size; ++$i) { + foreach ($schema as $key => $type) { + $items[$i][$key] = $unpacker->{'unpack'.$type}(); + } + } + + return $items; + } +} diff --git a/converter/vendor/rybakit/msgpack/examples/MessagePack/Uint64.php b/converter/vendor/rybakit/msgpack/examples/MessagePack/Uint64.php new file mode 100644 index 0000000000000000000000000000000000000000..e73500481343b805fbbb54045a9ebd110bc2628a --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/MessagePack/Uint64.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App\MessagePack; + +final class Uint64 +{ + public $value; + + public function __construct(string $value) + { + $this->value = $value; + } + + public function __toString() : string + { + return $this->value; + } +} diff --git a/converter/vendor/rybakit/msgpack/examples/MessagePack/Uint64Transformer.php b/converter/vendor/rybakit/msgpack/examples/MessagePack/Uint64Transformer.php new file mode 100644 index 0000000000000000000000000000000000000000..bc406fa5ef211b34c5ad488acafc96c35eb9ca62 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/MessagePack/Uint64Transformer.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace App\MessagePack; + +use MessagePack\Packer; +use MessagePack\TypeTransformer\Packable; + +class Uint64Transformer implements Packable +{ + public function pack(Packer $packer, $value) : ?string + { + return $value instanceof Uint64 + ? "\xcf".\gmp_export($value->value) + : null; + } +} diff --git a/converter/vendor/rybakit/msgpack/examples/array_iterator.php b/converter/vendor/rybakit/msgpack/examples/array_iterator.php new file mode 100644 index 0000000000000000000000000000000000000000..edc00ef7c8704806b06783eb4802ffbb9b7b8416 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/array_iterator.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use App\MessagePack\ArrayIteratorTransformer; +use MessagePack\BufferUnpacker; +use MessagePack\Packer; + +require __DIR__.'/autoload.php'; + +$transformer = new ArrayIteratorTransformer(1); + +$packer = new Packer(); +$packer->registerTransformer($transformer); +$packed = $packer->pack(new ArrayIterator(range(1, 10000))); + +$unpacker = new BufferUnpacker($packed); +$unpacker->registerTransformer($transformer); + +$sum = 0; +foreach ($unpacker->unpack() as $i) { + $sum += $i; +} + +echo "Sum: $sum\n"; + +/* OUTPUT +Sum: 50005000 +*/ diff --git a/converter/vendor/rybakit/msgpack/examples/autoload.php b/converter/vendor/rybakit/msgpack/examples/autoload.php new file mode 100644 index 0000000000000000000000000000000000000000..500b231f8dcc0ad130d8beb04a758da7d2246373 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/autoload.php @@ -0,0 +1,13 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +$loader = require dirname(__DIR__).'/vendor/autoload.php'; +$loader->addPsr4('App\\', __DIR__); diff --git a/converter/vendor/rybakit/msgpack/examples/binary.php b/converter/vendor/rybakit/msgpack/examples/binary.php new file mode 100644 index 0000000000000000000000000000000000000000..16df362b5ee37bf576d3e8b0d231a1d83ea7af43 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/binary.php @@ -0,0 +1,30 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use MessagePack\Packer; +use MessagePack\PackOptions; +use MessagePack\Type\Binary; +use MessagePack\TypeTransformer\BinaryTransformer; + +require __DIR__.'/autoload.php'; + +// https://stackoverflow.com/questions/40808984/msgpack-between-php-and-javascript + +$packer = new Packer(PackOptions::FORCE_STR); +$packer->registerTransformer(new BinaryTransformer()); + +$packed = $packer->pack(['name' => new Binary('value')]); + +echo '[', implode(', ', unpack('C*', $packed)), "]\n"; + +/* OUTPUT +[129, 164, 110, 97, 109, 101, 196, 5, 118, 97, 108, 117, 101] +*/ diff --git a/converter/vendor/rybakit/msgpack/examples/datetime.php b/converter/vendor/rybakit/msgpack/examples/datetime.php new file mode 100644 index 0000000000000000000000000000000000000000..14ee91b914e9e3113b3e3d7738b85bd740c83649 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/datetime.php @@ -0,0 +1,34 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use App\MessagePack\DateTimeTransformer; +use MessagePack\BufferUnpacker; +use MessagePack\Packer; + +require __DIR__.'/autoload.php'; + +$date = new DateTimeImmutable('2000-01-01'); +$transformer = new DateTimeTransformer(2); + +$packer = new Packer(); +$packer->registerTransformer($transformer); +$packed = $packer->pack($date); + +$unpacker = new BufferUnpacker($packed); +$unpacker->registerTransformer($transformer); + +printf("Raw: %s\n", $date->format('r')); +printf("Unpacked: %s\n", $unpacker->unpack()->format('r')); + +/* OUTPUT +Raw: Sat, 01 Jan 2000 00:00:00 +0000 +Unpacked: Sat, 01 Jan 2000 00:00:00 +0000 +*/ diff --git a/converter/vendor/rybakit/msgpack/examples/map.php b/converter/vendor/rybakit/msgpack/examples/map.php new file mode 100644 index 0000000000000000000000000000000000000000..4d3a2fa8ead77dce639bfd1e31021eacbbb26fb5 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/map.php @@ -0,0 +1,31 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use MessagePack\Packer; +use MessagePack\PackOptions; +use MessagePack\Type\Map; +use MessagePack\TypeTransformer\MapTransformer; + +require __DIR__.'/autoload.php'; + +$packer = new Packer(PackOptions::FORCE_ARR); +$packer->registerTransformer(new MapTransformer()); + +$packedArray = $packer->pack([1, 2, 3]); +$packedMap = $packer->pack(new Map([1, 2, 3])); + +printf("Packed array: %s\n", implode(' ', str_split(bin2hex($packedArray), 2))); +printf("Packed map: %s\n", implode(' ', str_split(bin2hex($packedMap), 2))); + +/* OUTPUT +Packed array: 93 01 02 03 +Packed map: 83 00 01 01 02 02 03 +*/ diff --git a/converter/vendor/rybakit/msgpack/examples/packed_map.php b/converter/vendor/rybakit/msgpack/examples/packed_map.php new file mode 100644 index 0000000000000000000000000000000000000000..c18ecd5510b3a4bc62ef14accc8d525580172070 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/packed_map.php @@ -0,0 +1,60 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use App\MessagePack\PackedMap; +use App\MessagePack\PackedMapTransformer; +use MessagePack\BufferUnpacker; +use MessagePack\Packer; + +require __DIR__.'/autoload.php'; + +$schema = [ + 'id' => 'int', + 'first_name' => 'str', + 'last_name' => 'str', +]; + +$profiles = []; +for ($i = 0; $i < 1000; ++$i) { + $profiles[] = [ + 'id' => $i, + 'first_name' => sprintf('first_name_%03s', $i), + 'last_name' => sprintf('last_name_%03s', $i), + ]; +} + +$transformer = new PackedMapTransformer(3); + +$packer = new Packer(); +$packer->registerTransformer($transformer); + +$unpacker = new BufferUnpacker(); +$unpacker->registerTransformer($transformer); + +$packedMap = $packer->pack($profiles); +$packedPackedMap = $packer->pack(new PackedMap($profiles, $schema)); + +$unpackedMap = $unpacker->reset($packedMap)->unpack(); +$unpackedPackedMap = $unpacker->reset($packedPackedMap)->unpack(); + +if (($unpackedMap !== $profiles) || ($unpackedPackedMap !== $profiles)) { + exit(1); +} + +printf("Map size: %dB\n", strlen($packedMap)); +printf("PackedMap size: %dB\n", strlen($packedPackedMap)); +printf("Space savings: %.2F%%\n", 1 - strlen($packedPackedMap) / strlen($packedMap)); + +/* OUTPUT +Map size: 56619B +PackedMap size: 31660B +Space savings: 0.44% +*/ diff --git a/converter/vendor/rybakit/msgpack/examples/sugar.php b/converter/vendor/rybakit/msgpack/examples/sugar.php new file mode 100644 index 0000000000000000000000000000000000000000..2189df0bd377cd1d70c232558e42d00e8a290338 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/sugar.php @@ -0,0 +1,23 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use MessagePack\MessagePack; + +require __DIR__.'/autoload.php'; + +$packed = MessagePack::pack('foobar'); +$unpacked = MessagePack::unpack($packed); + +echo "$unpacked\n"; + +/* OUTPUT +foobar +*/ diff --git a/converter/vendor/rybakit/msgpack/examples/uint64.php b/converter/vendor/rybakit/msgpack/examples/uint64.php new file mode 100644 index 0000000000000000000000000000000000000000..d88f21d662e898a42698e5b329bc1dfbe16b3ce7 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/examples/uint64.php @@ -0,0 +1,36 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use App\MessagePack\Uint64; +use App\MessagePack\Uint64Transformer; +use MessagePack\BufferUnpacker; +use MessagePack\Packer; + +require __DIR__.'/autoload.php'; + +if (!extension_loaded('gmp')) { + echo "GMP extension is required to run this example.\n"; + exit(1); +} + +$packer = new Packer(); +$packer->registerTransformer(new Uint64Transformer()); + +$uint64 = new Uint64('18446744073709551615'); +$packed = $packer->pack($uint64); + +printf("Packed (%s): %s\n", $uint64, bin2hex($packed)); +printf("Unpacked: %s\n", (new BufferUnpacker($packed))->unpack()); + +/* OUTPUT +Packed (18446744073709551615): cfffffffffffffffff +Unpacked: 18446744073709551615 +*/ diff --git a/converter/vendor/rybakit/msgpack/phpunit.xml.dist b/converter/vendor/rybakit/msgpack/phpunit.xml.dist new file mode 100644 index 0000000000000000000000000000000000000000..409290700d6f65efd9736cb24cd26ca60ad46090 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/phpunit.xml.dist @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + verbose="true" + bootstrap="vendor/autoload.php" +> + <php> + <ini name="date.timezone" value="UTC" /> + <ini name="display_errors" value="On" /> + <ini name="display_startup_errors" value="On" /> + <ini name="error_reporting" value="E_ALL" /> + </php> + + <testsuites> + <testsuite name="unit"> + <directory>tests/Unit</directory> + </testsuite> + <testsuite name="examples"> + <file>tests/ExamplesTest.php</file> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>src</directory> + </whitelist> + </filter> +</phpunit> diff --git a/converter/vendor/rybakit/msgpack/src/BufferUnpacker.php b/converter/vendor/rybakit/msgpack/src/BufferUnpacker.php new file mode 100644 index 0000000000000000000000000000000000000000..69d84f8aa9ac78638663d7578b0f1cac7d9578a1 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/BufferUnpacker.php @@ -0,0 +1,596 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack; + +use MessagePack\Exception\InsufficientDataException; +use MessagePack\Exception\IntegerOverflowException; +use MessagePack\Exception\UnpackingFailedException; +use MessagePack\TypeTransformer\Unpackable; + +class BufferUnpacker +{ + private $buffer; + private $offset = 0; + private $isBigIntAsStr; + private $isBigIntAsGmp; + + /** + * @var Unpackable[]|null + */ + private $transformers; + + /** + * @param string $buffer + * @param UnpackOptions|int|null $options + * + * @throws \MessagePack\Exception\InvalidOptionException + */ + public function __construct(string $buffer = '', $options = null) + { + if (null === $options) { + $options = UnpackOptions::fromDefaults(); + } elseif (!$options instanceof PackOptions) { + $options = UnpackOptions::fromBitmask($options); + } + + $this->isBigIntAsStr = $options->isBigIntAsStrMode(); + $this->isBigIntAsGmp = $options->isBigIntAsGmpMode(); + + $this->buffer = $buffer; + } + + public function registerTransformer(Unpackable $transformer) : self + { + $this->transformers[$transformer->getType()] = $transformer; + + return $this; + } + + public function append(string $data) : self + { + $this->buffer .= $data; + + return $this; + } + + public function reset(string $buffer = '') : self + { + $this->buffer = $buffer; + $this->offset = 0; + + return $this; + } + + public function __clone() + { + $this->buffer = ''; + $this->offset = 0; + } + + public function tryUnpack() : array + { + $data = []; + $offset = $this->offset; + + try { + do { + $data[] = $this->unpack(); + $offset = $this->offset; + } while (isset($this->buffer[$this->offset])); + } catch (InsufficientDataException $e) { + $this->offset = $offset; + } + + if ($this->offset) { + $this->buffer = isset($this->buffer[$this->offset]) ? \substr($this->buffer, $this->offset) : ''; + $this->offset = 0; + } + + return $data; + } + + public function unpack() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + // fixint + if ($c <= 0x7f) { + return $c; + } + // fixstr + if ($c >= 0xa0 && $c <= 0xbf) { + return ($c & 0x1f) ? $this->unpackStrData($c & 0x1f) : ''; + } + // fixarray + if ($c >= 0x90 && $c <= 0x9f) { + return ($c & 0xf) ? $this->unpackArrayData($c & 0xf) : []; + } + // fixmap + if ($c >= 0x80 && $c <= 0x8f) { + return ($c & 0xf) ? $this->unpackMapData($c & 0xf) : []; + } + // negfixint + if ($c >= 0xe0) { + return $c - 0x100; + } + + switch ($c) { + case 0xc0: return null; + case 0xc2: return false; + case 0xc3: return true; + + // bin + case 0xc4: return $this->unpackStrData($this->unpackUint8()); + case 0xc5: return $this->unpackStrData($this->unpackUint16()); + case 0xc6: return $this->unpackStrData($this->unpackUint32()); + + // float + case 0xca: return $this->unpackFloat32(); + case 0xcb: return $this->unpackFloat64(); + + // uint + case 0xcc: return $this->unpackUint8(); + case 0xcd: return $this->unpackUint16(); + case 0xce: return $this->unpackUint32(); + case 0xcf: return $this->unpackUint64(); + + // int + case 0xd0: return $this->unpackInt8(); + case 0xd1: return $this->unpackInt16(); + case 0xd2: return $this->unpackInt32(); + case 0xd3: return $this->unpackInt64(); + + // str + case 0xd9: return $this->unpackStrData($this->unpackUint8()); + case 0xda: return $this->unpackStrData($this->unpackUint16()); + case 0xdb: return $this->unpackStrData($this->unpackUint32()); + + // array + case 0xdc: return $this->unpackArrayData($this->unpackUint16()); + case 0xdd: return $this->unpackArrayData($this->unpackUint32()); + + // map + case 0xde: return $this->unpackMapData($this->unpackUint16()); + case 0xdf: return $this->unpackMapData($this->unpackUint32()); + + // ext + case 0xd4: return $this->unpackExtData(1); + case 0xd5: return $this->unpackExtData(2); + case 0xd6: return $this->unpackExtData(4); + case 0xd7: return $this->unpackExtData(8); + case 0xd8: return $this->unpackExtData(16); + case 0xc7: return $this->unpackExtData($this->unpackUint8()); + case 0xc8: return $this->unpackExtData($this->unpackUint16()); + case 0xc9: return $this->unpackExtData($this->unpackUint32()); + } + + throw UnpackingFailedException::unknownCode($c); + } + + public function unpackNil() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + if ("\xc0" === $this->buffer[$this->offset]) { + ++$this->offset; + + return null; + } + + throw UnpackingFailedException::unexpectedCode(\ord($this->buffer[$this->offset++]), 'nil'); + } + + public function unpackBool() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if (0xc2 === $c) { + return false; + } + if (0xc3 === $c) { + return true; + } + + throw UnpackingFailedException::unexpectedCode($c, 'bool'); + } + + public function unpackInt() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + // fixint + if ($c <= 0x7f) { + return $c; + } + // negfixint + if ($c >= 0xe0) { + return $c - 0x100; + } + + switch ($c) { + // uint + case 0xcc: return $this->unpackUint8(); + case 0xcd: return $this->unpackUint16(); + case 0xce: return $this->unpackUint32(); + case 0xcf: return $this->unpackUint64(); + + // int + case 0xd0: return $this->unpackInt8(); + case 0xd1: return $this->unpackInt16(); + case 0xd2: return $this->unpackInt32(); + case 0xd3: return $this->unpackInt64(); + } + + throw UnpackingFailedException::unexpectedCode($c, 'int'); + } + + public function unpackFloat() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if (0xcb === $c) { + return $this->unpackFloat64(); + } + if (0xca === $c) { + return $this->unpackFloat32(); + } + + throw UnpackingFailedException::unexpectedCode($c, 'float'); + } + + public function unpackStr() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if ($c >= 0xa0 && $c <= 0xbf) { + return ($c & 0x1f) ? $this->unpackStrData($c & 0x1f) : ''; + } + if (0xd9 === $c) { + return $this->unpackStrData($this->unpackUint8()); + } + if (0xda === $c) { + return $this->unpackStrData($this->unpackUint16()); + } + if (0xdb === $c) { + return $this->unpackStrData($this->unpackUint32()); + } + + throw UnpackingFailedException::unexpectedCode($c, 'str'); + } + + public function unpackBin() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if (0xc4 === $c) { + return $this->unpackStrData($this->unpackUint8()); + } + if (0xc5 === $c) { + return $this->unpackStrData($this->unpackUint16()); + } + if (0xc6 === $c) { + return $this->unpackStrData($this->unpackUint32()); + } + + throw UnpackingFailedException::unexpectedCode($c, 'bin'); + } + + public function unpackArray() + { + $size = $this->unpackArrayHeader(); + + $array = []; + while ($size--) { + $array[] = $this->unpack(); + } + + return $array; + } + + public function unpackArrayHeader() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if ($c >= 0x90 && $c <= 0x9f) { + return $c & 0xf; + } + if (0xdc === $c) { + return $this->unpackUint16(); + } + if (0xdd === $c) { + return $this->unpackUint32(); + } + + throw UnpackingFailedException::unexpectedCode($c, 'array header'); + } + + public function unpackMap() + { + $size = $this->unpackMapHeader(); + + $map = []; + while ($size--) { + $map[$this->unpack()] = $this->unpack(); + } + + return $map; + } + + public function unpackMapHeader() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if ($c >= 0x80 && $c <= 0x8f) { + return $c & 0xf; + } + if (0xde === $c) { + return $this->unpackUint16(); + } + if (0xdf === $c) { + return $this->unpackUint32(); + } + + throw UnpackingFailedException::unexpectedCode($c, 'map header'); + } + + public function unpackExt() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $c = \ord($this->buffer[$this->offset]); + ++$this->offset; + + switch ($c) { + case 0xd4: return $this->unpackExtData(1); + case 0xd5: return $this->unpackExtData(2); + case 0xd6: return $this->unpackExtData(4); + case 0xd7: return $this->unpackExtData(8); + case 0xd8: return $this->unpackExtData(16); + case 0xc7: return $this->unpackExtData($this->unpackUint8()); + case 0xc8: return $this->unpackExtData($this->unpackUint16()); + case 0xc9: return $this->unpackExtData($this->unpackUint32()); + } + + throw UnpackingFailedException::unexpectedCode($c, 'ext header'); + } + + private function unpackUint8() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + return \ord($this->buffer[$this->offset++]); + } + + private function unpackUint16() + { + if (!isset($this->buffer[$this->offset + 1])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 2); + } + + $hi = \ord($this->buffer[$this->offset]); + $lo = \ord($this->buffer[++$this->offset]); + ++$this->offset; + + return $hi << 8 | $lo; + } + + private function unpackUint32() + { + if (!isset($this->buffer[$this->offset + 3])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); + } + + $num = \unpack('N', $this->buffer, $this->offset)[1]; + $this->offset += 4; + + return $num; + } + + private function unpackUint64() + { + if (!isset($this->buffer[$this->offset + 7])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); + } + + $num = \unpack('J', $this->buffer, $this->offset)[1]; + $this->offset += 8; + + return $num < 0 ? $this->handleIntOverflow($num) : $num; + } + + private function unpackInt8() + { + if (!isset($this->buffer[$this->offset])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 1); + } + + $num = \ord($this->buffer[$this->offset]); + ++$this->offset; + + return $num > 0x7f ? $num - 0x100 : $num; + } + + private function unpackInt16() + { + if (!isset($this->buffer[$this->offset + 1])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 2); + } + + $hi = \ord($this->buffer[$this->offset]); + $lo = \ord($this->buffer[++$this->offset]); + ++$this->offset; + + return $hi > 0x7f ? $hi << 8 | $lo - 0x10000 : $hi << 8 | $lo; + } + + private function unpackInt32() + { + if (!isset($this->buffer[$this->offset + 3])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); + } + + $num = \unpack('N', $this->buffer, $this->offset)[1]; + $this->offset += 4; + + return $num > 0x7fffffff ? $num - 0x100000000 : $num; + } + + private function unpackInt64() + { + if (!isset($this->buffer[$this->offset + 7])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); + } + + $num = \unpack('J', $this->buffer, $this->offset)[1]; + $this->offset += 8; + + return $num; + } + + private function unpackFloat32() + { + if (!isset($this->buffer[$this->offset + 3])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 4); + } + + $num = \unpack('G', $this->buffer, $this->offset)[1]; + $this->offset += 4; + + return $num; + } + + private function unpackFloat64() + { + if (!isset($this->buffer[$this->offset + 7])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, 8); + } + + $num = \unpack('E', $this->buffer, $this->offset)[1]; + $this->offset += 8; + + return $num; + } + + private function unpackStrData($length) + { + if (!isset($this->buffer[$this->offset + $length - 1])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, $length); + } + + $str = \substr($this->buffer, $this->offset, $length); + $this->offset += $length; + + return $str; + } + + private function unpackArrayData($size) + { + $array = []; + while ($size--) { + $array[] = $this->unpack(); + } + + return $array; + } + + private function unpackMapData($size) + { + $map = []; + while ($size--) { + $map[$this->unpack()] = $this->unpack(); + } + + return $map; + } + + private function unpackExtData($length) + { + if (!isset($this->buffer[$this->offset + $length - 1])) { + throw InsufficientDataException::unexpectedLength($this->buffer, $this->offset, $length); + } + + // int8 + $type = \ord($this->buffer[$this->offset]); + ++$this->offset; + + if ($type > 0x7f) { + $type -= 0x100; + } + + if (isset($this->transformers[$type])) { + return $this->transformers[$type]->unpack($this, $length); + } + + $data = \substr($this->buffer, $this->offset, $length); + $this->offset += $length; + + return new Ext($type, $data); + } + + private function handleIntOverflow($value) + { + if ($this->isBigIntAsStr) { + return \sprintf('%u', $value); + } + if ($this->isBigIntAsGmp) { + return \gmp_init(\sprintf('%u', $value)); + } + + throw new IntegerOverflowException($value); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Exception/InsufficientDataException.php b/converter/vendor/rybakit/msgpack/src/Exception/InsufficientDataException.php new file mode 100644 index 0000000000000000000000000000000000000000..5ebc61aa29c9152eefbadcff84f612f02e08a77c --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Exception/InsufficientDataException.php @@ -0,0 +1,23 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Exception; + +class InsufficientDataException extends UnpackingFailedException +{ + public static function unexpectedLength(string $buffer, int $offset, int $expectedLength) : self + { + $actualLength = \strlen($buffer) - $offset; + $message = "Not enough data to unpack: expected $expectedLength, got $actualLength."; + + return new self($message); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Exception/IntegerOverflowException.php b/converter/vendor/rybakit/msgpack/src/Exception/IntegerOverflowException.php new file mode 100644 index 0000000000000000000000000000000000000000..e0b5f1e20ac66fc99209a3cf12f07aa69148dce5 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Exception/IntegerOverflowException.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Exception; + +class IntegerOverflowException extends UnpackingFailedException +{ + private $value; + + public function __construct(int $value) + { + parent::__construct(\sprintf('The value is too big: %u.', $value)); + + $this->value = $value; + } + + public function getValue() : int + { + return $this->value; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Exception/InvalidOptionException.php b/converter/vendor/rybakit/msgpack/src/Exception/InvalidOptionException.php new file mode 100644 index 0000000000000000000000000000000000000000..b9986925565a4a404b28f85aa904af37e83cbde5 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Exception/InvalidOptionException.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Exception; + +class InvalidOptionException extends \InvalidArgumentException +{ + public static function outOfRange(string $invalidOption, array $validOptions) : self + { + $use = \count($validOptions) > 2 + ? \sprintf('one of %2$s or %1$s', \array_pop($validOptions), \implode(', ', $validOptions)) + : \implode(' or ', $validOptions); + + return new self("Invalid option $invalidOption, use $use."); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Exception/PackingFailedException.php b/converter/vendor/rybakit/msgpack/src/Exception/PackingFailedException.php new file mode 100644 index 0000000000000000000000000000000000000000..e7df078877bfbb7219766784b9bf259a3e843022 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Exception/PackingFailedException.php @@ -0,0 +1,38 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Exception; + +class PackingFailedException extends \RuntimeException +{ + private $value; + + public function __construct($value, string $message = '', \Throwable $previous = null) + { + parent::__construct($message, 0, $previous); + + $this->value = $value; + } + + public function getValue() + { + return $this->value; + } + + public static function unsupportedType($value) : self + { + $message = \sprintf('Unsupported type: %s.', + \is_object($value) ? \get_class($value) : \gettype($value) + ); + + return new self($value, $message); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Exception/UnpackingFailedException.php b/converter/vendor/rybakit/msgpack/src/Exception/UnpackingFailedException.php new file mode 100644 index 0000000000000000000000000000000000000000..10ad83d86998cd90758ba75ce896b1c8d77cef1e --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Exception/UnpackingFailedException.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Exception; + +class UnpackingFailedException extends \RuntimeException +{ + public static function unknownCode(int $code) : self + { + return new self(\sprintf('Unknown code: 0x%x.', $code)); + } + + public static function unexpectedCode(int $code, string $type) : self + { + return new self(\sprintf('Unexpected %s code: 0x%x.', $type, $code)); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Ext.php b/converter/vendor/rybakit/msgpack/src/Ext.php new file mode 100644 index 0000000000000000000000000000000000000000..ff5bd0798c3fbc8a101a9eb384ae03c99c4ddb79 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Ext.php @@ -0,0 +1,24 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack; + +final class Ext +{ + public $type; + public $data; + + public function __construct(int $type, string $data) + { + $this->type = $type; + $this->data = $data; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/MessagePack.php b/converter/vendor/rybakit/msgpack/src/MessagePack.php new file mode 100644 index 0000000000000000000000000000000000000000..bd0f5411ccd3eee4fd6633e2d3a0bbf4adfce08a --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/MessagePack.php @@ -0,0 +1,50 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack; + +final class MessagePack +{ + /** + * @codeCoverageIgnore + */ + private function __construct() + { + } + + /** + * @param mixed $value + * @param PackOptions|int|null $options + * + * @throws \MessagePack\Exception\InvalidOptionException + * @throws \MessagePack\Exception\PackingFailedException + * + * @return string + */ + public static function pack($value, $options = null) : string + { + return (new Packer($options))->pack($value); + } + + /** + * @param string $data + * @param UnpackOptions|int|null $options + * + * @throws \MessagePack\Exception\InvalidOptionException + * @throws \MessagePack\Exception\UnpackingFailedException + * + * @return mixed + */ + public static function unpack(string $data, $options = null) + { + return (new BufferUnpacker($data, $options))->unpack(); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/PackOptions.php b/converter/vendor/rybakit/msgpack/src/PackOptions.php new file mode 100644 index 0000000000000000000000000000000000000000..1724f6b3d50859ab731e73ae2662defb0052cbe5 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/PackOptions.php @@ -0,0 +1,129 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack; + +use MessagePack\Exception\InvalidOptionException; + +final class PackOptions +{ + public const FORCE_STR = 0b00000001; + public const FORCE_BIN = 0b00000010; + public const DETECT_STR_BIN = 0b00000100; + public const FORCE_ARR = 0b00001000; + public const FORCE_MAP = 0b00010000; + public const DETECT_ARR_MAP = 0b00100000; + public const FORCE_FLOAT32 = 0b01000000; + public const FORCE_FLOAT64 = 0b10000000; + + private $strBinMode; + private $arrMapMode; + private $floatMode; + + private function __construct() + { + } + + public static function fromDefaults() : self + { + $self = new self(); + $self->strBinMode = self::DETECT_STR_BIN; + $self->arrMapMode = self::DETECT_ARR_MAP; + $self->floatMode = self::FORCE_FLOAT64; + + return $self; + } + + public static function fromBitmask(int $bitmask) : self + { + $self = new self(); + + $self->strBinMode = self::getSingleOption('str/bin', $bitmask, + self::FORCE_STR | + self::FORCE_BIN | + self::DETECT_STR_BIN + ) ?: self::DETECT_STR_BIN; + + $self->arrMapMode = self::getSingleOption('arr/map', $bitmask, + self::FORCE_ARR | + self::FORCE_MAP | + self::DETECT_ARR_MAP + ) ?: self::DETECT_ARR_MAP; + + $self->floatMode = self::getSingleOption('float', $bitmask, + self::FORCE_FLOAT32 | + self::FORCE_FLOAT64 + ) ?: self::FORCE_FLOAT64; + + return $self; + } + + public function isDetectStrBinMode() : bool + { + return self::DETECT_STR_BIN === $this->strBinMode; + } + + public function isForceStrMode() : bool + { + return self::FORCE_STR === $this->strBinMode; + } + + public function isForceBinMode() : bool + { + return self::FORCE_BIN === $this->strBinMode; + } + + public function isDetectArrMapMode() : bool + { + return self::DETECT_ARR_MAP === $this->arrMapMode; + } + + public function isForceArrMode() : bool + { + return self::FORCE_ARR === $this->arrMapMode; + } + + public function isForceMapMode() : bool + { + return self::FORCE_MAP === $this->arrMapMode; + } + + public function isForceFloat32Mode() : bool + { + return self::FORCE_FLOAT32 === $this->floatMode; + } + + private static function getSingleOption(string $name, int $bitmask, int $validBitmask) : int + { + $option = $bitmask & $validBitmask; + if ($option === ($option & -$option)) { + return $option; + } + + static $map = [ + self::FORCE_STR => 'FORCE_STR', + self::FORCE_BIN => 'FORCE_BIN', + self::DETECT_STR_BIN => 'DETECT_STR_BIN', + self::FORCE_ARR => 'FORCE_ARR', + self::FORCE_MAP => 'FORCE_MAP', + self::DETECT_ARR_MAP => 'DETECT_ARR_MAP', + self::FORCE_FLOAT32 => 'FORCE_FLOAT32', + self::FORCE_FLOAT64 => 'FORCE_FLOAT64', + ]; + + $validOptions = []; + for ($i = $validBitmask & -$validBitmask; $i <= $validBitmask; $i <<= 1) { + $validOptions[] = __CLASS__.'::'.$map[$i]; + } + + throw InvalidOptionException::outOfRange($name, $validOptions); + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Packer.php b/converter/vendor/rybakit/msgpack/src/Packer.php new file mode 100644 index 0000000000000000000000000000000000000000..7df52b78b07a406ad1c266c589ea93506c4db8e6 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Packer.php @@ -0,0 +1,293 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack; + +use MessagePack\Exception\InvalidOptionException; +use MessagePack\Exception\PackingFailedException; +use MessagePack\TypeTransformer\Packable; + +class Packer +{ + private const UTF8_REGEX = '/\A(?: + [\x00-\x7F]++ # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*+\z/x'; + + private $isDetectStrBin; + private $isForceStr; + private $isDetectArrMap; + private $isForceArr; + private $isForceFloat32; + + /** + * @var Packable[]|null + */ + private $transformers; + + /** + * @param PackOptions|int|null $options + * + * @throws InvalidOptionException + */ + public function __construct($options = null) + { + if (null === $options) { + $options = PackOptions::fromDefaults(); + } elseif (!$options instanceof PackOptions) { + $options = PackOptions::fromBitmask($options); + } + + $this->isDetectStrBin = $options->isDetectStrBinMode(); + $this->isForceStr = $options->isForceStrMode(); + $this->isDetectArrMap = $options->isDetectArrMapMode(); + $this->isForceArr = $options->isForceArrMode(); + $this->isForceFloat32 = $options->isForceFloat32Mode(); + } + + public function registerTransformer(Packable $transformer) : self + { + $this->transformers[] = $transformer; + + return $this; + } + + public function pack($value) + { + if (\is_int($value)) { + return $this->packInt($value); + } + if (\is_string($value)) { + if ($this->isForceStr) { + return $this->packStr($value); + } + if ($this->isDetectStrBin) { + return \preg_match(self::UTF8_REGEX, $value) + ? $this->packStr($value) + : $this->packBin($value); + } + + return $this->packBin($value); + } + if (\is_array($value)) { + if ($this->isDetectArrMap) { + if (!isset($value[0]) && !\array_key_exists(0, $value)) { + return empty($value) ? "\x90" : $this->packMap($value); + } + + return \array_values($value) === $value + ? $this->packArray($value) + : $this->packMap($value); + } + + return $this->isForceArr ? $this->packArray($value) : $this->packMap($value); + } + if (null === $value) { + return "\xc0"; + } + if (\is_bool($value)) { + return $value ? "\xc3" : "\xc2"; + } + if (\is_float($value)) { + return $this->packFloat($value); + } + if ($value instanceof Ext) { + return $this->packExt($value->type, $value->data); + } + if ($this->transformers) { + foreach ($this->transformers as $transformer) { + if (null !== $packed = $transformer->pack($this, $value)) { + return $packed; + } + } + } + + throw PackingFailedException::unsupportedType($value); + } + + public function packNil() + { + return "\xc0"; + } + + public function packBool($bool) + { + return $bool ? "\xc3" : "\xc2"; + } + + public function packInt($int) + { + if ($int >= 0) { + if ($int <= 0x7f) { + return \chr($int); + } + if ($int <= 0xff) { + return "\xcc".\chr($int); + } + if ($int <= 0xffff) { + return "\xcd".\chr($int >> 8).\chr($int); + } + if ($int <= 0xffffffff) { + return \pack('CN', 0xce, $int); + } + + return \pack('CJ', 0xcf, $int); + } + + if ($int >= -0x20) { + return \chr(0xe0 | $int); + } + if ($int >= -0x80) { + return "\xd0".\chr($int); + } + if ($int >= -0x8000) { + return "\xd1".\chr($int >> 8).\chr($int); + } + if ($int >= -0x80000000) { + return \pack('CN', 0xd2, $int); + } + + return \pack('CJ', 0xd3, $int); + } + + public function packFloat($float) + { + return $this->isForceFloat32 + ? "\xca".\pack('G', $float) + : "\xcb".\pack('E', $float); + } + + public function packStr($str) + { + $length = \strlen($str); + + if ($length < 32) { + return \chr(0xa0 | $length).$str; + } + if ($length <= 0xff) { + return "\xd9".\chr($length).$str; + } + if ($length <= 0xffff) { + return "\xda".\chr($length >> 8).\chr($length).$str; + } + + return \pack('CN', 0xdb, $length).$str; + } + + public function packBin($str) + { + $length = \strlen($str); + + if ($length <= 0xff) { + return "\xc4".\chr($length).$str; + } + if ($length <= 0xffff) { + return "\xc5".\chr($length >> 8).\chr($length).$str; + } + + return \pack('CN', 0xc6, $length).$str; + } + + public function packArray($array) + { + $data = $this->packArrayHeader(\count($array)); + + foreach ($array as $val) { + $data .= $this->pack($val); + } + + return $data; + } + + public function packArrayHeader($size) + { + if ($size <= 0xf) { + return \chr(0x90 | $size); + } + if ($size <= 0xffff) { + return "\xdc".\chr($size >> 8).\chr($size); + } + + return \pack('CN', 0xdd, $size); + } + + public function packMap($map) + { + $data = $this->packMapHeader(\count($map)); + + if ($this->isForceStr) { + foreach ($map as $key => $val) { + $data .= \is_string($key) ? $this->packStr($key) : $this->packInt($key); + $data .= $this->pack($val); + } + + return $data; + } + + if ($this->isDetectStrBin) { + foreach ($map as $key => $val) { + $data .= \is_string($key) + ? (\preg_match(self::UTF8_REGEX, $key) ? $this->packStr($key) : $this->packBin($key)) + : $this->packInt($key); + $data .= $this->pack($val); + } + + return $data; + } + + foreach ($map as $key => $val) { + $data .= \is_string($key) ? $this->packBin($key) : $this->packInt($key); + $data .= $this->pack($val); + } + + return $data; + } + + public function packMapHeader($size) + { + if ($size <= 0xf) { + return \chr(0x80 | $size); + } + if ($size <= 0xffff) { + return "\xde".\chr($size >> 8).\chr($size); + } + + return \pack('CN', 0xdf, $size); + } + + public function packExt($type, $data) + { + $length = \strlen($data); + + switch ($length) { + case 1: return "\xd4".\chr($type).$data; + case 2: return "\xd5".\chr($type).$data; + case 4: return "\xd6".\chr($type).$data; + case 8: return "\xd7".\chr($type).$data; + case 16: return "\xd8".\chr($type).$data; + } + + if ($length <= 0xff) { + return "\xc7".\chr($length).\chr($type).$data; + } + if ($length <= 0xffff) { + return \pack('CnC', 0xc8, $length, $type).$data; + } + + return \pack('CNC', 0xc9, $length, $type).$data; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Type/Binary.php b/converter/vendor/rybakit/msgpack/src/Type/Binary.php new file mode 100644 index 0000000000000000000000000000000000000000..5ea8f92f9db9747c66bf04870ee6c15a0b9e7113 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Type/Binary.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Type; + +final class Binary +{ + public $data; + + public function __construct(string $data) + { + $this->data = $data; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/Type/Map.php b/converter/vendor/rybakit/msgpack/src/Type/Map.php new file mode 100644 index 0000000000000000000000000000000000000000..48c08995c26441f9fba9becdd1bb1418c68c0172 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/Type/Map.php @@ -0,0 +1,22 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Type; + +final class Map +{ + public $map; + + public function __construct(array $map) + { + $this->map = $map; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/TypeTransformer/BinaryTransformer.php b/converter/vendor/rybakit/msgpack/src/TypeTransformer/BinaryTransformer.php new file mode 100644 index 0000000000000000000000000000000000000000..3acb8cbe6e21d00e4113092bdb76131fc0167b68 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/TypeTransformer/BinaryTransformer.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\TypeTransformer; + +use MessagePack\Packer; +use MessagePack\Type\Binary; + +class BinaryTransformer implements Packable +{ + public function pack(Packer $packer, $value) : ?string + { + return $value instanceof Binary + ? $packer->packBin($value->data) + : null; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/TypeTransformer/MapTransformer.php b/converter/vendor/rybakit/msgpack/src/TypeTransformer/MapTransformer.php new file mode 100644 index 0000000000000000000000000000000000000000..c3473bf731ad23cd21b870aaa01c906875bb1ac8 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/TypeTransformer/MapTransformer.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\TypeTransformer; + +use MessagePack\Packer; +use MessagePack\Type\Map; + +class MapTransformer implements Packable +{ + public function pack(Packer $packer, $value) : ?string + { + return $value instanceof Map + ? $packer->packMap($value->map) + : null; + } +} diff --git a/converter/vendor/rybakit/msgpack/src/TypeTransformer/Packable.php b/converter/vendor/rybakit/msgpack/src/TypeTransformer/Packable.php new file mode 100644 index 0000000000000000000000000000000000000000..730fc435486a4191e86155330de3dadf90d4a553 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/TypeTransformer/Packable.php @@ -0,0 +1,19 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\TypeTransformer; + +use MessagePack\Packer; + +interface Packable +{ + public function pack(Packer $packer, $value) : ?string; +} diff --git a/converter/vendor/rybakit/msgpack/src/TypeTransformer/Unpackable.php b/converter/vendor/rybakit/msgpack/src/TypeTransformer/Unpackable.php new file mode 100644 index 0000000000000000000000000000000000000000..2f16e14c34af4e26aaee72f64fb87a83c7f43a4a --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/TypeTransformer/Unpackable.php @@ -0,0 +1,21 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\TypeTransformer; + +use MessagePack\BufferUnpacker; + +interface Unpackable +{ + public function getType() : int; + + public function unpack(BufferUnpacker $unpacker, int $extLength); +} diff --git a/converter/vendor/rybakit/msgpack/src/UnpackOptions.php b/converter/vendor/rybakit/msgpack/src/UnpackOptions.php new file mode 100644 index 0000000000000000000000000000000000000000..f59b6e193d3baf05a9a76f9e5c871f63d22cfe20 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/src/UnpackOptions.php @@ -0,0 +1,84 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack; + +use MessagePack\Exception\InvalidOptionException; + +final class UnpackOptions +{ + public const BIGINT_AS_STR = 0b001; + public const BIGINT_AS_GMP = 0b010; + public const BIGINT_AS_EXCEPTION = 0b100; + + private $bigIntMode; + + private function __construct() + { + } + + public static function fromDefaults() : self + { + $self = new self(); + $self->bigIntMode = self::BIGINT_AS_STR; + + return $self; + } + + public static function fromBitmask(int $bitmask) : self + { + $self = new self(); + + $self->bigIntMode = self::getSingleOption('bigint', $bitmask, + self::BIGINT_AS_STR | + self::BIGINT_AS_GMP | + self::BIGINT_AS_EXCEPTION + ) ?: self::BIGINT_AS_STR; + + return $self; + } + + public function isBigIntAsStrMode() : bool + { + return self::BIGINT_AS_STR === $this->bigIntMode; + } + + public function isBigIntAsGmpMode() : bool + { + return self::BIGINT_AS_GMP === $this->bigIntMode; + } + + public function isBigIntAsExceptionMode() : bool + { + return self::BIGINT_AS_EXCEPTION === $this->bigIntMode; + } + + private static function getSingleOption(string $name, int $bitmask, int $validBitmask) : int + { + $option = $bitmask & $validBitmask; + if ($option === ($option & -$option)) { + return $option; + } + + static $map = [ + self::BIGINT_AS_STR => 'BIGINT_AS_STR', + self::BIGINT_AS_GMP => 'BIGINT_AS_GMP', + self::BIGINT_AS_EXCEPTION => 'BIGINT_AS_EXCEPTION', + ]; + + $validOptions = []; + for ($i = $validBitmask & -$validBitmask; $i <= $validBitmask; $i <<= 1) { + $validOptions[] = __CLASS__.'::'.$map[$i]; + } + + throw InvalidOptionException::outOfRange($name, $validOptions); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/DataProvider.php b/converter/vendor/rybakit/msgpack/tests/DataProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..04e0abf8f7a0476e0b579d051ca0a77925abb037 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/DataProvider.php @@ -0,0 +1,269 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/* + * Most of the test data in this file are borrowed from + * https://github.com/vsergeev/u-msgpack-python/blob/master/test_umsgpack.py + */ + +namespace MessagePack\Tests; + +use MessagePack\Ext; + +class DataProvider +{ + public static function provideData() : array + { + return array_merge( + self::provideNilData(), + self::provideBoolData(), + self::provideIntData(), + self::provideFloatData(), + self::provideStrData(), + self::provideBinData(), + self::provideArrayData(), + self::provideMapData(), + self::provideExtData() + ); + } + + public static function provideUnpackData() : array + { + return array_merge( + self::provideNilData(), + self::provideBoolData(), + self::provideIntUnpackData(), + self::provideFloatUnpackData(), + self::provideStrData(), + self::provideBinData(), + self::provideArrayData(), + self::provideMapUnpackData(), + self::provideExtData() + ); + } + + public static function provideNilData() : array + { + return [ + 'nil' => [null, "\xc0"], + ]; + } + + public static function provideBoolData() : array + { + return [ + 'false' => [false, "\xc2"], + 'true' => [true, "\xc3"], + ]; + } + + public static function provideIntData() : array + { + return [ + '7-bit uint #1' => [0, "\x00"], + '7-bit uint #2' => [16, "\x10"], + '7-bit uint #3' => [127, "\x7f"], + + '5-bit sint #1' => [-1, "\xff"], + '5-bit sint #2' => [-16, "\xf0"], + '5-bit sint #3' => [-32, "\xe0"], + + '8-bit uint #1' => [128, "\xcc\x80"], + '8-bit uint #2' => [240, "\xcc\xf0"], + '8-bit uint #3' => [255, "\xcc\xff"], + + '16-bit uint #1' => [256, "\xcd\x01\x00"], + '16-bit uint #2' => [8192, "\xcd\x20\x00"], + '16-bit uint #3' => [65535, "\xcd\xff\xff"], + + '32-bit uint #1' => [65536, "\xce\x00\x01\x00\x00"], + '32-bit uint #2' => [2097152, "\xce\x00\x20\x00\x00"], + '32-bit uint #3' => [4294967295, "\xce\xff\xff\xff\xff"], + + '64-bit uint #1' => [4294967296, "\xcf"."\x00\x00\x00\x01"."\x00\x00\x00\x00"], + '64-bit uint #2' => [281474976710656, "\xcf"."\x00\x01\x00\x00"."\x00\x00\x00\x00"], + '64-bit uint #3' => [9223372036854775807, "\xcf"."\x7f\xff\xff\xff"."\xff\xff\xff\xff"], + + '8-bit int #1' => [-33, "\xd0\xdf"], + '8-bit int #2' => [-100, "\xd0\x9c"], + '8-bit int #3' => [-128, "\xd0\x80"], + + '16-bit int #1' => [-129, "\xd1\xff\x7f"], + '16-bit int #2' => [-2000, "\xd1\xf8\x30"], + '16-bit int #3' => [-32768, "\xd1\x80\x00"], + + '32-bit int #1' => [-32769, "\xd2\xff\xff\x7f\xff"], + '32-bit int #2' => [-1000000000, "\xd2\xc4\x65\x36\x00"], + '32-bit int #3' => [-2147483648, "\xd2\x80\x00\x00\x00"], + + '64-bit int #1' => [-2147483649, "\xd3"."\xff\xff\xff\xff"."\x7f\xff\xff\xff"], + '64-bit int #2' => [-4294967296, "\xd3"."\xff\xff\xff\xff"."\x00\x00\x00\x00"], + '64-bit int #3' => [-281474976710656, "\xd3"."\xff\xff\x00\x00"."\x00\x00\x00\x00"], + // https://bugs.php.net/bug.php?id=53934 + '64-bit int #4' => [(int) '-9223372036854775808', "\xd3"."\x80\x00\x00\x00"."\x00\x00\x00\x00"], + ]; + } + + public static function provideIntUnpackData() : array + { + return array_merge(self::provideIntData(), [ + '64-bit uint #4' => [0, "\xcf"."\x00\x00\x00\x00"."\x00\x00\x00\x00"], + + '8-bit int #4' => [127, "\xd0\x7f"], + + '16-bit int #4' => [32767, "\xd1\x7f\xff"], + + '32-bit int #4' => [2147483647, "\xd2\x7f\xff\xff\xff"], + + '64-bit int #5' => [4294967296, "\xd3"."\x00\x00\x00\x01"."\x00\x00\x00\x00"], + '64-bit int #6' => [281474976710656, "\xd3"."\x00\x01\x00\x00"."\x00\x00\x00\x00"], + '64-bin int #7' => [9223372036854775807, "\xd3"."\x7f\xff\xff\xff"."\xff\xff\xff\xff"], + ]); + } + + public static function provideFloatData() : array + { + return [ + '64-bit float #1' => [0.0, "\xcb"."\x00\x00\x00\x00"."\x00\x00\x00\x00"], + '64-bit float #2' => [2.5, "\xcb"."\x40\x04\x00\x00"."\x00\x00\x00\x00"], + '64-bit float #3' => [10 ** 35, "\xcb"."\x47\x33\x42\x61"."\x72\xc7\x4d\x82"], + ]; + } + + public static function provideFloatUnpackData() : array + { + return array_merge(self::provideFloatData(), [ + '32-bit float #1' => [0.0, "\xca"."\x00\x00\x00\x00"], + '32-bit float #2' => [2.5, "\xca"."\x40\x20\x00\x00"], + ]); + } + + public static function provideStrData() : array + { + return [ + 'fix string #1' => ['', "\xa0"], + 'fix string #2' => ['a', "\xa1\x61"], + 'fix string #3' => ['abc', "\xa3\x61\x62\x63"], + 'fix string #4' => [str_repeat('a', 31), "\xbf".str_repeat("\x61", 31)], + + '8-bit string #1' => [str_repeat('b', 32), "\xd9\x20".str_repeat('b', 32)], + '8-bit string #2' => [str_repeat('c', 100), "\xd9\x64".str_repeat('c', 100)], + '8-bit string #3' => [str_repeat('d', 255), "\xd9\xff".str_repeat('d', 255)], + '16-bit string #1' => [str_repeat('b', 256), "\xda\x01\x00".str_repeat('b', 256)], + '16-bit string #2' => [str_repeat('c', 65535), "\xda\xff\xff".str_repeat('c', 65535)], + '32-bit string' => [str_repeat('b', 65536), "\xdb\x00\x01\x00\x00".str_repeat('b', 65536)], + + 'wide char string #1' => ['Allagbé', "\xa8Allagb\xc3\xa9"], + 'wide char string #2' => ['По оживлённым берегам', "\xd9\x28\xd0\x9f\xd0\xbe\x20\xd0\xbe\xd0\xb6\xd0\xb8\xd0\xb2\xd0\xbb\xd1\x91\xd0\xbd\xd0\xbd\xd1\x8b\xd0\xbc\x20\xd0\xb1\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb3\xd0\xb0\xd0\xbc"], + ]; + } + + public static function provideBinData() : array + { + return [ + '8-bit binary #1' => ["\x80", "\xc4\x01"."\x80"], + '8-bit binary #2' => [str_repeat("\x80", 32), "\xc4\x20".str_repeat("\x80", 32)], + '8-bit binary #3' => [str_repeat("\x80", 255), "\xc4\xff".str_repeat("\x80", 255)], + '16-bit binary' => [str_repeat("\x80", 256), "\xc5\x01\x00".str_repeat("\x80", 256)], + '32-bit binary' => [str_repeat("\x80", 65536), "\xc6\x00\x01\x00\x00".str_repeat("\x80", 65536)], + ]; + } + + public static function provideArrayData() : array + { + return [ + 'fix array #1' => [[], "\x90"], + 'fix array #2' => [[null, null], "\x92\xc0\xc0"], + 'fix array #3' => [[5, 'abc', true], "\x93\x05\xa3\x61\x62\x63\xc3"], + '16-bit array #1' => [array_fill(0, 16, 0x05), "\xdc\x00\x10".str_repeat("\x05", 16)], + '16-bit array #2' => [array_fill(0, 65535, 0x05), "\xdc\xff\xff".str_repeat("\x05", 65535)], + '32-bit array' => [array_fill(0, 65536, 0x05), "\xdd\x00\x01\x00\x00".str_repeat("\x05", 65536)], + 'complex array' => [[true, 0x01, new Ext(3, 'foo'), 0xff, [1 => false, 2 => 'abc'], "\x80", [1, 2, 3], 'abc'], "\x98\xc3\x01\xc7\x03\x03\x66\x6f\x6f\xcc\xff\x82\x01\xc2\x02\xa3\x61\x62\x63\xc4\x01\x80\x93\x01\x02\x03\xa3\x61\x62\x63"], + ]; + } + + public static function provideMapData() : array + { + return [ + 'fix map #1' => [[1 => true, 2 => 'abc', 3 => "\x80", 4 => null], "\x84\x01\xc3\x02\xa3\x61\x62\x63\x03\xc4\x01\x80\x04\xc0"], + 'fix map #2' => [['abc' => 5], "\x81\xa3\x61\x62\x63\x05"], + 'fix map #3' => [["\x80" => 0xffff], "\x81\xc4\x01\x80\xcd\xff\xff"], + 'fix map #4' => [[-1 => -1, 1 => 1], "\x82\xff\xff\x01\x01"], + '16-bit map #1' => [array_fill(1, 16, 0x05), "\xde\x00\x10".array_reduce(range(1, 16), function ($r, $i) { return $r .= pack('C', $i)."\x05"; })], + '16-bit map #2' => [array_fill(1, 65535, 0x05), "\xde\xff\xff".array_reduce(range(1, 127), function ($r, $i) { return $r .= pack('C', $i)."\x05"; }).array_reduce(range(128, 255), function ($r, $i) { return $r .= "\xcc".pack('C', $i)."\x05"; }).array_reduce(range(256, 65535), function ($r, $i) { return $r .= "\xcd".pack('n', $i)."\x05"; })], + '32-bit map' => [array_fill(1, 65536, 0x05), "\xdf\x00\x01\x00\x00".array_reduce(range(1, 127), function ($r, $i) { return $r .= pack('C', $i)."\x05"; }).array_reduce(range(128, 255), function ($r, $i) { return $r .= "\xcc".pack('C', $i)."\x05"; }).array_reduce(range(256, 65535), function ($r, $i) { return $r .= "\xcd".pack('n', $i)."\x05"; })."\xce".pack('N', 65536)."\x05"], + 'complex map' => [[1 => [[1 => 2, 3 => 4], [1 => null]], 2 => 1, 3 => [false, 'def'], 4 => [0x100000000 => 'a', 0xffffffff => 'b']], "\x84\x01\x92\x82\x01\x02\x03\x04\x81\x01\xc0\x02\x01\x03\x92\xc2\xa3\x64\x65\x66\x04\x82\xcf\x00\x00\x00\x01\x00\x00\x00\x00\xa1\x61\xce\xff\xff\xff\xff\xa1\x62"], + ]; + } + + public static function provideMapUnpackData() : array + { + return array_merge(self::provideMapData(), [ + 'fix map #5' => [[], "\x80"], + 'fix map #6' => [[0 => null], "\x81\xc2\xc0"], + 'fix map #7' => [[1 => null], "\x81\xc3\xc0"], + ]); + } + + public static function provideExtData() : array + { + return [ + 'fixext 1' => [new Ext(5, "\x80"), "\xd4\x05"."\x80"], + 'fixext 2' => [new Ext(5, str_repeat("\x80", 2)), "\xd5\x05".str_repeat("\x80", 2)], + 'fixext 4' => [new Ext(5, str_repeat("\x80", 4)), "\xd6\x05".str_repeat("\x80", 4)], + 'fixext 8' => [new Ext(5, str_repeat("\x80", 8)), "\xd7\x05".str_repeat("\x80", 8)], + 'fixext 16' => [new Ext(5, str_repeat("\x80", 16)), "\xd8\x05".str_repeat("\x80", 16)], + '8-bit ext' => [new Ext(5, str_repeat("\x80", 255)), "\xc7\xff\x05".str_repeat("\x80", 255)], + '16-bit ext' => [new Ext(5, str_repeat("\x80", 256)), "\xc8\x01\x00\x05".str_repeat("\x80", 256)], + '32-bit ext' => [new Ext(5, str_repeat("\x80", 65536)), "\xc9\x00\x01\x00\x00\x05".str_repeat("\x80", 65536)], + ]; + } + + public static function getSlowTestNames() : array + { + return [ + '16-bit array #2', + '32-bit array', + '16-bit map #2', + '32-bit map', + ]; + } + + public static function getPeclIncompatibleTestNames() : array + { + return [ + '8-bit binary #1', + '8-bit binary #2', + '8-bit binary #3', + '16-bit binary', + '32-bit binary', + '16-bit array #2', + '32-bit array', + 'complex array', + '16-bit map #2', + '32-bit map', + 'fix map #1', + 'fix map #3', + 'fix map #4', + 'fix map #5', + 'fix map #6', + 'fix map #7', + 'fixext 1', + 'fixext 2', + 'fixext 4', + 'fixext 8', + 'fixext 16', + '8-bit ext', + '16-bit ext', + '32-bit ext', + ]; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/ExamplesTest.php b/converter/vendor/rybakit/msgpack/tests/ExamplesTest.php new file mode 100644 index 0000000000000000000000000000000000000000..58a80531a69f3a089f9ec355290df7f061c09e2b --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/ExamplesTest.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests; + +use PHPUnit\Framework\TestCase; + +final class ExamplesTest extends TestCase +{ + /** + * @dataProvider provideExampleData + */ + public function testExample(string $filename) : void + { + exec("php $filename", $output, $exitCode); + + self::assertSame(0, $exitCode); + + if ($output) { + self::assertOutput($filename, implode("\n", $output)); + } + } + + public function provideExampleData() : iterable + { + $dir = dirname(__DIR__).'/examples'; + foreach (glob("$dir/*.php") as $filename) { + if (strpos($filename, 'autoload.php')) { + continue; + } + yield [$filename]; + } + } + + private static function assertOutput(string $filename, string $output) : void + { + $content = file_get_contents($filename); + + if (preg_match('~\/\*\s*?OUTPUT\b(.+?)\*\/~s', $content, $matches)) { + self::assertSame(trim($matches[1]), $output); + } + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/AverageableBenchmark.php b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/AverageableBenchmark.php new file mode 100644 index 0000000000000000000000000000000000000000..c7c9890e10eedd97a13fb40a49de3d80a8ebce8a --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/AverageableBenchmark.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Benchmark; + +use MessagePack\Tests\Perf\Target\Target; +use MessagePack\Tests\Perf\Test; + +class AverageableBenchmark implements Benchmark +{ + private $benchmark; + private $rounds; + + public function __construct(Benchmark $benchmark, int $rounds = 3) + { + $this->benchmark = $benchmark; + $this->rounds = $rounds; + } + + public function benchmark(Target $target, Test $test) + { + $sum = 0; + + for ($i = $this->rounds; $i; --$i) { + $sum += $this->benchmark->benchmark($target, $test); + } + + return $sum / $this->rounds; + } + + public function getInfo() : array + { + return ['Rounds' => $this->rounds] + $this->benchmark->getInfo(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/Benchmark.php b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/Benchmark.php new file mode 100644 index 0000000000000000000000000000000000000000..b5387007e2ed50d8d642e59d0047d306afe78420 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/Benchmark.php @@ -0,0 +1,25 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Benchmark; + +use MessagePack\Tests\Perf\Target\Target; +use MessagePack\Tests\Perf\Test; + +interface Benchmark +{ + /** + * @return int|float + */ + public function benchmark(Target $target, Test $test); + + public function getInfo() : array; +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/DurationBenchmark.php b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/DurationBenchmark.php new file mode 100644 index 0000000000000000000000000000000000000000..56fd3d93b874fd4a054fdbb6782f24e0c7cf0040 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/DurationBenchmark.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Benchmark; + +use MessagePack\Tests\Perf\Target\Target; +use MessagePack\Tests\Perf\Test; + +class DurationBenchmark implements Benchmark +{ + private $duration; + + public function __construct($duration) + { + $this->duration = $duration; + } + + /** + * {@inheritdoc} + */ + public function benchmark(Target $target, Test $test) + { + $target->sanitize($test); + + $iterations = $this->measurePerform($target, $test); + $overheadTime = $this->measureOverhead($target, $test, $iterations); + + $extraIterations = round($overheadTime * $iterations / $this->duration); + + return $iterations + $extraIterations; + } + + public function getInfo() : array + { + return ['Duration' => $this->duration]; + } + + private function measurePerform(Target $target, Test $test) : int + { + $iterations = 0; + $time = microtime(true) + $this->duration; + + while (microtime(true) <= $time) { + $target->perform($test); + ++$iterations; + } + + return $iterations; + } + + private function measureOverhead(Target $target, Test $test, $iterations) : float + { + $time = microtime(true); + + for ($i = $iterations; $i; --$i) { + $target->calibrate($test); + } + + return microtime(true) - $time; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/FilterableBenchmark.php b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/FilterableBenchmark.php new file mode 100644 index 0000000000000000000000000000000000000000..df3d26ba1670abd701306813780808582f0cfe81 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/FilterableBenchmark.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Benchmark; + +use MessagePack\Tests\Perf\Filter\Filter; +use MessagePack\Tests\Perf\Target\Target; +use MessagePack\Tests\Perf\Test; +use MessagePack\Tests\Perf\TestSkippedException; + +class FilterableBenchmark implements Benchmark +{ + private $benchmark; + private $filter; + + public function __construct(Benchmark $benchmark, Filter $filter) + { + $this->benchmark = $benchmark; + $this->filter = $filter; + } + + public function benchmark(Target $target, Test $test) + { + if (!$this->filter->isAccepted($test)) { + throw new TestSkippedException($test); + } + + return $this->benchmark->benchmark($target, $test); + } + + public function getInfo() : array + { + return ['Filter' => get_class($this->filter)] + $this->benchmark->getInfo(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/IterationBenchmark.php b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/IterationBenchmark.php new file mode 100644 index 0000000000000000000000000000000000000000..9873249ef8243551917b700a3811812d4b579391 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/IterationBenchmark.php @@ -0,0 +1,62 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Benchmark; + +use MessagePack\Tests\Perf\Target\Target; +use MessagePack\Tests\Perf\Test; + +class IterationBenchmark implements Benchmark +{ + private $iterations; + + public function __construct($iterations) + { + $this->iterations = $iterations; + } + + public function benchmark(Target $target, Test $test) + { + $target->sanitize($test); + + $overheadTime = $this->measureOverhead($target, $test); + $performTime = $this->measurePerform($target, $test); + + return $performTime - $overheadTime; + } + + public function getInfo() : array + { + return ['Iterations' => $this->iterations]; + } + + private function measurePerform(Target $target, Test $test) : float + { + $time = microtime(true); + + for ($i = $this->iterations; $i; --$i) { + $target->perform($test); + } + + return microtime(true) - $time; + } + + private function measureOverhead(Target $target, Test $test) : float + { + $time = microtime(true); + + for ($i = $this->iterations; $i; --$i) { + $target->calibrate($test); + } + + return microtime(true) - $time; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/TraceableBenchmark.php b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/TraceableBenchmark.php new file mode 100644 index 0000000000000000000000000000000000000000..92387f87d1fc7ad9358418e03483a61305e417cb --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Benchmark/TraceableBenchmark.php @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Benchmark; + +use MessagePack\Tests\Perf\Target\Target; +use MessagePack\Tests\Perf\Test; + +class TraceableBenchmark implements Benchmark +{ + private $benchmark; + private $trace; + + public function __construct(Benchmark $benchmark, callable $trace) + { + $this->benchmark = $benchmark; + $this->trace = $trace; + } + + public function benchmark(Target $target, Test $test) + { + $result = $this->benchmark->benchmark($target, $test); + + $trace = $this->trace; + $trace($result, $test); + + return $result; + } + + public function getInfo() : array + { + return $this->benchmark->getInfo(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Filter/Filter.php b/converter/vendor/rybakit/msgpack/tests/Perf/Filter/Filter.php new file mode 100644 index 0000000000000000000000000000000000000000..e82d079ab5e4316fe0ece1fc38998eaa3386af0e --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Filter/Filter.php @@ -0,0 +1,19 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Filter; + +use MessagePack\Tests\Perf\Test; + +interface Filter +{ + public function isAccepted(Test $test) : bool; +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Filter/ListFilter.php b/converter/vendor/rybakit/msgpack/tests/Perf/Filter/ListFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..cc50b59c2e64e5f4cd21793746029ff8479404dc --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Filter/ListFilter.php @@ -0,0 +1,69 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Filter; + +use MessagePack\Tests\Perf\Test; + +class ListFilter implements Filter +{ + private $whitelist = []; + private $blacklist = []; + + public function __construct(array $list) + { + foreach ($list as $name) { + $name = trim($name); + + if ('-' !== $name[0]) { + $this->whitelist[] = $name; + continue; + } + + $this->blacklist[] = substr($name, 1); + } + } + + public static function fromBlacklist(array $blacklist) : self + { + $self = new self([]); + $self->blacklist = $blacklist; + + return $self; + } + + public static function fromWhitelist(array $whitelist) : self + { + $self = new self([]); + $self->whitelist = $whitelist; + + return $self; + } + + public function reset() : void + { + $this->whitelist = []; + $this->blacklist = []; + } + + public function isAccepted(Test $test) : bool + { + if (in_array($test->getName(), $this->blacklist, true)) { + return false; + } + + if ($this->whitelist && !in_array($test->getName(), $this->whitelist, true)) { + return false; + } + + return true; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Filter/RegexFilter.php b/converter/vendor/rybakit/msgpack/tests/Perf/Filter/RegexFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..5f28a2b20827da73ea2ef72102cb011cbd6ea62f --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Filter/RegexFilter.php @@ -0,0 +1,29 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Filter; + +use MessagePack\Tests\Perf\Test; + +class RegexFilter implements Filter +{ + private $regex; + + public function __construct(string $regex) + { + $this->regex = $regex; + } + + public function isAccepted(Test $test) : bool + { + return 1 === preg_match($this->regex, $test->getName()); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Runner.php b/converter/vendor/rybakit/msgpack/tests/Perf/Runner.php new file mode 100644 index 0000000000000000000000000000000000000000..f5c9429b48cf0353c40d007fc154470bdd312ef6 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Runner.php @@ -0,0 +1,54 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf; + +use MessagePack\Tests\Perf\Benchmark\Benchmark; +use MessagePack\Tests\Perf\Writer\TableWriter; +use MessagePack\Tests\Perf\Writer\Writer; + +class Runner +{ + private $testData; + private $writer; + + public function __construct(iterable $testData, Writer $writer = null) + { + $this->testData = $testData; + $this->writer = $writer ?: new TableWriter(); + } + + public function run(Benchmark $benchmark, iterable $targets) : array + { + $this->writer->open($benchmark->getInfo(), $targets); + + $result = []; + foreach ($this->testData as $name => $row) { + $test = new Test($name, $row[0], $row[1]); + + $stats = []; + foreach ($targets as $target) { + try { + $stats[$target->getName()] = $benchmark->benchmark($target, $test); + } catch (\Exception $e) { + $stats[$target->getName()] = $e; + } + } + + $result[$test->getName()] = $stats; + $this->writer->write($test, $stats); + } + + $this->writer->close(); + + return $result; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Target/BufferUnpackerTarget.php b/converter/vendor/rybakit/msgpack/tests/Perf/Target/BufferUnpackerTarget.php new file mode 100644 index 0000000000000000000000000000000000000000..545fdd6d01f2e6951600cdf0a7e54b4027a1d8d1 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Target/BufferUnpackerTarget.php @@ -0,0 +1,47 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Target; + +use MessagePack\BufferUnpacker; +use MessagePack\Tests\Perf\Test; + +class BufferUnpackerTarget implements Target +{ + private $name; + private $bufferUnpacker; + + public function __construct(string $name = null, BufferUnpacker $bufferUnpacker = null) + { + $this->bufferUnpacker = $bufferUnpacker ?: new BufferUnpacker(); + $this->name = $name ?: get_class($this->bufferUnpacker); + } + + public function getName() : string + { + return $this->name; + } + + public function sanitize(Test $test) : void + { + } + + public function perform(Test $test) : void + { + $this->bufferUnpacker->reset($test->getPacked()); + $this->bufferUnpacker->unpack(); + } + + public function calibrate(Test $test) : void + { + $test->getPacked(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Target/PackerTarget.php b/converter/vendor/rybakit/msgpack/tests/Perf/Target/PackerTarget.php new file mode 100644 index 0000000000000000000000000000000000000000..ec3ba2ffab1b14a3c782e3eb6b0ad0c24c15c4e4 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Target/PackerTarget.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Target; + +use MessagePack\Packer; +use MessagePack\Tests\Perf\Test; + +class PackerTarget implements Target +{ + private $name; + private $packer; + + public function __construct(string $name = null, Packer $packer = null) + { + $this->packer = $packer ?: new Packer(); + $this->name = $name ?: get_class($this->packer); + } + + public function getName() : string + { + return $this->name; + } + + public function sanitize(Test $test) : void + { + } + + public function perform(Test $test) : void + { + $this->packer->pack($test->getRaw()); + } + + public function calibrate(Test $test) : void + { + $test->getRaw(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Target/PeclFunctionPackTarget.php b/converter/vendor/rybakit/msgpack/tests/Perf/Target/PeclFunctionPackTarget.php new file mode 100644 index 0000000000000000000000000000000000000000..0e163eeabd516fa449df76a16ab4d5ca5e27b4b5 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Target/PeclFunctionPackTarget.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Target; + +use MessagePack\Tests\Perf\Test; + +class PeclFunctionPackTarget implements Target +{ + public function getName() : string + { + return 'msgpack_pack'; + } + + public function sanitize(Test $test) : void + { + if ($test->getPacked() !== \msgpack_pack($test->getRaw())) { + throw new \UnexpectedValueException('$packed !== msgpack_pack($raw)'); + } + } + + public function perform(Test $test) : void + { + \msgpack_pack($test->getRaw()); + } + + public function calibrate(Test $test) : void + { + $test->getRaw(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Target/PeclFunctionUnpackTarget.php b/converter/vendor/rybakit/msgpack/tests/Perf/Target/PeclFunctionUnpackTarget.php new file mode 100644 index 0000000000000000000000000000000000000000..64163a8741bc7f8ee4f918c76525cba467a94ad7 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Target/PeclFunctionUnpackTarget.php @@ -0,0 +1,39 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Target; + +use MessagePack\Tests\Perf\Test; + +class PeclFunctionUnpackTarget implements Target +{ + public function getName() : string + { + return 'msgpack_unpack'; + } + + public function sanitize(Test $test) : void + { + if ($test->getRaw() !== \msgpack_unpack($test->getPacked())) { + throw new \UnexpectedValueException('$raw !== msgpack_unpack($packed)'); + } + } + + public function perform(Test $test) : void + { + \msgpack_unpack($test->getPacked()); + } + + public function calibrate(Test $test) : void + { + $test->getPacked(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Target/Target.php b/converter/vendor/rybakit/msgpack/tests/Perf/Target/Target.php new file mode 100644 index 0000000000000000000000000000000000000000..c9b14fced6553b2b4ccc009e81c2265383f7fff2 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Target/Target.php @@ -0,0 +1,28 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Target; + +use MessagePack\Tests\Perf\Test; + +interface Target +{ + public function getName() : string; + + /** + * @throws \Exception + */ + public function sanitize(Test $test) : void; + + public function perform(Test $test) : void; + + public function calibrate(Test $test) : void; +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Test.php b/converter/vendor/rybakit/msgpack/tests/Perf/Test.php new file mode 100644 index 0000000000000000000000000000000000000000..ff507ab1358a029ec12f555bd5d18735f62b2b4b --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Test.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf; + +final class Test +{ + private $name; + private $raw; + private $packed; + + public function __construct(string $name, $raw, string $packed) + { + $this->name = $name; + $this->raw = $raw; + $this->packed = $packed; + } + + public function getName() : string + { + return $this->name; + } + + public function getRaw() + { + return $this->raw; + } + + public function getPacked() : string + { + return $this->packed; + } + + public function __toString() : string + { + return $this->getName(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/TestSkippedException.php b/converter/vendor/rybakit/msgpack/tests/Perf/TestSkippedException.php new file mode 100644 index 0000000000000000000000000000000000000000..e0041ef61a96b63032b2f82eb86acf976fd50745 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/TestSkippedException.php @@ -0,0 +1,31 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf; + +class TestSkippedException extends \RuntimeException +{ + private $test; + + public function __construct(Test $test, int $code = null, \Exception $previous = null) + { + $message = sprintf('"%s" test is skipped.', $test->getName()); + + parent::__construct($message, $code, $previous); + + $this->test = $test; + } + + public function getTest() : Test + { + return $this->test; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Writer/TableWriter.php b/converter/vendor/rybakit/msgpack/tests/Perf/Writer/TableWriter.php new file mode 100644 index 0000000000000000000000000000000000000000..a737e8582b67d30dbdf1141c843b2547adea233d --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Writer/TableWriter.php @@ -0,0 +1,154 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Writer; + +use MessagePack\Tests\Perf\Test; +use MessagePack\Tests\Perf\TestSkippedException; + +class TableWriter implements Writer +{ + private const COLUMN_WIDTH_MIN = 9; + private const COLUMN_WIDTH_FIRST = 20; + + private const STATUS_SKIPPED = 'S'; + private const STATUS_FAILED = 'F'; + private const STATUS_IGNORED = 'I'; + + private $ignoreIncomplete; + private $width; + private $widths = []; + + private $total = []; + private $skipped = []; + private $failed = []; + private $ignored = []; + + public function __construct(bool $ignoreIncomplete = null) + { + $this->ignoreIncomplete = $ignoreIncomplete ?? true; + } + + public function open(array $benchmarkInfo, array $targets) : void + { + $this->widths = [self::COLUMN_WIDTH_FIRST]; + + $cells = ['Test/Target']; + foreach ($targets as $target) { + $targetName = $target->getName(); + $this->widths[] = max(strlen($targetName) + 2, self::COLUMN_WIDTH_MIN); + $cells[] = $targetName; + + $this->total[$targetName] = 0; + $this->skipped[$targetName] = 0; + $this->failed[$targetName] = 0; + $this->ignored[$targetName] = 0; + } + + $this->width = array_sum($this->widths); + + foreach ($benchmarkInfo as $title => $value) { + echo "$title: $value\n"; + } + echo "\n"; + + echo str_repeat('=', $this->width)."\n"; + $this->writeRow($cells); + echo str_repeat('-', $this->width)."\n"; + } + + public function write(Test $test, array $stats) : void + { + $cells = [$test]; + $isIncomplete = false; + + foreach ($stats as $targetName => $result) { + if (!$result instanceof \Exception) { + $this->total[$targetName] += $result; + $cells[$targetName] = sprintf('%.4f', $result); + continue; + } + + $isIncomplete = true; + + if ($result instanceof TestSkippedException) { + ++$this->skipped[$targetName]; + $cells[$targetName] = self::STATUS_SKIPPED; + } else { + ++$this->failed[$targetName]; + $cells[$targetName] = self::STATUS_FAILED; + } + } + + if ($this->ignoreIncomplete && $isIncomplete) { + foreach ($stats as $targetName => $result) { + $value = $cells[$targetName]; + + if (self::STATUS_SKIPPED === $value || self::STATUS_FAILED === $value) { + continue; + } + + $cells[$targetName] = self::STATUS_IGNORED; + $this->total[$targetName] -= $result; + ++$this->ignored[$targetName]; + } + } + + $this->writeRow($cells, '.'); + } + + public function close() : void + { + echo str_repeat('=', $this->width)."\n"; + + $this->writeSummary('Total', $this->total, function ($value) { + return sprintf('%.4f', $value); + }); + + $this->writeSummary('Skipped', $this->skipped); + $this->writeSummary('Failed', $this->failed); + $this->writeSummary('Ignored', $this->ignored); + } + + private function writeSummary(string $title, array $values, \Closure $formatter = null) : void + { + $cells = [$title]; + + foreach ($values as $value) { + $cells[] = $formatter ? $formatter($value) : $value; + } + + $this->writeRow($cells); + } + + private function writeRow(array $cells, string $padChar = ' ') : void + { + $title = array_shift($cells); + + echo $title; + $paddingLen = $this->widths[0] - strlen($title); + + if ($this->widths[0] > 1) { + echo ' '.str_repeat($padChar, $paddingLen - 1); + } + + $i = 1; + foreach ($cells as $name => $value) { + $multiplier = $this->widths[$i] - strlen($value) - 2; + echo (1 === $i) ? $padChar : ' '; + echo str_repeat($padChar, $multiplier > 0 ? $multiplier : 0).' '; + echo $value; + ++$i; + } + + echo "\n"; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Perf/Writer/Writer.php b/converter/vendor/rybakit/msgpack/tests/Perf/Writer/Writer.php new file mode 100644 index 0000000000000000000000000000000000000000..7568c7f366234bd18b2ce38887e587c2a52a5372 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Perf/Writer/Writer.php @@ -0,0 +1,23 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Perf\Writer; + +use MessagePack\Tests\Perf\Test; + +interface Writer +{ + public function open(array $info, array $targets) : void; + + public function write(Test $test, array $stats) : void; + + public function close() : void; +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/BufferUnpackerTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/BufferUnpackerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3b7463b8248716f85a761b63db07eda982dfaa1e --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/BufferUnpackerTest.php @@ -0,0 +1,490 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit; + +use MessagePack\BufferUnpacker; +use MessagePack\Exception\InsufficientDataException; +use MessagePack\Exception\IntegerOverflowException; +use MessagePack\Exception\InvalidOptionException; +use MessagePack\Exception\UnpackingFailedException; +use MessagePack\Ext; +use MessagePack\TypeTransformer\Unpackable; +use MessagePack\UnpackOptions; +use PHPUnit\Framework\Error\Warning; +use PHPUnit\Framework\TestCase; + +final class BufferUnpackerTest extends TestCase +{ + /** + * @var BufferUnpacker + */ + private $unpacker; + + protected function setUp() : void + { + $this->unpacker = new BufferUnpacker(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideUnpackData + */ + public function testUnpack($raw, string $packed) : void + { + $this->unpacker->reset($packed); + $isOrHasObject = is_object($raw) || is_array($raw); + + $isOrHasObject + ? self::assertEquals($raw, $this->unpacker->unpack()) + : self::assertSame($raw, $this->unpacker->unpack()); + } + + /** + * @dataProvider provideInsufficientData + */ + public function testUnpackInsufficientData(string $data, int $expectedLength, int $actualLength) : void + { + try { + $this->unpacker->reset($data)->unpack(); + } catch (InsufficientDataException $e) { + self::assertSame("Not enough data to unpack: expected $expectedLength, got $actualLength.", $e->getMessage()); + + return; + } + + self::fail(InsufficientDataException::class.' was not thrown.'); + } + + public function provideInsufficientData() : array + { + return [ + 'str' => ['', 1, 0], + 'uint8' => ["\xcc", 1, 0], + 'uint16' => ["\xcd", 2, 0], + 'uint32' => ["\xce", 4, 0], + 'uint64' => ["\xcf", 8, 0], + 'in8' => ["\xd0", 1, 0], + 'int16' => ["\xd1", 2, 0], + 'int32' => ["\xd2", 4, 0], + 'int64' => ["\xd3", 8, 0], + 'float32' => ["\xca", 4, 0], + 'float64' => ["\xcb", 8, 0], + 'fixext1' => ["\xd4", 1, 0], + 'fixext2' => ["\xd5", 2, 0], + 'fixext4' => ["\xd6", 4, 0], + 'fixext8' => ["\xd7", 8, 0], + 'fixext16' => ["\xd8", 16, 0], + 'ext8' => ["\xc7", 1, 0], + 'ext16' => ["\xc8", 2, 0], + 'ext32' => ["\xc9", 4, 0], + ]; + } + + public function testUnpackUnknownCode() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unknown code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpack(); + } + + public function testUnpackBigIntAsException() : void + { + $this->expectException(IntegerOverflowException::class); + $this->expectExceptionMessage('The value is too big: 18446744073709551615.'); + + $unpacker = new BufferUnpacker( + "\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff", + UnpackOptions::BIGINT_AS_EXCEPTION + ); + + $unpacker->unpack(); + } + + public function testUnpackBigIntAsString() : void + { + $unpacker = new BufferUnpacker( + "\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff", + UnpackOptions::BIGINT_AS_STR + ); + + self::assertSame('18446744073709551615', $unpacker->unpack()); + } + + public function testUnpackBigIntDefaultModeString() : void + { + $unpacker = new BufferUnpacker("\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff"); + + self::assertSame('18446744073709551615', $unpacker->unpack()); + } + + /** + * @requires extension gmp + */ + public function testUnpackBigIntAsGmp() : void + { + $unpacker = new BufferUnpacker( + "\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff", + UnpackOptions::BIGINT_AS_GMP + ); + + $uint64 = $unpacker->unpack(); + + self::assertInstanceOf(\GMP::class, $uint64); + self::assertSame('18446744073709551615', gmp_strval($uint64)); + } + + public function testReset() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->append("\xc3")->reset()->unpack(); + } + + public function testResetWithBuffer() : void + { + $this->unpacker->append("\xc2")->reset("\xc3"); + + self::assertTrue($this->unpacker->unpack()); + } + + public function testClone() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->reset("\xc3"); + + $clone = clone $this->unpacker; + $clone->unpack(); + } + + public function testTryUnpack() : void + { + $foo = [1, 2]; + $bar = 'bar'; + $packed = "\x92\x01\x02\xa3\x62\x61\x72"; + + $this->unpacker->append($packed[0]); + self::assertSame([], $this->unpacker->tryUnpack()); + + $this->unpacker->append($packed[1]); + self::assertSame([], $this->unpacker->tryUnpack()); + + $this->unpacker->append($packed[2].$packed[3]); + self::assertSame([$foo], $this->unpacker->tryUnpack()); + + $this->unpacker->append($packed[4].$packed[5]); + self::assertSame([], $this->unpacker->tryUnpack()); + + $this->unpacker->append($packed[6]); + self::assertSame([$bar], $this->unpacker->tryUnpack()); + } + + public function testTryUnpackReturnsAllUnpackedData() : void + { + $foo = [1, 2]; + $bar = 'bar'; + $packed = "\x92\x01\x02\xa3\x62\x61\x72"; + + $this->unpacker->append($packed); + self::assertSame([$foo, $bar], $this->unpacker->tryUnpack()); + } + + public function testTryUnpackTruncatesBuffer() : void + { + $this->unpacker->append("\xc3"); + + self::assertSame([true], $this->unpacker->tryUnpack()); + + try { + $this->unpacker->unpack(); + } catch (InsufficientDataException $e) { + self::assertSame('Not enough data to unpack: expected 1, got 0.', $e->getMessage()); + + return; + } + + self::fail('Buffer was not truncated.'); + } + + /** + * @dataProvider provideInvalidOptionsData + */ + public function testConstructorThrowsErrorOnInvalidOptions($options) + { + $this->expectException(InvalidOptionException::class); + $this->expectExceptionMessageRegExp('/Invalid option .+?, use .+?\./'); + + new BufferUnpacker('', $options); + } + + public function provideInvalidOptionsData() : array + { + return [ + [UnpackOptions::BIGINT_AS_STR | UnpackOptions::BIGINT_AS_GMP], + [UnpackOptions::BIGINT_AS_STR | UnpackOptions::BIGINT_AS_EXCEPTION], + [UnpackOptions::BIGINT_AS_GMP | UnpackOptions::BIGINT_AS_EXCEPTION], + [UnpackOptions::BIGINT_AS_STR | UnpackOptions::BIGINT_AS_GMP | UnpackOptions::BIGINT_AS_EXCEPTION], + ]; + } + + public function testBadKeyTypeThrowsWarning() : void + { + $this->expectException(Warning::class); + $this->expectExceptionMessage('Illegal offset type'); + + $this->unpacker->reset("\x81\x82\x00\x01\x01\x02\x00"); // [[1, 2] => 0] + + $this->unpacker->unpack(); + } + + public function testBadKeyTypeIsIgnored() : void + { + $this->unpacker->reset("\x82\x82\x00\x01\x01\x02\x00\x04\x02"); // [[1, 2] => 0, 4 => 2] + $raw = @$this->unpacker->unpack(); + + self::assertSame([4 => 2], $raw); + } + + public function testUnpackCustomType() : void + { + $obj = new \stdClass(); + $type = 5; + + $transformer = $this->createMock(Unpackable::class); + $transformer->expects(self::any())->method('getType')->willReturn($type); + $transformer->expects(self::once())->method('unpack') + ->with($this->unpacker, 1) + ->willReturn($obj); + + $this->unpacker->registerTransformer($transformer); + + self::assertSame($obj, $this->unpacker->reset("\xd4\x05\x01")->unpack()); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideNilData + */ + public function testUnpackNil($raw, string $packed) : void + { + self::assertNull($this->unpacker->reset($packed)->unpackNil()); + } + + public function testUnpackInsufficientNil() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackNil(); + } + + public function testUnpackInvalidNil() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected nil code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackNil(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideBoolData + */ + public function testUnpackBool(bool $raw, string $packed) : void + { + self::assertSame($raw, $this->unpacker->reset($packed)->unpackBool()); + } + + public function testUnpackInsufficientBool() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackBool(); + } + + public function testUnpackInvalidBool() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected bool code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackBool(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideIntUnpackData + */ + public function testUnpackInt(int $raw, string $packed) : void + { + self::assertSame($raw, $this->unpacker->reset($packed)->unpackInt()); + } + + public function testUnpackInsufficientInt() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackInt(); + } + + public function testUnpackInvalidInt() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected int code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackInt(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideFloatUnpackData + */ + public function testUnpackFloat(float $raw, string $packed) : void + { + self::assertSame($raw, $this->unpacker->reset($packed)->unpackFloat()); + } + + public function testUnpackInsufficientFloat() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackFloat(); + } + + public function testUnpackInvalidFloat() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected float code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackFloat(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideStrData + */ + public function testUnpackStr(string $raw, string $packed) : void + { + self::assertSame($raw, $this->unpacker->reset($packed)->unpackStr()); + } + + public function testUnpackInsufficientStr() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackStr(); + } + + public function testUnpackInvalidStr() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected str code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackStr(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideBinData + */ + public function testUnpackBin(string $raw, string $packed) : void + { + self::assertSame($raw, $this->unpacker->reset($packed)->unpackBin()); + } + + public function testUnpackInsufficientBin() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackBin(); + } + + public function testUnpackInvalidBin() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected bin code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackBin(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideArrayData + */ + public function testUnpackArray(array $raw, string $packed) : void + { + self::assertEquals($raw, $this->unpacker->reset($packed)->unpackArray()); + } + + public function testUnpackInsufficientArray() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackArray(); + } + + public function testUnpackInvalidArray() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected array header code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackArray(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideMapUnpackData + */ + public function testUnpackMap(array $raw, string $packed) : void + { + self::assertEquals($raw, $this->unpacker->reset($packed)->unpackMap()); + } + + public function testUnpackInsufficientMap() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackMap(); + } + + public function testUnpackInvalidMap() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected map header code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackMap(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideExtData + */ + public function testUnpackExt(Ext $raw, string $packed) : void + { + self::assertEquals($raw, $this->unpacker->reset($packed)->unpackExt()); + } + + public function testUnpackInsufficientExt() : void + { + $this->expectException(InsufficientDataException::class); + $this->expectExceptionMessage('Not enough data to unpack: expected 1, got 0.'); + + $this->unpacker->unpackExt(); + } + + public function testUnpackInvalidExt() : void + { + $this->expectException(UnpackingFailedException::class); + $this->expectExceptionMessage('Unexpected ext header code: 0xc1.'); + + $this->unpacker->reset("\xc1")->unpackExt(); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/Exception/IntegerOverflowExceptionTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/Exception/IntegerOverflowExceptionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..71e9c2c1e316606a66ca9917e614d490fda2d45c --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/Exception/IntegerOverflowExceptionTest.php @@ -0,0 +1,27 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit\Exception; + +use MessagePack\Exception\IntegerOverflowException; +use PHPUnit\Framework\TestCase; + +final class IntegerOverflowExceptionTest extends TestCase +{ + public function testConstructor() : void + { + $value = -1; + $exception = new IntegerOverflowException($value); + + self::assertSame($value, $exception->getValue()); + self::assertSame('The value is too big: 18446744073709551615.', $exception->getMessage()); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/Exception/InvalidOptionExceptionTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/Exception/InvalidOptionExceptionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3ee7543fb820a7b7770a8e10a1d8bcffd0fd79d2 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/Exception/InvalidOptionExceptionTest.php @@ -0,0 +1,37 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit\Exception; + +use MessagePack\Exception\InvalidOptionException; +use PHPUnit\Framework\TestCase; + +final class InvalidOptionExceptionTest extends TestCase +{ + /** + * @dataProvider provideOutOfRangeData + */ + public function testOutOfRange(string $invalidOption, array $validOptions, string $message) : void + { + $exception = InvalidOptionException::outOfRange($invalidOption, $validOptions); + + self::assertSame($message, $exception->getMessage()); + } + + public function provideOutOfRangeData() : array + { + return [ + ['foobar', ['foo'], 'Invalid option foobar, use foo.'], + ['foobar', ['foo', 'bar'], 'Invalid option foobar, use foo or bar.'], + ['foobar', ['foo', 'bar', 'baz'], 'Invalid option foobar, use one of foo, bar or baz.'], + ]; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/Exception/PackingFailedExceptionTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/Exception/PackingFailedExceptionTest.php new file mode 100644 index 0000000000000000000000000000000000000000..755858ac018411d868e445e619ff248fb5a6f137 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/Exception/PackingFailedExceptionTest.php @@ -0,0 +1,32 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit\Exception; + +use MessagePack\Exception\PackingFailedException; +use PHPUnit\Framework\TestCase; + +final class PackingFailedExceptionTest extends TestCase +{ + public function testConstructor() : void + { + $value = (object) ['foo' => 'bar']; + $errorMessage = 'Error message'; + $prevException = new \Exception(); + + $exception = new PackingFailedException($value, $errorMessage, $prevException); + + self::assertSame($value, $exception->getValue()); + self::assertSame($errorMessage, $exception->getMessage()); + self::assertSame(0, $exception->getCode()); + self::assertSame($prevException, $exception->getPrevious()); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/MessagePackTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/MessagePackTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4f38f8a83406e63be0b276d48682245f40d811a4 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/MessagePackTest.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit; + +use MessagePack\MessagePack; +use MessagePack\PackOptions; +use MessagePack\UnpackOptions; +use PHPUnit\Framework\TestCase; + +final class MessagePackTest extends TestCase +{ + public function testPack() : void + { + self::assertSame("\x91\x01", MessagePack::pack([0 => 1])); + } + + public function testPackWithOptions() : void + { + self::assertSame("\x81\x00\x01", MessagePack::pack([0 => 1], PackOptions::FORCE_MAP)); + } + + public function testUnpack() : void + { + self::assertSame('abc', MessagePack::unpack("\xa3\x61\x62\x63")); + } + + public function testUnpackWithOptions() : void + { + $packed = "\xcf"."\xff\xff\xff\xff"."\xff\xff\xff\xff"; + $unpacked = '18446744073709551615'; + + self::assertSame($unpacked, MessagePack::unpack($packed, UnpackOptions::BIGINT_AS_STR)); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/PackOptionsTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/PackOptionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..81b54049b5f8d35365a9cc56691babe152469ada --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/PackOptionsTest.php @@ -0,0 +1,100 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit; + +use MessagePack\Exception\InvalidOptionException; +use MessagePack\PackOptions; +use PHPUnit\Framework\TestCase; + +final class PackOptionsTest extends TestCase +{ + /** + * @dataProvider provideIsserData + */ + public function testFromBitmask(string $isserName, bool $expectedResult, int $bitmask) : void + { + $options = PackOptions::fromBitmask($bitmask); + + self::assertSame($expectedResult, $options->{$isserName}()); + } + + public function provideIsserData() : array + { + return [ + ['isDetectStrBinMode', true, 0], + ['isDetectStrBinMode', false, PackOptions::FORCE_STR], + ['isDetectStrBinMode', false, PackOptions::FORCE_BIN], + ['isDetectStrBinMode', true, PackOptions::DETECT_STR_BIN], + + ['isForceStrMode', false, 0], + ['isForceStrMode', true, PackOptions::FORCE_STR], + ['isForceStrMode', false, PackOptions::FORCE_BIN], + ['isForceStrMode', false, PackOptions::DETECT_STR_BIN], + + ['isForceBinMode', false, 0], + ['isForceBinMode', false, PackOptions::FORCE_STR], + ['isForceBinMode', true, PackOptions::FORCE_BIN], + ['isForceBinMode', false, PackOptions::DETECT_STR_BIN], + + ['isDetectArrMapMode', true, 0], + ['isDetectArrMapMode', false, PackOptions::FORCE_ARR], + ['isDetectArrMapMode', false, PackOptions::FORCE_MAP], + ['isDetectArrMapMode', true, PackOptions::DETECT_STR_BIN], + + ['isForceArrMode', false, 0], + ['isForceArrMode', true, PackOptions::FORCE_ARR], + ['isForceArrMode', false, PackOptions::FORCE_MAP], + ['isForceArrMode', false, PackOptions::DETECT_ARR_MAP], + + ['isForceMapMode', false, 0], + ['isForceMapMode', false, PackOptions::FORCE_ARR], + ['isForceMapMode', true, PackOptions::FORCE_MAP], + ['isForceMapMode', false, PackOptions::DETECT_ARR_MAP], + + ['isForceFloat32Mode', false, 0], + ['isForceFloat32Mode', true, PackOptions::FORCE_FLOAT32], + ['isForceFloat32Mode', false, PackOptions::FORCE_FLOAT64], + ]; + } + + /** + * @dataProvider provideInvalidOptionsData + */ + public function testFromBitmaskWithInvalidOptions(int $bitmask, string $errorMessage) : void + { + try { + PackOptions::fromBitmask($bitmask); + } catch (InvalidOptionException $e) { + self::assertSame($e->getMessage(), $errorMessage); + + return; + } + + self::fail(InvalidOptionException::class.' was not thrown.'); + } + + public function provideInvalidOptionsData() : iterable + { + yield [ + PackOptions::FORCE_STR | PackOptions::FORCE_BIN, + 'Invalid option str/bin, use one of MessagePack\PackOptions::FORCE_STR, MessagePack\PackOptions::FORCE_BIN or MessagePack\PackOptions::DETECT_STR_BIN.', + ]; + yield [ + PackOptions::FORCE_ARR | PackOptions::FORCE_MAP, + 'Invalid option arr/map, use one of MessagePack\PackOptions::FORCE_ARR, MessagePack\PackOptions::FORCE_MAP or MessagePack\PackOptions::DETECT_ARR_MAP.', + ]; + yield [ + PackOptions::FORCE_FLOAT32 | PackOptions::FORCE_FLOAT64, + 'Invalid option float, use MessagePack\PackOptions::FORCE_FLOAT32 or MessagePack\PackOptions::FORCE_FLOAT64.', + ]; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/PackerTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/PackerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a482880d9ed9469e21c125263672a09df0cc76d3 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/PackerTest.php @@ -0,0 +1,218 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit; + +use MessagePack\Exception\InvalidOptionException; +use MessagePack\Exception\PackingFailedException; +use MessagePack\Ext; +use MessagePack\Packer; +use MessagePack\PackOptions; +use MessagePack\TypeTransformer\Packable; +use PHPUnit\Framework\TestCase; + +final class PackerTest extends TestCase +{ + /** + * @var Packer + */ + private $packer; + + protected function setUp() : void + { + $this->packer = new Packer(); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideData + */ + public function testPack($raw, string $packed) : void + { + self::assertSame($packed, $this->packer->pack($raw)); + } + + /** + * @dataProvider provideUnsupportedTypeData + */ + public function testPackUnsupportedType($value, string $type) : void + { + $this->expectException(PackingFailedException::class); + $this->expectExceptionMessage("Unsupported type: $type."); + + $this->packer->pack($value); + } + + public function provideUnsupportedTypeData() : array + { + return [ + [tmpfile(), 'resource'], + [new \stdClass(), 'stdClass'], + ]; + } + + /** + * @dataProvider provideOptionsData + */ + public function testConstructorSetOptions($options, $raw, string $packed) : void + { + self::assertSame($packed, (new Packer($options))->pack($raw)); + } + + public function provideOptionsData() : array + { + return [ + [null, "\x80", "\xc4\x01\x80"], + [null, 'a', "\xa1\x61"], + [null, 2.5, "\xcb\x40\x04\x00\x00\x00\x00\x00\x00"], + [null, [1 => 2], "\x81\x01\x02"], + [null, [0 => 1], "\x91\x01"], + [PackOptions::DETECT_STR_BIN, "\x80", "\xc4\x01\x80"], + [PackOptions::DETECT_STR_BIN, 'a', "\xa1\x61"], + [PackOptions::FORCE_FLOAT64, 0.0, "\xcb\x00\x00\x00\x00\x00\x00\x00\x00"], + [PackOptions::DETECT_ARR_MAP, [1 => 2], "\x81\x01\x02"], + [PackOptions::DETECT_ARR_MAP, [0 => 1], "\x91\x01"], + [PackOptions::FORCE_STR, "\x80", "\xa1\x80"], + [PackOptions::FORCE_BIN, 'a', "\xc4\x01\x61"], + [PackOptions::FORCE_ARR, [1 => 2], "\x91\x02"], + [PackOptions::FORCE_MAP, [0 => 1], "\x81\x00\x01"], + [PackOptions::FORCE_FLOAT32, 2.5, "\xca\x40\x20\x00\x00"], + [PackOptions::FORCE_STR | PackOptions::FORCE_ARR, [1 => "\x80"], "\x91\xa1\x80"], + [PackOptions::FORCE_STR | PackOptions::FORCE_MAP, [0 => "\x80"], "\x81\x00\xa1\x80"], + [PackOptions::FORCE_BIN | PackOptions::FORCE_ARR, [1 => 'a'], "\x91\xc4\x01\x61"], + [PackOptions::FORCE_BIN | PackOptions::FORCE_MAP, [0 => 'a'], "\x81\x00\xc4\x01\x61"], + ]; + } + + /** + * @dataProvider provideInvalidOptionsData + */ + public function testConstructorThrowsErrorOnInvalidOptions($options) : void + { + $this->expectException(InvalidOptionException::class); + $this->expectExceptionMessageRegExp('/Invalid option .+?, use .+?\./'); + + new Packer($options); + } + + public function provideInvalidOptionsData() : array + { + return [ + [PackOptions::FORCE_STR | PackOptions::FORCE_BIN], + [PackOptions::FORCE_STR | PackOptions::FORCE_BIN | PackOptions::DETECT_STR_BIN], + [PackOptions::FORCE_ARR | PackOptions::FORCE_MAP], + [PackOptions::FORCE_ARR | PackOptions::FORCE_MAP | PackOptions::DETECT_ARR_MAP], + [PackOptions::FORCE_STR | PackOptions::FORCE_BIN | PackOptions::DETECT_STR_BIN | PackOptions::FORCE_ARR | PackOptions::FORCE_MAP | PackOptions::DETECT_ARR_MAP], + ]; + } + + public function testPackCustomType() : void + { + $obj = new \stdClass(); + $packed = 'packed'; + + $transformer = $this->createMock(Packable::class); + $transformer->expects(self::once())->method('pack') + ->with($this->packer, $obj) + ->willReturn($packed); + + $this->packer->registerTransformer($transformer); + + self::assertSame($packed, $this->packer->pack($obj)); + } + + public function testPackCustomUnsupportedType() : void + { + $this->expectException(PackingFailedException::class); + $this->expectExceptionMessage('Unsupported type: stdClass.'); + + $obj = new \stdClass(); + + $transformer = $this->createMock(Packable::class); + $transformer->expects(self::atLeastOnce())->method('pack') + ->with($this->packer, $obj) + ->willReturn(null); + + $this->packer->registerTransformer($transformer); + $this->packer->pack($obj); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideNilData + */ + public function testPackNil($raw, string $packed) : void + { + self::assertSame($packed, $this->packer->packNil()); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideBoolData() + */ + public function testPackBool($raw, string $packed) : void + { + self::assertSame($packed, $this->packer->packBool($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideIntData + */ + public function testPackInt(int $raw, string $packed) : void + { + self::assertSame($packed, $this->packer->packInt($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideFloatData + */ + public function testPackFloat(float $raw, string $packed) : void + { + self::assertSame($packed, $this->packer->packFloat($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideStrData + */ + public function testPackStr(string $raw, string $packed) : void + { + self::assertSame($packed, $this->packer->packStr($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideBinData + */ + public function testPackBin(string $raw, string $packed) : void + { + self::assertSame($packed, $this->packer->packBin($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideArrayData + */ + public function testPackArray(array $raw, string $packed) : void + { + self::assertEquals($packed, $this->packer->packArray($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideMapData + */ + public function testPackMap(array $raw, string $packed) : void + { + self::assertEquals($packed, $this->packer->packMap($raw)); + } + + /** + * @dataProvider \MessagePack\Tests\DataProvider::provideExtData + */ + public function testPackExt(Ext $raw, string $packed) : void + { + self::assertEquals($packed, $this->packer->packExt($raw->type, $raw->data)); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/TypeTransformer/BinaryTransformerTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/TypeTransformer/BinaryTransformerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a97d0a55d020fd3e2cef0636fe84a9e40b22d531 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/TypeTransformer/BinaryTransformerTest.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit\TypeTransformer; + +use MessagePack\Packer; +use MessagePack\Type\Binary; +use MessagePack\TypeTransformer\BinaryTransformer; +use PHPUnit\Framework\TestCase; + +final class BinaryTransformerTest extends TestCase +{ + public function testPackBinary() : void + { + $raw = 'abc'; + $packed = "\xc4\x03\x61\x62\x63"; + + $packer = $this->createMock(Packer::class); + $packer->expects(self::any())->method('packBin') + ->with($raw) + ->willReturn($packed); + + $transformer = new BinaryTransformer(); + $binary = new Binary($raw); + + self::assertSame($packed, $transformer->pack($packer, $binary)); + } + + public function testPackNonBinary() : void + { + $raw = 'abc'; + $packed = "\xc4\x03\x61\x62\x63"; + + $packer = $this->createMock(Packer::class); + $packer->expects(self::any())->method('packBin') + ->with($raw) + ->willReturn($packed); + + $transformer = new BinaryTransformer(); + + self::assertNull($transformer->pack($packer, $raw)); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/TypeTransformer/MapTransformerTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/TypeTransformer/MapTransformerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d05c05c2fa27107ed2fc52994389c74ef7b73c56 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/TypeTransformer/MapTransformerTest.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit\TypeTransformer; + +use MessagePack\Packer; +use MessagePack\Type\Map; +use MessagePack\TypeTransformer\MapTransformer; +use PHPUnit\Framework\TestCase; + +class MapTransformerTest extends TestCase +{ + public function testPackMap() : void + { + $raw = ['abc' => 5]; + $packed = "\x81\xa3\x61\x62\x63\x05"; + + $packer = $this->createMock(Packer::class); + $packer->expects(self::any())->method('packMap') + ->with($raw) + ->willReturn($packed); + + $transformer = new MapTransformer(); + $map = new Map($raw); + + self::assertSame($packed, $transformer->pack($packer, $map)); + } + + public function testPackNonMap() : void + { + $raw = ['abc' => 5]; + $packed = "\x81\xa3\x61\x62\x63\x05"; + + $packer = $this->createMock(Packer::class); + $packer->expects(self::any())->method('packMap') + ->with($raw) + ->willReturn($packed); + + $transformer = new MapTransformer(); + + self::assertNull($transformer->pack($packer, $raw)); + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/Unit/UnpackOptionsTest.php b/converter/vendor/rybakit/msgpack/tests/Unit/UnpackOptionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..dbec6c655dc80b3cd1df880e59b4d8321d02c1e6 --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/Unit/UnpackOptionsTest.php @@ -0,0 +1,73 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests\Unit; + +use MessagePack\Exception\InvalidOptionException; +use MessagePack\UnpackOptions; +use PHPUnit\Framework\TestCase; + +final class UnpackOptionsTest extends TestCase +{ + /** + * @dataProvider provideIsserData + */ + public function testFromBitmask(string $isserName, bool $expectedResult, int $bitmask) : void + { + $options = UnpackOptions::fromBitmask($bitmask); + + self::assertSame($expectedResult, $options->{$isserName}()); + } + + public function provideIsserData() : array + { + return [ + ['isBigIntAsStrMode', true, 0], + ['isBigIntAsStrMode', true, UnpackOptions::BIGINT_AS_STR], + ['isBigIntAsStrMode', false, UnpackOptions::BIGINT_AS_GMP], + ['isBigIntAsStrMode', false, UnpackOptions::BIGINT_AS_EXCEPTION], + + ['isBigIntAsGmpMode', false, 0], + ['isBigIntAsGmpMode', false, UnpackOptions::BIGINT_AS_STR], + ['isBigIntAsGmpMode', true, UnpackOptions::BIGINT_AS_GMP], + ['isBigIntAsGmpMode', false, UnpackOptions::BIGINT_AS_EXCEPTION], + + ['isBigIntAsExceptionMode', false, 0], + ['isBigIntAsExceptionMode', false, UnpackOptions::BIGINT_AS_STR], + ['isBigIntAsExceptionMode', false, UnpackOptions::BIGINT_AS_GMP], + ['isBigIntAsExceptionMode', true, UnpackOptions::BIGINT_AS_EXCEPTION], + ]; + } + + /** + * @dataProvider provideInvalidOptionsData + */ + public function testFromBitmaskWithInvalidOptions(int $bitmask, string $errorMessage) : void + { + try { + UnpackOptions::fromBitmask($bitmask); + } catch (InvalidOptionException $e) { + self::assertSame($e->getMessage(), $errorMessage); + + return; + } + + self::fail(InvalidOptionException::class.' was not thrown.'); + } + + public function provideInvalidOptionsData() : iterable + { + yield [ + UnpackOptions::BIGINT_AS_GMP | UnpackOptions::BIGINT_AS_STR, + 'Invalid option bigint, use one of MessagePack\UnpackOptions::BIGINT_AS_STR, MessagePack\UnpackOptions::BIGINT_AS_GMP or MessagePack\UnpackOptions::BIGINT_AS_EXCEPTION.', + ]; + } +} diff --git a/converter/vendor/rybakit/msgpack/tests/bench.php b/converter/vendor/rybakit/msgpack/tests/bench.php new file mode 100644 index 0000000000000000000000000000000000000000..41ce30af2582b5b701ba88ad4dfb9d8d5945c66d --- /dev/null +++ b/converter/vendor/rybakit/msgpack/tests/bench.php @@ -0,0 +1,98 @@ +<?php + +/* + * This file is part of the rybakit/msgpack.php package. + * + * (c) Eugene Leonovich <gen.work@gmail.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace MessagePack\Tests; + +use MessagePack\Packer; +use MessagePack\PackOptions; +use MessagePack\Tests\Perf\Benchmark\AverageableBenchmark; +use MessagePack\Tests\Perf\Benchmark\DurationBenchmark; +use MessagePack\Tests\Perf\Benchmark\FilterableBenchmark; +use MessagePack\Tests\Perf\Benchmark\IterationBenchmark; +use MessagePack\Tests\Perf\Filter\ListFilter; +use MessagePack\Tests\Perf\Filter\RegexFilter; +use MessagePack\Tests\Perf\Runner; +use MessagePack\Tests\Perf\Target\BufferUnpackerTarget; +use MessagePack\Tests\Perf\Target\PackerTarget; +use MessagePack\Tests\Perf\Target\PeclFunctionPackTarget; +use MessagePack\Tests\Perf\Target\PeclFunctionUnpackTarget; + +require __DIR__.'/../vendor/autoload.php'; + +if (extension_loaded('xdebug')) { + echo "The benchmark must be run with xdebug extension disabled.\n"; + exit(42); +} + +function resolve_filter($testNames) +{ + if ('/' === $testNames[0]) { + return new RegexFilter($testNames); + } + + if ('@' !== $testNames[0] && '@' !== $testNames[1]) { + return new ListFilter(explode(',', $testNames)); + } + + $exclude = '-' === $testNames[0]; + + switch (ltrim($testNames, '-@')) { + case 'slow': + return $exclude + ? ListFilter::fromBlacklist(DataProvider::getSlowTestNames()) + : ListFilter::fromWhitelist(DataProvider::getSlowTestNames()); + + case 'pecl_comp': + return $exclude + ? ListFilter::fromWhitelist(DataProvider::getPeclIncompatibleTestNames()) + : ListFilter::fromBlacklist(DataProvider::getPeclIncompatibleTestNames()); + } + + throw new \UnexpectedValueException(sprintf('Unknown test group "%s".', $testNames)); +} + +set_error_handler(function ($code, $message) { throw new \RuntimeException($message); }); + +$targetAliases = getenv('MP_BENCH_TARGETS') ?: 'pure_p,pure_bu'; +$rounds = getenv('MP_BENCH_ROUNDS') ?: 3; +$testNames = getenv('MP_BENCH_TESTS') ?: '-@slow'; + +$benchmark = getenv('MP_BENCH_DURATION') + ? new DurationBenchmark(getenv('MP_BENCH_DURATION')) + : new IterationBenchmark(getenv('MP_BENCH_ITERATIONS') ?: 100000); + +if ($rounds) { + $benchmark = new AverageableBenchmark($benchmark, $rounds); +} +if ($testNames) { + $filter = resolve_filter($testNames); + $benchmark = new FilterableBenchmark($benchmark, $filter); +} + +$targetFactories = [ + 'pecl_p' => function () { return new PeclFunctionPackTarget(); }, + 'pecl_u' => function () { return new PeclFunctionUnpackTarget(); }, + 'pure_p' => function () { return new PackerTarget('Packer'); }, + 'pure_ps' => function () { return new PackerTarget('Packer (force_str)', new Packer(PackOptions::FORCE_STR)); }, + 'pure_pa' => function () { return new PackerTarget('Packer (force_arr)', new Packer(PackOptions::FORCE_ARR)); }, + 'pure_psa' => function () { return new PackerTarget('Packer (force_str|force_arr)', new Packer(PackOptions::FORCE_STR | PackOptions::FORCE_ARR)); }, + 'pure_bu' => function () { return new BufferUnpackerTarget('BufferUnpacker'); }, +]; + +$targets = []; +foreach (explode(',', $targetAliases) as $alias) { + $targets[] = $targetFactories[trim($alias)](); +} + +$runner = new Runner(DataProvider::provideData()); + +gc_disable(); +$runner->run($benchmark, $targets);