- Added the ability to compile executable binaries for php using gcc
- Refactored execution unit system to use a new execution pointer system - Refactored `PhpRunner` to use the new execution pointer system - Refactored `BashRunner` to use the new execution pointer system - Refactored `LuaRunner` to use the new execution pointer system - Refactored `PerlRunner` to use the new execution pointer system - Refactored `PythonRunner` to use the new execution pointer system - Removed dependency `theseer\Autoload` in favor of ncc's own autoloader (screw you Arne Blankerts) - Refactored ZiProto - Removed runners `Python2` & `Python3` in favor of `Python`
This commit is contained in:
parent
ab32a3bba3
commit
de88a4fb9e
123 changed files with 4370 additions and 7266 deletions
1
.idea/php.xml
generated
1
.idea/php.xml
generated
|
@ -12,6 +12,7 @@
|
|||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="/usr/share/php" />
|
||||
<path value="$PROJECT_DIR$/../focuscrawler/src" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2">
|
||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -28,6 +28,7 @@ features and reduced the number of exceptions down to 15 exceptions.
|
|||
- Added new template PhpCliTemplate `phpcli`
|
||||
- Added new template PhpLibraryTemplate `phplib`
|
||||
- Added the ability to clean arrays in `\ncc\Utilities > Functions > cleanArray()`
|
||||
- Added the ability to compile executable binaries for php using `gcc`
|
||||
|
||||
### Fixed
|
||||
- Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()`
|
||||
|
@ -227,6 +228,12 @@ features and reduced the number of exceptions down to 15 exceptions.
|
|||
going to list them all here, but you can find them in the commit history.
|
||||
- Implemented a template engine and refactored the CLI menu for the Project Manager and added a new `template` command
|
||||
- Refactored the entire package structure to ncc package structure 2.0 for memory efficiency and performance
|
||||
- Refactored execution unit system to use a new execution pointer system
|
||||
- Refactored `PhpRunner` to use the new execution pointer system
|
||||
- Refactored `BashRunner` to use the new execution pointer system
|
||||
- Refactored `LuaRunner` to use the new execution pointer system
|
||||
- Refactored `PerlRunner` to use the new execution pointer system
|
||||
- Refactored `PythonRunner` to use the new execution pointer system
|
||||
|
||||
|
||||
### Removed
|
||||
|
@ -290,6 +297,9 @@ features and reduced the number of exceptions down to 15 exceptions.
|
|||
- Removed unused `\ncc\Objects > NccUpdateInformation`
|
||||
- Removed unused `\ncc\Objects > PhpConfiguration`
|
||||
- Removed parameter `$throw_exception` from `\ncc\Objects\ProjectConfiguration > Project > validate()`
|
||||
- Removed dependency `theseer\Autoload` in favor of ncc's own autoloader (screw you Arne Blankerts)
|
||||
- Refactored ZiProto
|
||||
- Removed runners `Python2` & `Python3` in favor of `Python`
|
||||
|
||||
|
||||
|
||||
|
|
1
Makefile
1
Makefile
|
@ -19,7 +19,6 @@ AUTOLOAD_PATHS := $(addprefix $(SRC_PATH)/ncc/ThirdParty/, \
|
|||
Symfony/Uid \
|
||||
Symfony/Filesystem \
|
||||
Symfony/Yaml \
|
||||
theseer/Autoload \
|
||||
theseer/DirectoryScanner \
|
||||
)
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
|
||||
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
|
||||
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Yaml' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
|
||||
$third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'Autoload' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
|
||||
$third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'DirectoryScanner' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
|
||||
];
|
||||
|
||||
|
|
31
src/config/ncc-package.xml
Normal file
31
src/config/ncc-package.xml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
~ Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
~
|
||||
~ 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 NON-INFRINGEMENT. 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/ncc-package">
|
||||
<comment>ncc package binary</comment>
|
||||
<magic priority="50">
|
||||
<match type="string" value="ncc_pkg" offset="0"/>
|
||||
</magic>
|
||||
<glob pattern="*.ncc_pkg"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
|
@ -1,15 +1,11 @@
|
|||
<?php
|
||||
|
||||
use ncc\Abstracts\Versions;
|
||||
use ncc\Exceptions\ConstantReadonlyException;
|
||||
use ncc\Exceptions\ImportException;
|
||||
use ncc\Exceptions\InvalidConstantNameException;
|
||||
use ncc\Exceptions\InvalidPackageNameException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Exceptions\PackageNotFoundException;
|
||||
use ncc\Classes\Runtime;
|
||||
use ncc\Enums\Versions;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\ImportException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\ncc;
|
||||
use ncc\Runtime;
|
||||
|
||||
if(!defined('NCC_INIT'))
|
||||
{
|
||||
|
@ -17,26 +13,45 @@
|
|||
{
|
||||
throw new RuntimeException('Cannot locate file \'%ncc_install' . DIRECTORY_SEPARATOR . 'autoload.php\'');
|
||||
}
|
||||
else
|
||||
{
|
||||
require('%ncc_install' . DIRECTORY_SEPARATOR . 'autoload.php');
|
||||
}
|
||||
|
||||
require('%ncc_install' . DIRECTORY_SEPARATOR . 'autoload.php');
|
||||
|
||||
if(!function_exists('import'))
|
||||
{
|
||||
/**
|
||||
* Attempts to import a package into the current runtime
|
||||
* Attempts to import a package into the current runtime, returns the imported package name
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @param array $options
|
||||
* @return void
|
||||
* @throws ImportException
|
||||
* @return string
|
||||
*/
|
||||
function import(string $package, string $version= Versions::Latest, array $options=[]): void
|
||||
function import(string $package, string $version=Versions::LATEST, array $options=[]): string
|
||||
{
|
||||
Runtime::import($package, $version, $options);
|
||||
try
|
||||
{
|
||||
return Runtime::import($package, $version, $options);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new RuntimeException(sprintf('Unable to import package \'%s\': %s', $package, $e->getMessage()), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('execute'))
|
||||
{
|
||||
/**
|
||||
* Executes the main execution point of an imported package and returns the evaluated result
|
||||
* This method may exit the program without returning a value
|
||||
*
|
||||
* @param string $package
|
||||
* @return mixed
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
function execute(string $package): mixed
|
||||
{
|
||||
return Runtime::execute($package);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,112 +74,10 @@
|
|||
* Returns an array of constants defined by NCC
|
||||
*
|
||||
* @return array
|
||||
* @throws \ncc\Exceptions\RuntimeException
|
||||
*/
|
||||
function ncc_constants(): array
|
||||
{
|
||||
return ncc::getConstants();
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('consts_get'))
|
||||
{
|
||||
/**
|
||||
* Returns the value of a constant defined in NCC's runtime environment
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @return string|null
|
||||
*/
|
||||
function consts_get(string $package, string $name): ?string
|
||||
{
|
||||
return Runtime\Constants::get($package, $name);
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('consts_set'))
|
||||
{
|
||||
/**
|
||||
* Sets the value of a constant defined in NCC's runtime environment
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $readonly
|
||||
* @return void
|
||||
* @throws ConstantReadonlyException
|
||||
* @throws InvalidConstantNameException
|
||||
*/
|
||||
function consts_set(string $package, string $name, string $value, bool $readonly=false): void
|
||||
{
|
||||
Runtime\Constants::register($package, $name, $value, $readonly);
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('consts_delete'))
|
||||
{
|
||||
/**
|
||||
* Deletes a constant defined in NCC's runtime environment
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @return void
|
||||
* @throws ConstantReadonlyException
|
||||
*/
|
||||
function consts_delete(string $package, string $name): void
|
||||
{
|
||||
Runtime\Constants::delete($package, $name);
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('get_data_path'))
|
||||
{
|
||||
/**
|
||||
* Returns the data path of the package
|
||||
*
|
||||
* @param string $package
|
||||
* @return string
|
||||
* @throws InvalidPackageNameException
|
||||
* @throws InvalidScopeException
|
||||
* @throws PackageLockException
|
||||
* @throws PackageNotFoundException
|
||||
*/
|
||||
function get_data_path(string $package): string
|
||||
{
|
||||
return Runtime::getDataPath($package);
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('get_constant'))
|
||||
{
|
||||
/**
|
||||
* Returns the value of a constant defined in NCC's runtime environment
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @return string|null
|
||||
*/
|
||||
function get_constant(string $package, string $name): ?string
|
||||
{
|
||||
return Runtime::getConstant($package, $name);
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('set_constant'))
|
||||
{
|
||||
/**
|
||||
* Sets the value of a constant defined in NCC's runtime environment
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return void
|
||||
* @throws ConstantReadonlyException
|
||||
* @throws InvalidConstantNameException
|
||||
*/
|
||||
function set_constant(string $package, string $name, string $value): void
|
||||
{
|
||||
Runtime::setConstant($package, $name, $value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,9 +12,7 @@
|
|||
// Start script
|
||||
function scanContents($dir, &$results = array())
|
||||
{
|
||||
$files = scandir($dir);
|
||||
|
||||
foreach ($files as $key => $value)
|
||||
foreach (scandir($dir, SCANDIR_SORT_NONE) as $key => $value)
|
||||
{
|
||||
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
|
||||
if (!is_dir($path))
|
||||
|
@ -49,6 +47,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin', \ncc\ZiProto\ZiProto::encode($hash_values));
|
||||
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin', \ncc\Extensions\ZiProto\ZiProto::encode($hash_values));
|
||||
ncc\Utilities\Console::out('Created checksum.bin');
|
||||
exit(0);
|
|
@ -31,7 +31,7 @@
|
|||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\Validate;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
# Global Variables
|
||||
$NCC_INSTALL_PATH=DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'ncc';
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\CLI\Commands;
|
||||
namespace ncc\CLI\Commands;
|
||||
|
||||
use Exception;
|
||||
use ncc\Managers\ExecutionPointerManager;
|
||||
use ncc\Managers\PackageLockManager;
|
||||
use ncc\Classes\Runtime;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
|
@ -41,8 +40,6 @@ namespace ncc\CLI\Commands;
|
|||
{
|
||||
$package = $args['package'] ?? null;
|
||||
$version = $args['exec-version'] ?? 'latest';
|
||||
$unit_name = $args['exec-unit'] ?? 'main';
|
||||
$set_args = $args['exec-args'] ?? null;
|
||||
|
||||
if($package == null)
|
||||
{
|
||||
|
@ -50,67 +47,23 @@ namespace ncc\CLI\Commands;
|
|||
exit(0);
|
||||
}
|
||||
|
||||
$package_lock_manager = new PackageLockManager();
|
||||
$execution_pointer_manager = new ExecutionPointerManager();
|
||||
|
||||
try
|
||||
{
|
||||
$package_entry = $package_lock_manager->getPackageLock()->getPackage($package);
|
||||
$package_name = Runtime::import($package, $version);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException('Package ' . $package . ' is not installed', $e, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if($package_entry === null)
|
||||
{
|
||||
Console::outError('Package ' . $package . ' is not installed', true, 1);
|
||||
Console::outException('Cannot import package ' . $package, $e, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$version_entry = $package_entry->getVersion($version, true);
|
||||
exit(Runtime::execute($package_name));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException('Version ' . $version . ' is not installed', $e, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$units = $execution_pointer_manager->getUnits($package_entry->getName(), $version_entry->getVersion());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException(sprintf('Cannot load execution units for package \'%s\'', $package), $e, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!in_array($unit_name, $units))
|
||||
{
|
||||
Console::outError(sprintf('Unit \'%s\' is not configured for package \'%s\'', $unit_name, $package), true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$options = [];
|
||||
|
||||
if($set_args != null)
|
||||
{
|
||||
global $argv;
|
||||
$args_index = array_search('--exec-args', $argv);
|
||||
$options = array_slice($argv, $args_index + 1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
exit($execution_pointer_manager->executeUnit($package_entry->getName(), $version_entry->getVersion(), $unit_name, $options));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException(sprintf('Cannot execute execution point \'%s\' in package \'%s\'', $unit_name, $package), $e, 1);
|
||||
Console::outException($e->getMessage(), $e, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +79,6 @@ namespace ncc\CLI\Commands;
|
|||
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
|
||||
new CliHelpSection(['exec', '--package'], '(Required) The package to execute'),
|
||||
new CliHelpSection(['--exec-version'], '(default: latest) The version of the package to execute'),
|
||||
new CliHelpSection(['--exec-unit'], '(default: main) The unit point of the package to execute'),
|
||||
new CliHelpSection(['--exec-args'], '(optional) Anything past this point will be passed to the execution unit'),
|
||||
];
|
||||
|
||||
|
@ -144,7 +96,6 @@ namespace ncc\CLI\Commands;
|
|||
Console::out(PHP_EOL . 'Example Usage:' . PHP_EOL);
|
||||
Console::out(' ncc exec --package com.example.program');
|
||||
Console::out(' ncc exec --package com.example.program --exec-version 1.0.0');
|
||||
Console::out(' ncc exec --package com.example.program --exec-version 1.0.0 --exec-unit setup');
|
||||
Console::out(' ncc exec --package com.example.program --exec-args --foo --bar --extra=test');
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
use ncc\Enums\Scopes;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Managers\CredentialManager;
|
||||
use ncc\Managers\PackageManager;
|
||||
use ncc\Managers\PackageManagerOld;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
|
@ -277,7 +277,7 @@
|
|||
*/
|
||||
private static function getInstallPackages($args): void
|
||||
{
|
||||
$package_manager = new PackageManager();
|
||||
$package_manager = new PackageManagerOld();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -339,7 +339,7 @@
|
|||
private static function installPackage($args): void
|
||||
{
|
||||
$package = ($args['package'] ?? $args['p']);
|
||||
$package_manager = new PackageManager();
|
||||
$package_manager = new PackageManagerOld();
|
||||
|
||||
if(Resolver::resolveScope() !== Scopes::SYSTEM)
|
||||
{
|
||||
|
@ -618,7 +618,7 @@
|
|||
Console::outError('Missing argument \'package\'', true, 1);
|
||||
}
|
||||
|
||||
$package_manager = new PackageManager();
|
||||
$package_manager = new PackageManagerOld();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -707,7 +707,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
$package_manager = new PackageManager();
|
||||
$package_manager = new PackageManagerOld();
|
||||
|
||||
foreach($package_manager->getInstalledPackages() as $package => $versions)
|
||||
{
|
||||
|
|
|
@ -1,59 +1,72 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\BashExtension;
|
||||
namespace ncc\Classes\BashExtension;
|
||||
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use ncc\Classes\ExecutionUnitRunner;
|
||||
use ncc\Enums\Runners;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\OperationException;
|
||||
use ncc\Interfaces\RunnerInterface;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
|
||||
class BashRunner implements RunnerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws PathNotFoundException
|
||||
* @throws IOException
|
||||
* @throws OperationException
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
|
||||
{
|
||||
if(!file_exists($path) && !is_file($path))
|
||||
$tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.bash';
|
||||
IO::fwrite($tmp, $unit->getData(), 0777);
|
||||
|
||||
try
|
||||
{
|
||||
throw new PathNotFoundException($path);
|
||||
$process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
|
||||
$process->run(static function($type, $buffer) use ($unit)
|
||||
{
|
||||
if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
|
||||
{
|
||||
print($buffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new OperationException(sprintf('There was an error executing the bash execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
unlink($tmp);
|
||||
}
|
||||
|
||||
$execution_unit = new ExecutionUnit();
|
||||
$execution_unit->setExecutionPolicy($policy);
|
||||
$execution_unit->setData(IO::fread($path));
|
||||
|
||||
return $execution_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getFileExtension(): string
|
||||
{
|
||||
return '.bash';
|
||||
return $process->getExitCode();
|
||||
}
|
||||
}
|
151
src/ncc/Classes/ExecutionUnitRunner.php
Normal file
151
src/ncc/Classes/ExecutionUnitRunner.php
Normal file
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes;
|
||||
|
||||
use Exception;
|
||||
use ncc\Classes\BashExtension\BashRunner;
|
||||
use ncc\Classes\NccExtension\ConstantCompiler;
|
||||
use ncc\Classes\PhpExtension\PhpRunner;
|
||||
use ncc\Enums\Runners;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\OperationException;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
|
||||
use ncc\ThirdParty\Symfony\Process\Process;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class ExecutionUnitRunner
|
||||
{
|
||||
/**
|
||||
* Constructs and returns a process object based off the Execution Unit
|
||||
*
|
||||
* @param ExecutionUnit $unit
|
||||
* @param array $args
|
||||
* @return Process
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
public static function constructProcess(ExecutionUnit $unit, array $args=[]): Process
|
||||
{
|
||||
$bin = match($unit->getExecutionPolicy()->getRunner())
|
||||
{
|
||||
Runners::PHP => (new ExecutableFinder())->find('php'),
|
||||
Runners::BASH => (new ExecutableFinder())->find('bash'),
|
||||
Runners::PYTHON => (new ExecutableFinder())->find('python'),
|
||||
Runners::LUA => (new ExecutableFinder())->find('lua'),
|
||||
Runners::PERL => (new ExecutableFinder())->find('perl'),
|
||||
|
||||
default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $unit->getExecutionPolicy()->getName(), $unit->getExecutionPolicy()->getRunner()))
|
||||
};
|
||||
|
||||
$process = new Process(array_merge([$bin], $args, $unit->getExecutionPolicy()->getExecute()->getOptions()));
|
||||
$process->setWorkingDirectory(ConstantCompiler::compileRuntimeConstants($unit->getExecutionPolicy()->getExecute()->getWorkingDirectory()));
|
||||
$process->setEnv($unit->getExecutionPolicy()->getExecute()->getEnvironmentVariables());
|
||||
|
||||
if($unit->getExecutionPolicy()->getExecute()->isTty())
|
||||
{
|
||||
$process->setTty(true);
|
||||
}
|
||||
|
||||
if($unit->getExecutionPolicy()->getExecute()->getTimeout() !== null)
|
||||
{
|
||||
$process->setTimeout($unit->getExecutionPolicy()->getExecute()->getTimeout());
|
||||
}
|
||||
|
||||
if($unit->getExecutionPolicy()->getExecute()->getIdleTimeout() !== null)
|
||||
{
|
||||
$process->setIdleTimeout($unit->getExecutionPolicy()->getExecute()->getIdleTimeout());
|
||||
}
|
||||
|
||||
return $process;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a ExecutionUnit locally on the system
|
||||
*
|
||||
* @param string $package_path
|
||||
* @param string $policy_name
|
||||
* @param array $args
|
||||
* @return int
|
||||
* @throws IOException
|
||||
* @throws OperationException
|
||||
*/
|
||||
public static function executeFromSystem(string $package_path, string $policy_name, array $args=[]): int
|
||||
{
|
||||
$unit_path = $package_path . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $policy_name . '.unit';
|
||||
|
||||
if(!is_file($unit_path))
|
||||
{
|
||||
throw new IOException(sprintf('The execution policy %s does not exist in the package %s (%s)', $policy_name, $package_path, $unit_path));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$execution_unit = ExecutionUnit::fromArray(ZiProto::decode(IO::fread($unit_path)));
|
||||
return match ($execution_unit->getExecutionPolicy()->getRunner())
|
||||
{
|
||||
Runners::PHP => PhpRunner::executeUnit($execution_unit, $args),
|
||||
Runners::BASH => BashRunner::executeUnit($execution_unit, $args),
|
||||
default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())),
|
||||
};
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new OperationException(sprintf('There was an error executing the execution policy %s: %s', $policy_name, $e->getMessage()), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the execution policy directly from a package (if supported)
|
||||
*
|
||||
* @param PackageReader $package_reader
|
||||
* @param string $policy_name
|
||||
* @param array $args
|
||||
* @return int
|
||||
* @throws ConfigurationException
|
||||
* @throws OperationException
|
||||
*/
|
||||
public static function executeFromPackage(PackageReader $package_reader, string $policy_name, array $args=[]): int
|
||||
{
|
||||
$execution_unit = $package_reader->getExecutionUnit($policy_name);
|
||||
|
||||
try
|
||||
{
|
||||
return match ($execution_unit->getExecutionPolicy()->getRunner())
|
||||
{
|
||||
Runners::PHP => PhpRunner::executeUnit($execution_unit, $args, false),
|
||||
Runners::BASH => BashRunner::executeUnit($execution_unit, $args),
|
||||
default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())),
|
||||
};
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new OperationException(sprintf('There was an error executing the execution policy from a package %s: %s', $policy_name, $e->getMessage()), $e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,54 +1,74 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\LuaExtension;
|
||||
namespace ncc\Classes\LuaExtension;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use ncc\Classes\ExecutionUnitRunner;
|
||||
use ncc\Enums\Runners;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\OperationException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\RunnerInterface;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
|
||||
class LuaRunner implements RunnerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws PathNotFoundException
|
||||
* @throws OperationException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
|
||||
{
|
||||
$execution_unit = new ExecutionUnit();
|
||||
$execution_unit->setExecutionPolicy($policy);
|
||||
$execution_unit->setData(IO::fread($path));
|
||||
$tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.lua';
|
||||
IO::fwrite($tmp, $unit->getData(), 0777);
|
||||
|
||||
return $execution_unit;
|
||||
}
|
||||
try
|
||||
{
|
||||
$process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
|
||||
$process->run(static function($type, $buffer) use ($unit)
|
||||
{
|
||||
if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
|
||||
{
|
||||
print($buffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new OperationException(sprintf('There was an error executing the lua execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
unlink($tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getFileExtension(): string
|
||||
{
|
||||
return '.lua';
|
||||
return $process->getExitCode();
|
||||
}
|
||||
}
|
|
@ -28,22 +28,25 @@
|
|||
use ncc\Classes\PackageWriter;
|
||||
use ncc\CLI\Main;
|
||||
use ncc\Enums\ComponentDataType;
|
||||
use ncc\Enums\Flags\PackageFlags;
|
||||
use ncc\Enums\LogLevel;
|
||||
use ncc\Enums\Options\BuildConfigurationOptions;
|
||||
use ncc\Enums\Options\BuildConfigurationValues;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\CompilerInterface;
|
||||
use ncc\Managers\ProjectManager;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\Package\Resource;
|
||||
use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
|
||||
use ncc\Utilities\Base64;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\Resolver;
|
||||
|
||||
class NccCompiler
|
||||
class NccCompiler implements CompilerInterface
|
||||
{
|
||||
/**
|
||||
* @var ProjectManager
|
||||
|
@ -59,18 +62,35 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the project manager
|
||||
*
|
||||
* @return ProjectManager
|
||||
*/
|
||||
public function getProjectManager(): ProjectManager
|
||||
{
|
||||
return $this->project_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param string $build_configuration
|
||||
* @return string
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws NotSupportedException
|
||||
* @throws PathNotFoundException
|
||||
* @noinspection UnusedFunctionResultInspection
|
||||
*/
|
||||
public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string
|
||||
{
|
||||
$configuration = $this->project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
|
||||
$package_path = $configuration->getOutputPath() . DIRECTORY_SEPARATOR . $this->project_manager->getProjectConfiguration()->getAssembly()->getPackage() . '.ncc';
|
||||
$package_writer = new PackageWriter($package_path);
|
||||
$progress = 0;
|
||||
$steps =
|
||||
count($this->project_manager->getProjectConfiguration()->getExecutionPolicies()) +
|
||||
count($this->project_manager->getComponents($build_configuration)) +
|
||||
count($this->project_manager->getResources($build_configuration));
|
||||
$package_writer = $this->createPackageWriter($package_path, $configuration);
|
||||
|
||||
Console::out(sprintf('Building project \'%s\'', $this->project_manager->getProjectConfiguration()->getAssembly()->getName()));
|
||||
|
||||
|
@ -89,7 +109,7 @@
|
|||
}
|
||||
|
||||
Console::outVerbose('Building package header...');
|
||||
$package_writer->setMetadata($this->buildMetadata($build_configuration));
|
||||
$this->processMetadata($package_writer, $build_configuration);
|
||||
|
||||
Console::outVerbose('Adding assembly information...');
|
||||
$package_writer->setAssembly($this->project_manager->getProjectConfiguration()->getAssembly());
|
||||
|
@ -104,16 +124,20 @@
|
|||
// Process execution policies
|
||||
if(count($this->project_manager->getProjectConfiguration()->getExecutionPolicies()) > 0)
|
||||
{
|
||||
Console::out('Processing execution policies...');
|
||||
Console::outVerbose('Processing execution policies...');
|
||||
$execution_units = $this->project_manager->getExecutionUnits($build_configuration);
|
||||
|
||||
if(count($execution_units) === 0)
|
||||
{
|
||||
$progress = count($this->project_manager->getProjectConfiguration()->getExecutionPolicies());
|
||||
Console::inlineProgressBar($progress, $steps);
|
||||
Console::outWarning('The project contains execution policies but none of them are used');
|
||||
}
|
||||
|
||||
foreach($execution_units as $unit)
|
||||
{
|
||||
$progress++;
|
||||
Console::inlineProgressBar($progress, $steps);
|
||||
$package_writer->addExecutionUnit($unit);
|
||||
}
|
||||
}
|
||||
|
@ -121,68 +145,119 @@
|
|||
// Compile package components
|
||||
foreach($this->project_manager->getComponents($build_configuration) as $component)
|
||||
{
|
||||
$progress++;
|
||||
Console::inlineProgressBar($progress, $steps);
|
||||
Console::outVerbose(sprintf('Compiling \'%s\'', $component));
|
||||
$package_writer->addComponent($this->buildComponent($component));
|
||||
|
||||
$this->processComponent($package_writer, $component);
|
||||
}
|
||||
|
||||
// Compile package resources
|
||||
foreach($this->project_manager->getResources($build_configuration) as $resource)
|
||||
{
|
||||
$progress++;
|
||||
Console::inlineProgressBar($progress, $steps);
|
||||
Console::outVerbose(sprintf('Processing \'%s\'', $resource));
|
||||
$package_writer->addResource($this->buildResource($resource));
|
||||
|
||||
$this->processResource($package_writer, $resource);
|
||||
}
|
||||
|
||||
$package_writer->close();
|
||||
return $package_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a package writer with the specified options
|
||||
*
|
||||
* @param string $path
|
||||
* @param BuildConfiguration $build_configuration
|
||||
* @return PackageWriter
|
||||
* @throws IOException
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
private function createPackageWriter(string $path, BuildConfiguration $build_configuration): PackageWriter
|
||||
{
|
||||
$package_writer = new PackageWriter($path);
|
||||
|
||||
if(isset($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]))
|
||||
{
|
||||
$package_writer->addFlag(PackageFlags::COMPRESSION);
|
||||
switch(strtolower($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]))
|
||||
{
|
||||
case BuildConfigurationOptions\CompressionOptions::HIGH:
|
||||
$package_writer->addFlag(PackageFlags::HIGH_COMPRESSION);
|
||||
break;
|
||||
|
||||
case BuildConfigurationOptions\CompressionOptions::MEDIUM:
|
||||
$package_writer->addFlag(PackageFlags::MEDIUM_COMPRESSION);
|
||||
break;
|
||||
|
||||
case BuildConfigurationOptions\CompressionOptions::LOW:
|
||||
$package_writer->addFlag(PackageFlags::LOW_COMPRESSION);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(sprintf('The compression level \'%s\' is not supported', $build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]));
|
||||
}
|
||||
}
|
||||
|
||||
return $package_writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a single component as a base64 encoded string
|
||||
*
|
||||
* @param PackageWriter $package_writer
|
||||
* @param string $file_path
|
||||
* @return Package\Component
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* @noinspection UnusedFunctionResultInspection
|
||||
*/
|
||||
public function buildComponent(string $file_path): Package\Component
|
||||
public function processComponent(PackageWriter $package_writer, string $file_path): void
|
||||
{
|
||||
return new Package\Component(
|
||||
$package_writer->addComponent(new Package\Component(
|
||||
Functions::removeBasename($file_path),
|
||||
Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs a resource into the package
|
||||
*
|
||||
* @param PackageWriter $package_writer
|
||||
* @param string $file_path
|
||||
* @return Resource
|
||||
* @return void
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* @noinspection UnusedFunctionResultInspection
|
||||
*/
|
||||
public function buildResource(string $file_path): Package\Resource
|
||||
public function processResource(PackageWriter $package_writer, string $file_path): void
|
||||
{
|
||||
return new Package\Resource(
|
||||
basename($file_path), IO::fread($file_path)
|
||||
);
|
||||
$package_writer->addResource(new Package\Resource(
|
||||
Functions::removeBasename($file_path), IO::fread($file_path)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the package header
|
||||
* Processes the package metadata
|
||||
*
|
||||
* @param ProjectManager $project_manager
|
||||
* @param PackageWriter $package_writer
|
||||
* @param string $build_configuration
|
||||
* @return Package\Metadata
|
||||
* @return void
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @noinspection UnusedFunctionResultInspection
|
||||
*/
|
||||
public function buildMetadata(string $build_configuration=BuildConfigurationValues::DEFAULT): Package\Metadata
|
||||
public function processMetadata(PackageWriter $package_writer, string $build_configuration=BuildConfigurationValues::DEFAULT): void
|
||||
{
|
||||
$header = new Package\Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler());
|
||||
$metadata = new Package\Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler());
|
||||
|
||||
$header->setRuntimeConstants($this->project_manager->getRuntimeConstants($build_configuration));
|
||||
$header->setOptions($this->project_manager->getCompilerOptions($build_configuration));
|
||||
$header->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource());
|
||||
$header->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain());
|
||||
$header->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller());
|
||||
$metadata->setRuntimeConstants($this->project_manager->getRuntimeConstants($build_configuration));
|
||||
$metadata->setOptions($this->project_manager->getCompilerOptions($build_configuration));
|
||||
$metadata->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource());
|
||||
$metadata->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain());
|
||||
$metadata->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller());
|
||||
|
||||
return $header;
|
||||
$package_writer->setMetadata($metadata);
|
||||
}
|
||||
}
|
|
@ -25,14 +25,18 @@
|
|||
|
||||
namespace ncc\Classes;
|
||||
|
||||
use ncc\Enums\Flags\PackageFlags;
|
||||
use ncc\Enums\PackageDirectory;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Objects\Package\Component;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\Package\Metadata;
|
||||
use ncc\Objects\Package\Resource;
|
||||
use ncc\Objects\ProjectConfiguration\Assembly;
|
||||
use ncc\Objects\ProjectConfiguration\Dependency;
|
||||
use ncc\Objects\ProjectConfiguration\Installer;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use RuntimeException;
|
||||
use ncc\Enums\PackageStructure;
|
||||
|
||||
|
@ -53,6 +57,11 @@
|
|||
*/
|
||||
private $package_file;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* PackageReader constructor.
|
||||
*
|
||||
|
@ -72,18 +81,26 @@
|
|||
throw new IOException(sprintf('Failed to open file \'%s\'', $file_path));
|
||||
}
|
||||
|
||||
$magic_bytes = fread($this->package_file, 7);
|
||||
$header = '';
|
||||
$pre_header = '';
|
||||
$diameter_hit = false;
|
||||
$this->header_length = 7;
|
||||
|
||||
// Check for the magic bytes "ncc_pkg"
|
||||
if($magic_bytes !== 'ncc_pkg')
|
||||
// Dynamically calculate header length until "ncc_pkg" is found
|
||||
while (!feof($this->package_file))
|
||||
{
|
||||
throw new IOException(sprintf('File \'%s\' is not a valid package file (invalid magic bytes)', $file_path));
|
||||
$char = fread($this->package_file, 1);
|
||||
$pre_header .= $char;
|
||||
|
||||
if (str_ends_with($pre_header, 'ncc_pkg'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate header length including "ncc_pkg"
|
||||
$this->header_length = strlen($pre_header);
|
||||
|
||||
// Read everything after "ncc_pkg" up until the delimiter (0x1F 0x1F)
|
||||
$header = '';
|
||||
while(!feof($this->package_file))
|
||||
{
|
||||
$this->header_length++;
|
||||
|
@ -109,6 +126,7 @@
|
|||
}
|
||||
|
||||
$this->headers = ZiProto::decode($header);
|
||||
$this->cache = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,7 +181,7 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets a resource from the package
|
||||
* Returns a resource from the package by name
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
|
@ -177,9 +195,28 @@
|
|||
|
||||
$location = explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
|
||||
fseek($this->package_file, ($this->header_length + (int)$location[0]));
|
||||
|
||||
if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
|
||||
{
|
||||
return gzuncompress(fread($this->package_file, (int)$location[1]));
|
||||
}
|
||||
|
||||
return fread($this->package_file, (int)$location[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a resource from the package by pointer
|
||||
*
|
||||
* @param int $pointer
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public function getByPointer(int $pointer, int $length): string
|
||||
{
|
||||
fseek($this->package_file, ($this->header_length + $pointer));
|
||||
return fread($this->package_file, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the package's assembly
|
||||
*
|
||||
|
@ -188,12 +225,21 @@
|
|||
*/
|
||||
public function getAssembly(): Assembly
|
||||
{
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY]['@assembly']))
|
||||
$directory = sprintf('@%s', PackageDirectory::ASSEMBLY);
|
||||
|
||||
if(isset($this->cache[$directory]))
|
||||
{
|
||||
return $this->cache[$directory];
|
||||
}
|
||||
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
|
||||
{
|
||||
throw new ConfigurationException('Package does not contain an assembly');
|
||||
}
|
||||
|
||||
return Assembly::fromArray(ZiProto::decode($this->get('@assembly')));
|
||||
$assembly = Assembly::fromArray(ZiProto::decode($this->get($directory)));
|
||||
$this->cache[$directory] = $assembly;
|
||||
return $assembly;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,12 +250,21 @@
|
|||
*/
|
||||
public function getMetadata(): Metadata
|
||||
{
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY]['@metadata']))
|
||||
$directory = sprintf('@%s', PackageDirectory::METADATA);
|
||||
|
||||
if(isset($this->cache[$directory]))
|
||||
{
|
||||
return $this->cache[$directory];
|
||||
}
|
||||
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
|
||||
{
|
||||
throw new ConfigurationException('Package does not contain metadata');
|
||||
}
|
||||
|
||||
return Metadata::fromArray(ZiProto::decode($this->get('@metadata')));
|
||||
$metadata = Metadata::fromArray(ZiProto::decode($this->get($directory)));
|
||||
$this->cache[$directory] = $metadata;
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,12 +274,21 @@
|
|||
*/
|
||||
public function getInstaller(): ?Installer
|
||||
{
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY]['@installer']))
|
||||
$directory = sprintf('@%s', PackageDirectory::INSTALLER);
|
||||
|
||||
if(isset($this->cache[$directory]))
|
||||
{
|
||||
return $this->cache[$directory];
|
||||
}
|
||||
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Installer::fromArray(ZiProto::decode($this->get('@installer')));
|
||||
$installer = Installer::fromArray(ZiProto::decode($this->get($directory)));
|
||||
$this->cache[$directory] = $installer;
|
||||
return $installer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -235,11 +299,13 @@
|
|||
public function getDependencies(): array
|
||||
{
|
||||
$dependencies = [];
|
||||
$directory = sprintf('@%s:', PackageDirectory::DEPENDENCIES);
|
||||
|
||||
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
|
||||
{
|
||||
if(str_starts_with($name, '@dependencies:'))
|
||||
if(str_starts_with($name, $directory))
|
||||
{
|
||||
$dependencies[] = str_replace('@dependencies:', '', $name);
|
||||
$dependencies[] = str_replace($directory, '', $name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,18 +316,31 @@
|
|||
* Returns a dependency from the package
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
* @return Dependency
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getDependency(string $name): array
|
||||
public function getDependency(string $name): Dependency
|
||||
{
|
||||
$dependency_name = sprintf('@dependencies:%s', $name);
|
||||
$dependency_name = sprintf('@%s:%s', PackageDirectory::DEPENDENCIES, $name);
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$dependency_name]))
|
||||
{
|
||||
throw new ConfigurationException(sprintf('Dependency \'%s\' not found in package', $name));
|
||||
}
|
||||
|
||||
return ZiProto::decode($this->get('@dependencies:' . $name));
|
||||
return Dependency::fromArray(ZiProto::decode($this->get($dependency_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dependency from the package by pointer
|
||||
*
|
||||
* @param int $pointer
|
||||
* @param int $length
|
||||
* @return Dependency
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getDependencyByPointer(int $pointer, int $length): Dependency
|
||||
{
|
||||
return Dependency::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,11 +351,13 @@
|
|||
public function getExecutionUnits(): array
|
||||
{
|
||||
$execution_units = [];
|
||||
$directory = sprintf('@%s:', PackageDirectory::EXECUTION_UNITS);
|
||||
|
||||
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
|
||||
{
|
||||
if(str_starts_with($name, '@execution_units:'))
|
||||
if(str_starts_with($name, $directory))
|
||||
{
|
||||
$execution_units[] = str_replace('@execution_units:', '', $name);
|
||||
$execution_units[] = str_replace($directory, '', $name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,7 +373,7 @@
|
|||
*/
|
||||
public function getExecutionUnit(string $name): ExecutionUnit
|
||||
{
|
||||
$execution_unit_name = sprintf('@execution_units:%s', $name);
|
||||
$execution_unit_name = sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS, $name);
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$execution_unit_name]))
|
||||
{
|
||||
throw new ConfigurationException(sprintf('Execution unit \'%s\' not found in package', $name));
|
||||
|
@ -302,24 +383,55 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the package's components
|
||||
* Returns an execution unit from the package by pointer
|
||||
*
|
||||
* @param int $pointer
|
||||
* @param int $length
|
||||
* @return ExecutionUnit
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getExecutionUnitByPointer(int $pointer, int $length): ExecutionUnit
|
||||
{
|
||||
return ExecutionUnit::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the package's component pointers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getComponents(): array
|
||||
{
|
||||
$components = [];
|
||||
$directory = sprintf('@%s:', PackageDirectory::COMPONENTS);
|
||||
|
||||
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
|
||||
{
|
||||
if(str_starts_with($name, '@components:'))
|
||||
if(str_starts_with($name, $directory))
|
||||
{
|
||||
$components[] = str_replace('@components:', '', $name);
|
||||
$components[] = str_replace($directory, '', $name);
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
public function getClassMap(): array
|
||||
{
|
||||
$class_map = [];
|
||||
$directory = sprintf('@%s:', PackageDirectory::CLASS_POINTER);
|
||||
|
||||
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
|
||||
{
|
||||
if(str_starts_with($name, $directory))
|
||||
{
|
||||
$class_map[] = str_replace($directory, '', $name);
|
||||
}
|
||||
}
|
||||
|
||||
return $class_map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a component from the package
|
||||
*
|
||||
|
@ -329,28 +441,61 @@
|
|||
*/
|
||||
public function getComponent(string $name): Component
|
||||
{
|
||||
$component_name = sprintf('@components:%s', $name);
|
||||
$component_name = sprintf('@%s:%s', PackageDirectory::COMPONENTS, $name);
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$component_name]))
|
||||
{
|
||||
throw new ConfigurationException(sprintf('Component \'%s\' not found in package', $name));
|
||||
}
|
||||
|
||||
return Component::fromArray(ZiProto::decode($this->get('@components:' . $name)));
|
||||
return Component::fromArray(ZiProto::decode($this->get($component_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of resources from the package
|
||||
* Returns a component from the package by pointer
|
||||
*
|
||||
* @param int $pointer
|
||||
* @param int $length
|
||||
* @return Component
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getComponentByPointer(int $pointer, int $length): Component
|
||||
{
|
||||
return Component::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a component from the package by a class pointer
|
||||
*
|
||||
* @param string $class
|
||||
* @return Component
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getComponentByClass(string $class): Component
|
||||
{
|
||||
$class_name = sprintf('@%s:%s', PackageDirectory::CLASS_POINTER, $class);
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$class_name]))
|
||||
{
|
||||
throw new ConfigurationException(sprintf('Class map \'%s\' not found in package', $class));
|
||||
}
|
||||
|
||||
return Component::fromArray(ZiProto::decode($this->get($class_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of resource pointers from the package
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getResources(): array
|
||||
{
|
||||
$resources = [];
|
||||
$directory = sprintf('@%s:', PackageDirectory::RESOURCES);
|
||||
|
||||
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
|
||||
{
|
||||
if(str_starts_with($name, '@resources:'))
|
||||
if(str_starts_with($name, $directory))
|
||||
{
|
||||
$resources[] = str_replace('@resources:', '', $name);
|
||||
$resources[] = str_replace($directory, '', $name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,18 +506,31 @@
|
|||
* Returns a resource from the package
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
* @return Resource
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getResource(string $name): string
|
||||
public function getResource(string $name): Resource
|
||||
{
|
||||
$resource_name = sprintf('@resources:%s', $name);
|
||||
$resource_name = sprintf('@%s:%s', PackageDirectory::RESOURCES, $name);
|
||||
if(!isset($this->headers[PackageStructure::DIRECTORY][$resource_name]))
|
||||
{
|
||||
throw new ConfigurationException(sprintf('Resource \'%s\' not found in package', $name));
|
||||
}
|
||||
|
||||
return $this->get('@resources:' . $name);
|
||||
return Resource::fromArray(ZiProto::decode($this->get($resource_name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a resource from the package by pointer
|
||||
*
|
||||
* @param int $pointer
|
||||
* @param int $length
|
||||
* @return Resource
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function getResourceByPointer(int $pointer, int $length): Resource
|
||||
{
|
||||
return Resource::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
namespace ncc\Classes;
|
||||
|
||||
use ncc\Enums\Flags\PackageFlags;
|
||||
use ncc\Enums\PackageDirectory;
|
||||
use ncc\Enums\PackageStructure;
|
||||
use ncc\Enums\PackageStructureVersions;
|
||||
use ncc\Exceptions\IOException;
|
||||
|
@ -35,7 +37,7 @@
|
|||
use ncc\Objects\ProjectConfiguration\Assembly;
|
||||
use ncc\Objects\ProjectConfiguration\Dependency;
|
||||
use ncc\Objects\ProjectConfiguration\Installer;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class PackageWriter
|
||||
{
|
||||
|
@ -59,6 +61,11 @@
|
|||
*/
|
||||
private $temporary_path;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $data_written;
|
||||
|
||||
/**
|
||||
* PackageWriter constructor.
|
||||
*
|
||||
|
@ -94,6 +101,7 @@
|
|||
touch($file_path);
|
||||
touch($file_path . '.tmp');
|
||||
|
||||
$this->data_written = false;
|
||||
$this->temporary_path = $file_path . '.tmp';
|
||||
$this->temp_file = @fopen($this->temporary_path, 'wb'); // Create a temporary data file
|
||||
$this->package_file = @fopen($file_path, 'wb');
|
||||
|
@ -148,6 +156,11 @@
|
|||
*/
|
||||
public function setFlags(array $flags): void
|
||||
{
|
||||
if($this->data_written)
|
||||
{
|
||||
throw new IOException('Cannot set flags after data has been written to the package');
|
||||
}
|
||||
|
||||
$this->headers[PackageStructure::FLAGS] = $flags;
|
||||
}
|
||||
|
||||
|
@ -156,9 +169,15 @@
|
|||
*
|
||||
* @param string $flag
|
||||
* @return void
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addFlag(string $flag): void
|
||||
{
|
||||
if($this->data_written)
|
||||
{
|
||||
throw new IOException('Cannot add a flag after data has been written to the package');
|
||||
}
|
||||
|
||||
if(!in_array($flag, $this->headers[PackageStructure::FLAGS], true))
|
||||
{
|
||||
$this->headers[PackageStructure::FLAGS][] = $flag;
|
||||
|
@ -173,6 +192,11 @@
|
|||
*/
|
||||
public function removeFlag(string $flag): void
|
||||
{
|
||||
if($this->data_written)
|
||||
{
|
||||
throw new IOException('Cannot remove a flag after data has been written to the package');
|
||||
}
|
||||
|
||||
$this->headers[PackageStructure::FLAGS] = array_diff($this->headers[PackageStructure::FLAGS], [$flag]);
|
||||
}
|
||||
|
||||
|
@ -181,102 +205,159 @@
|
|||
*
|
||||
* @param string $name
|
||||
* @param string $data
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function add(string $name, string $data): void
|
||||
public function add(string $name, string $data): array
|
||||
{
|
||||
if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
|
||||
{
|
||||
throw new IOException(sprintf('Resource \'%s\' already exists in package', $name));
|
||||
}
|
||||
|
||||
$this->headers[PackageStructure::DIRECTORY][$name] = sprintf("%d:%d", ftell($this->temp_file), strlen($data));
|
||||
if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
|
||||
{
|
||||
if(in_array(PackageFlags::LOW_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
|
||||
{
|
||||
$data = gzcompress($data, 1);
|
||||
}
|
||||
else if(in_array(PackageFlags::MEDIUM_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
|
||||
{
|
||||
$data = gzcompress($data, 6);
|
||||
}
|
||||
else if(in_array(PackageFlags::HIGH_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
|
||||
{
|
||||
$data = gzcompress($data, 9);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = gzcompress($data);
|
||||
}
|
||||
}
|
||||
|
||||
$pointer = sprintf("%d:%d", ftell($this->temp_file), strlen($data));
|
||||
$this->headers[PackageStructure::DIRECTORY][$name] = $pointer;
|
||||
$this->data_written = true;
|
||||
fwrite($this->temp_file, $data);
|
||||
|
||||
return explode(':', $pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pointer to the package
|
||||
*
|
||||
* @param string $name
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
* @return void
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addPointer(string $name, int $offset, int $length): void
|
||||
{
|
||||
if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
|
||||
{
|
||||
throw new IOException(sprintf('Resource \'%s\' already exists in package', $name));
|
||||
}
|
||||
|
||||
$this->headers[PackageStructure::DIRECTORY][$name] = sprintf("%d:%d", $offset, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the assembly of the package
|
||||
*
|
||||
* @param Assembly $assembly
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function setAssembly(Assembly $assembly): void
|
||||
public function setAssembly(Assembly $assembly): array
|
||||
{
|
||||
$this->add('@assembly', ZiProto::encode($assembly->toArray()));
|
||||
return $this->add(sprintf('@%s', PackageDirectory::ASSEMBLY), ZiProto::encode($assembly->toArray(true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the metadata to the package
|
||||
*
|
||||
* @param Metadata $metadata
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function setMetadata(Metadata $metadata): void
|
||||
public function setMetadata(Metadata $metadata): array
|
||||
{
|
||||
$this->add('@metadata', ZiProto::encode($metadata->toArray()));
|
||||
return $this->add(sprintf('@%s', PackageDirectory::METADATA), ZiProto::encode($metadata->toArray(true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the installer information of the package
|
||||
*
|
||||
* @param Installer $installer
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function setInstaller(Installer $installer): void
|
||||
public function setInstaller(Installer $installer): array
|
||||
{
|
||||
$this->add('@installer', ZiProto::encode($installer->toArray()));
|
||||
return $this->add(sprintf('@%s', PackageDirectory::INSTALLER), ZiProto::encode($installer->toArray(true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dependency configuration to the package
|
||||
*
|
||||
* @param Dependency $dependency
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addDependencyConfiguration(Dependency $dependency): void
|
||||
public function addDependencyConfiguration(Dependency $dependency): array
|
||||
{
|
||||
$this->add(sprintf('@dependencies:%s', $dependency->getName()), ZiProto::encode($dependency->toArray()));
|
||||
return $this->add(sprintf('@%s:%s', PackageDirectory::DEPENDENCIES, $dependency->getName()), ZiProto::encode($dependency->toArray(true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an execution unit to the package
|
||||
*
|
||||
* @param ExecutionUnit $unit
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addExecutionUnit(ExecutionUnit $unit): void
|
||||
public function addExecutionUnit(ExecutionUnit $unit): array
|
||||
{
|
||||
$this->add(sprintf('@execution_units:%s', $unit->getExecutionPolicy()->getName()), ZiProto::encode($unit->toArray()));
|
||||
return $this->add(sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS, $unit->getExecutionPolicy()->getName()), ZiProto::encode($unit->toArray(true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a component to the package
|
||||
*
|
||||
* @param Component $component
|
||||
* @return void
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addComponent(Component $component): void
|
||||
public function addComponent(Component $component): array
|
||||
{
|
||||
$this->add(sprintf('@components:%s', $component->getName()), ZiProto::encode($component->toArray()));
|
||||
return $this->add(sprintf('@%s:%s', PackageDirectory::COMPONENTS, $component->getName()), ZiProto::encode($component->toArray(true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a resource to the package
|
||||
*
|
||||
* @param Resource $resource
|
||||
* @return array
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addResource(Resource $resource): array
|
||||
{
|
||||
return $this->add(sprintf('@%s:%s', PackageDirectory::RESOURCES, $resource->getName()), $resource->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a class to a component in the package
|
||||
*
|
||||
* @param string $class
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
* @return void
|
||||
* @throws IOException
|
||||
*/
|
||||
public function addResource(Resource $resource): void
|
||||
public function mapClass(string $class, int $offset, int $length): void
|
||||
{
|
||||
$this->add(sprintf('@resources:%s', $resource->getName()), $resource->getData());
|
||||
$this->addPointer(sprintf('@%s:%s', PackageDirectory::CLASS_POINTER, $class), $offset, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,5 +408,17 @@
|
|||
{
|
||||
// Ignore
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(is_resource($this->package_file))
|
||||
{
|
||||
fclose($this->package_file);
|
||||
}
|
||||
|
||||
if(is_resource($this->temp_file))
|
||||
{
|
||||
fclose($this->temp_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,44 +22,51 @@
|
|||
|
||||
namespace ncc\Classes\PerlExtension;
|
||||
|
||||
use Exception;
|
||||
use ncc\Classes\ExecutionUnitRunner;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\OperationException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\RunnerInterface;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
|
||||
class PerlRunner implements RunnerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param string $path
|
||||
* @param ExecutionPolicy $policy
|
||||
* @return ExecutionUnit
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* @throws OperationException
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
|
||||
{
|
||||
$execution_unit = new ExecutionUnit();
|
||||
$tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.pl';
|
||||
IO::fwrite($tmp, $unit->getData(), 0777);
|
||||
|
||||
if(!file_exists($path) && !is_file($path))
|
||||
try
|
||||
{
|
||||
throw new PathNotFoundException($path);
|
||||
$process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
|
||||
$process->run(static function($type, $buffer) use ($unit)
|
||||
{
|
||||
if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
|
||||
{
|
||||
print($buffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new OperationException(sprintf('There was an error executing the perl execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
unlink($tmp);
|
||||
}
|
||||
|
||||
$execution_unit->setExecutionPolicy($policy);
|
||||
$execution_unit->setData(IO::fread($path));
|
||||
|
||||
return $execution_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getFileExtension(): string
|
||||
{
|
||||
return '.pl';
|
||||
return $process->getExitCode();
|
||||
}
|
||||
}
|
257
src/ncc/Classes/PhpExtension/AstWalker.php
Normal file
257
src/ncc/Classes/PhpExtension/AstWalker.php
Normal file
|
@ -0,0 +1,257 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PhpExtension;
|
||||
|
||||
use ncc\ThirdParty\nikic\PhpParser\Comment;
|
||||
use ncc\ThirdParty\nikic\PhpParser\Node;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use RuntimeException;
|
||||
|
||||
class AstWalker
|
||||
{
|
||||
/**
|
||||
* Returns an array representation of the node recursively
|
||||
*
|
||||
* @param array|Node $node
|
||||
* @return array
|
||||
*/
|
||||
public static function serialize(array|Node $node): array
|
||||
{
|
||||
if(is_array($node))
|
||||
{
|
||||
$serialized = [];
|
||||
foreach($node as $sub_node)
|
||||
{
|
||||
$serialized[] = $sub_node->jsonSerialize();
|
||||
}
|
||||
return $serialized;
|
||||
}
|
||||
|
||||
return $node->jsonSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of classes associated with the node recursively
|
||||
*
|
||||
* @param Node|array $node
|
||||
* @param string $prefix
|
||||
* @return array
|
||||
*/
|
||||
public static function extractClasses(Node|array $node, string $prefix=''): array
|
||||
{
|
||||
if(is_array($node))
|
||||
{
|
||||
$classes = [];
|
||||
foreach($node as $sub_node)
|
||||
{
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$classes = array_merge($classes, self::extractClasses($sub_node, $prefix));
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
|
||||
$classes = [];
|
||||
|
||||
if ($node instanceof Node\Stmt\ClassLike)
|
||||
{
|
||||
$classes[] = $prefix . $node->name;
|
||||
}
|
||||
|
||||
if ($node instanceof Node\Stmt\Namespace_)
|
||||
{
|
||||
if ($node->name && $node->name->parts)
|
||||
{
|
||||
$prefix .= implode('\\', $node->name->parts) . '\\';
|
||||
}
|
||||
else
|
||||
{
|
||||
$prefix = '';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($node->getSubNodeNames() as $node_name)
|
||||
{
|
||||
if ($node->$node_name instanceof Node)
|
||||
{
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$classes = array_merge($classes, self::extractClasses($node->$node_name, $prefix));
|
||||
}
|
||||
elseif (is_array($node->$node_name))
|
||||
{
|
||||
foreach ($node->$node_name as $sub_node)
|
||||
{
|
||||
if ($sub_node instanceof Node)
|
||||
{
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$classes = array_merge($classes, self::extractClasses($sub_node, $prefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs nodes from an array representation recursively
|
||||
*
|
||||
* @param $value
|
||||
* @return array|Comment|Node
|
||||
* @noinspection PhpMissingReturnTypeInspection
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public static function decodeRecursive($value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
if (isset($value['nodeType']))
|
||||
{
|
||||
if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc')
|
||||
{
|
||||
return self::decodeComment($value);
|
||||
}
|
||||
|
||||
return self::decodeNode($value);
|
||||
}
|
||||
|
||||
return self::decodeArray($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes an array by recursively decoding each value
|
||||
*
|
||||
* @param array $array
|
||||
* @return array
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private static function decodeArray(array $array) : array
|
||||
{
|
||||
$decoded_array = [];
|
||||
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
$decoded_array[$key] = self::decodeRecursive($value);
|
||||
}
|
||||
|
||||
return $decoded_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node from the node type
|
||||
*
|
||||
* @param array $value
|
||||
* @return Node
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private static function decodeNode(array $value) : Node
|
||||
{
|
||||
$node_type = $value['nodeType'];
|
||||
if (!is_string($node_type))
|
||||
{
|
||||
throw new RuntimeException('Node type must be a string');
|
||||
}
|
||||
|
||||
/** @var Node $node */
|
||||
$node = self::reflectionClassFromNodeType($node_type)->newInstanceWithoutConstructor();
|
||||
|
||||
if (isset($value['attributes'])) {
|
||||
if (!is_array($value['attributes']))
|
||||
{
|
||||
throw new RuntimeException('Attributes must be an array');
|
||||
}
|
||||
|
||||
$node->setAttributes(self::decodeArray($value['attributes']));
|
||||
}
|
||||
|
||||
foreach ($value as $name => $sub_node) {
|
||||
if ($name === 'nodeType' || $name === 'attributes')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->$name = self::decodeRecursive($sub_node);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the comment from the node type
|
||||
*
|
||||
* @param array $value
|
||||
* @return Comment
|
||||
*/
|
||||
private static function decodeComment(array $value): Comment
|
||||
{
|
||||
$class_name = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
|
||||
if (!isset($value['text']))
|
||||
{
|
||||
throw new RuntimeException('Comment must have text');
|
||||
}
|
||||
|
||||
return new $class_name(
|
||||
$value['text'],
|
||||
$value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
|
||||
$value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reflection class from the node type
|
||||
*
|
||||
* @param string $node_type
|
||||
* @return ReflectionClass
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private static function reflectionClassFromNodeType(string $node_type): ReflectionClass
|
||||
{
|
||||
return new ReflectionClass(self::classNameFromNodeType($node_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name from the node type
|
||||
*
|
||||
* @param string $nodeType
|
||||
* @return string
|
||||
*/
|
||||
private static function classNameFromNodeType(string $nodeType): string
|
||||
{
|
||||
$class_name = 'ncc\\ThirdParty\\nikic\\PhpParser\\Node\\' . str_replace('_', '\\', $nodeType);
|
||||
if (class_exists($class_name))
|
||||
{
|
||||
return $class_name;
|
||||
}
|
||||
|
||||
$class_name .= '_';
|
||||
if (class_exists($class_name))
|
||||
{
|
||||
return $class_name;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown node type \"$nodeType\"");
|
||||
}
|
||||
}
|
170
src/ncc/Classes/PhpExtension/ExecutableCompiler.php
Normal file
170
src/ncc/Classes/PhpExtension/ExecutableCompiler.php
Normal file
|
@ -0,0 +1,170 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PhpExtension;
|
||||
|
||||
use ncc\CLI\Main;
|
||||
use ncc\Enums\LogLevel;
|
||||
use ncc\Enums\Options\BuildConfigurationValues;
|
||||
use ncc\Exceptions\BuildException;
|
||||
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
|
||||
use ncc\ThirdParty\Symfony\Process\Process;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\PathFinder;
|
||||
|
||||
class ExecutableCompiler extends NccCompiler
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @throws BuildException
|
||||
*/
|
||||
public function build(string $build_configuration = BuildConfigurationValues::DEFAULT): string
|
||||
{
|
||||
$configuration = $this->getProjectManager()->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
|
||||
|
||||
if(!isset($configuration->getOptions()['ncc_configuration']))
|
||||
{
|
||||
throw new BuildException(sprintf("Unable to compile the binary, the build configuration '%s' does not have a ncc_configuration.", $build_configuration));
|
||||
}
|
||||
|
||||
// Build the ncc package first
|
||||
Console::outVerbose('Building ncc package.');
|
||||
$ncc_package = parent::build($configuration->getOptions()['ncc_configuration']);
|
||||
|
||||
// Prepare the ncc package for compilation
|
||||
$hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c';
|
||||
if(is_file($hex_dump_file))
|
||||
{
|
||||
unlink($hex_dump_file);
|
||||
}
|
||||
|
||||
Console::outVerbose(sprintf('Converting ncc package %s to hex dump', $ncc_package));
|
||||
$this->hexDump($ncc_package, $hex_dump_file, parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName());
|
||||
|
||||
// Prepare the gcc command
|
||||
$gcc_path = (new ExecutableFinder())->find('gcc');
|
||||
$binary_path = $configuration->getOutputPath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName();
|
||||
|
||||
if($gcc_path === null)
|
||||
{
|
||||
throw new BuildException("Unable to find gcc executable, please make sure it is installed and in your PATH environment variable.");
|
||||
}
|
||||
|
||||
if(!is_file(__DIR__ . DIRECTORY_SEPARATOR . 'bootstrap_main.c'))
|
||||
{
|
||||
throw new BuildException("Unable to find bootstrap_main.c, please make sure ncc is installed correctly.");
|
||||
}
|
||||
|
||||
$gcc_options = [
|
||||
__DIR__ . DIRECTORY_SEPARATOR . 'bootstrap_main.c',
|
||||
realpath($hex_dump_file)
|
||||
];
|
||||
|
||||
foreach($configuration->getOptions() as $option => $value)
|
||||
{
|
||||
if(str_starts_with($option, 'gcc-'))
|
||||
{
|
||||
$gcc_options[] = sprintf('-%s%s', substr($option, 4), $value === null ? '' : '=' . $value);
|
||||
}
|
||||
}
|
||||
|
||||
$gcc_options[] = '-o';
|
||||
$gcc_options[] = $binary_path;
|
||||
|
||||
switch(Main::getLogLevel())
|
||||
{
|
||||
case LogLevel::VERBOSE:
|
||||
$gcc_options[] = '-v';
|
||||
break;
|
||||
|
||||
case LogLevel::DEBUG:
|
||||
$gcc_options[] = '-v';
|
||||
$gcc_options[] = '-v';
|
||||
break;
|
||||
}
|
||||
|
||||
$process = new Process([$gcc_path, ...$gcc_options]);
|
||||
$process->setTimeout(0);
|
||||
|
||||
Console::outVerbose(sprintf('Compiling executable to %s: %s', $binary_path, implode(' ', $gcc_options)));
|
||||
$process->run(static function ($type, $buffer)
|
||||
{
|
||||
Console::outVerbose(rtrim($buffer, "\n"));
|
||||
});
|
||||
|
||||
if(!$process->isSuccessful())
|
||||
{
|
||||
unlink($hex_dump_file);
|
||||
throw new BuildException(sprintf("Unable to compile the binary, gcc exited with code %d: %s", $process->getExitCode(), $process->getErrorOutput()));
|
||||
}
|
||||
|
||||
// Finally, remove the hex dump file and return the executable path
|
||||
unlink($hex_dump_file);
|
||||
return $binary_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hex dump of the binary data and writes it to the output file suitable for inclusion in a C source
|
||||
* file, this is a similar utility to xxd.
|
||||
*
|
||||
* @param string $input_path
|
||||
* @param string $output_path
|
||||
* @param string $variable_name
|
||||
* @return void
|
||||
*/
|
||||
private function hexDump(string $input_path, string $output_path, string $variable_name): void
|
||||
{
|
||||
$input = fopen($input_path, 'rb');
|
||||
$output = fopen($output_path, 'wb');
|
||||
|
||||
fwrite($output, sprintf("unsigned char %s[] = {\n", Functions::toSnakeCase($variable_name)));
|
||||
$byte_count = 0;
|
||||
|
||||
// Convert the binary data to hex and write it to the output file
|
||||
while (!feof($input))
|
||||
{
|
||||
$byte = fread($input, 1);
|
||||
if (strlen($byte) === 1)
|
||||
{
|
||||
fwrite($output, sprintf(" 0x%02x,", ord($byte)));
|
||||
$byte_count++;
|
||||
}
|
||||
|
||||
// Write 12 bytes per line or when reaching the end of the file
|
||||
if ($byte_count === 12 || feof($input))
|
||||
{
|
||||
fwrite($output, "\n");
|
||||
$byte_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the output file
|
||||
fseek($output, -2, SEEK_END);
|
||||
fwrite($output, "\n");
|
||||
fwrite($output, "};\n");
|
||||
|
||||
// Finally, close the input and output files
|
||||
fclose($input);
|
||||
fclose($output);
|
||||
}
|
||||
}
|
|
@ -23,7 +23,9 @@
|
|||
namespace ncc\Classes\PhpExtension;
|
||||
|
||||
use Exception;
|
||||
use ncc\Classes\PackageWriter;
|
||||
use ncc\Enums\ComponentDataType;
|
||||
use ncc\Enums\Flags\ComponentFlags;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Objects\Package\Component;
|
||||
|
@ -32,34 +34,44 @@
|
|||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class NccCompiler extends \ncc\Classes\NccExtension\NccCompiler
|
||||
{
|
||||
/**
|
||||
* @param PackageWriter $package_writer
|
||||
* @param string $file_path
|
||||
* @return Component
|
||||
* @return void
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* @noinspection UnusedFunctionResultInspection
|
||||
*/
|
||||
public function buildComponent(string $file_path): Component
|
||||
public function processComponent(PackageWriter $package_writer, string $file_path): void
|
||||
{
|
||||
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
|
||||
$component_name = Functions::removeBasename($file_path);
|
||||
|
||||
try
|
||||
{
|
||||
$encoded = json_encode($parser->parse(IO::fread($file_path)), JSON_THROW_ON_ERROR);
|
||||
return new Component(Functions::removeBasename($file_path), ZiProto::encode(json_decode($encoded, true, 512, JSON_THROW_ON_ERROR)), ComponentDataType::AST);
|
||||
$stmts = (new ParserFactory())->create(ParserFactory::PREFER_PHP7)->parse(IO::fread($file_path));
|
||||
|
||||
$component = new Component($component_name, ZiProto::encode($stmts), ComponentDataType::AST);
|
||||
$component->addFlag(ComponentFlags::PHP_AST);
|
||||
$pointer = $package_writer->addComponent($component);
|
||||
|
||||
foreach(AstWalker::extractClasses($stmts) as $class)
|
||||
{
|
||||
$package_writer->mapClass($class, (int)$pointer[0], (int)$pointer[1]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outWarning(sprintf('Failed to compile file "%s" with error "%s"', $file_path, $e->getMessage()));
|
||||
}
|
||||
|
||||
return new Component(
|
||||
Functions::removeBasename($file_path),
|
||||
Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED
|
||||
);
|
||||
$component = new Component($component_name, Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED);
|
||||
$component->addFlag(ComponentFlags::PHP_B64);
|
||||
$package_writer->addComponent($component);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,356 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Classes\PhpExtension;
|
||||
|
||||
use ArrayIterator;
|
||||
use Exception;
|
||||
use ncc\Enums\ComponentDataType;
|
||||
use ncc\Enums\ComponentFileExtensions;
|
||||
use ncc\Exceptions\IntegrityException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\InstallerInterface;
|
||||
use ncc\Objects\InstallationPaths;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\Package\Component;
|
||||
use ncc\Objects\Package\Resource;
|
||||
use ncc\ThirdParty\nikic\PhpParser\Comment;
|
||||
use ncc\ThirdParty\nikic\PhpParser\Node;
|
||||
use ncc\ThirdParty\nikic\PhpParser\PrettyPrinter\Standard;
|
||||
use ncc\ThirdParty\theseer\Autoload\CollectorException;
|
||||
use ncc\ThirdParty\theseer\Autoload\CollectorResult;
|
||||
use ncc\ThirdParty\theseer\Autoload\Config;
|
||||
use ncc\ThirdParty\theseer\Autoload\Factory;
|
||||
use ncc\Utilities\Base64;
|
||||
use ncc\Utilities\IO;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use RuntimeException;
|
||||
use SplFileInfo;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
|
||||
class PhpInstaller implements InstallerInterface
|
||||
{
|
||||
/**
|
||||
* @var ReflectionClass[] Node type to reflection class map
|
||||
*/
|
||||
private $reflection_class;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct(Package $package)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the given component and returns the decoded component as a string representation
|
||||
* If the processed component does not result in a string representation, none will be returned.
|
||||
*
|
||||
* @param Component $component
|
||||
* @return string|null
|
||||
* @throws IntegrityException
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
public function processComponent(Package\Component $component): ?string
|
||||
{
|
||||
if($component->getData() === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!$component->validateChecksum())
|
||||
{
|
||||
throw new IntegrityException(sprintf('Checksum validation failed for component: %s', $component->getName()));
|
||||
}
|
||||
|
||||
switch($component->getDataType())
|
||||
{
|
||||
case ComponentDataType::AST:
|
||||
try
|
||||
{
|
||||
$stmts = $this->decodeRecursive($component->getData());
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new IntegrityException(sprintf('Cannot decode component: %s, %s', $component->getName(), $e->getMessage()));
|
||||
}
|
||||
|
||||
return (new Standard())->prettyPrintFile($stmts);
|
||||
|
||||
case ComponentDataType::BASE64_ENCODED:
|
||||
return Base64::decode($component->getData());
|
||||
|
||||
case ComponentDataType::PLAIN:
|
||||
return $component->getData();
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(sprintf('Component data type %s is not supported.', $component->getDataType()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function preInstall(InstallationPaths $installationPaths): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function postInstall(InstallationPaths $installationPaths): void
|
||||
{
|
||||
$autoload_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
$autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path);
|
||||
|
||||
IO::fwrite($autoload_path, $autoload_src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the given resource and returns the string representation of the resource
|
||||
*
|
||||
* @param Resource $resource
|
||||
* @return string|null
|
||||
* @throws IntegrityException
|
||||
*/
|
||||
public function processResource(Package\Resource $resource): ?string
|
||||
{
|
||||
if(!$resource->validateChecksum())
|
||||
{
|
||||
throw new IntegrityException('Checksum validation failed for resource ' . $resource->getName() . ', the package may be corrupted.');
|
||||
}
|
||||
|
||||
return Base64::decode($resource->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return array|Comment|Node
|
||||
* @throws ReflectionException
|
||||
* @noinspection PhpMissingReturnTypeInspection
|
||||
*/
|
||||
private function decodeRecursive($value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
if (isset($value['nodeType']))
|
||||
{
|
||||
if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc')
|
||||
{
|
||||
return $this->decodeComment($value);
|
||||
}
|
||||
|
||||
return $this->decodeNode($value);
|
||||
}
|
||||
|
||||
return $this->decodeArray($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @return array
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function decodeArray(array $array) : array
|
||||
{
|
||||
$decodedArray = [];
|
||||
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
$decodedArray[$key] = $this->decodeRecursive($value);
|
||||
}
|
||||
|
||||
return $decodedArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $value
|
||||
* @return Node
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function decodeNode(array $value) : Node
|
||||
{
|
||||
$nodeType = $value['nodeType'];
|
||||
if (!is_string($nodeType))
|
||||
{
|
||||
throw new RuntimeException('Node type must be a string');
|
||||
}
|
||||
|
||||
$reflectionClass = $this->reflectionClassFromNodeType($nodeType);
|
||||
/** @var Node $node */
|
||||
$node = $reflectionClass->newInstanceWithoutConstructor();
|
||||
|
||||
if (isset($value['attributes'])) {
|
||||
if (!is_array($value['attributes']))
|
||||
{
|
||||
throw new RuntimeException('Attributes must be an array');
|
||||
}
|
||||
|
||||
$node->setAttributes($this->decodeArray($value['attributes']));
|
||||
}
|
||||
|
||||
foreach ($value as $name => $subNode) {
|
||||
if ($name === 'nodeType' || $name === 'attributes')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->$name = $this->decodeRecursive($subNode);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $value
|
||||
* @return Comment
|
||||
*/
|
||||
private function decodeComment(array $value) : Comment
|
||||
{
|
||||
$className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
|
||||
if (!isset($value['text']))
|
||||
{
|
||||
throw new RuntimeException('Comment must have text');
|
||||
}
|
||||
|
||||
return new $className(
|
||||
$value['text'],
|
||||
$value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
|
||||
$value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $nodeType
|
||||
* @return ReflectionClass
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function reflectionClassFromNodeType(string $nodeType) : ReflectionClass
|
||||
{
|
||||
if (!isset($this->reflection_class[$nodeType]))
|
||||
{
|
||||
$className = $this->classNameFromNodeType($nodeType);
|
||||
$this->reflection_class[$nodeType] = new ReflectionClass($className);
|
||||
}
|
||||
return $this->reflection_class[$nodeType];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $nodeType
|
||||
* @return string
|
||||
*/
|
||||
private function classNameFromNodeType(string $nodeType) : string
|
||||
{
|
||||
$className = 'ncc\\ThirdParty\\nikic\\PhpParser\\Node\\' . str_replace('_', '\\', $nodeType);
|
||||
if (class_exists($className))
|
||||
{
|
||||
return $className;
|
||||
}
|
||||
|
||||
$className .= '_';
|
||||
if (class_exists($className))
|
||||
{
|
||||
return $className;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown node type \"$nodeType\"");
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the project and generates the autoloader source code.
|
||||
*
|
||||
* @param string $src
|
||||
* @param string $output
|
||||
* @return string
|
||||
* @throws CollectorException
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
private function generateAutoload(string $src, string $output): string
|
||||
{
|
||||
// Construct configuration
|
||||
$configuration = new Config([$src]);
|
||||
$configuration->setFollowSymlinks(false); // Don't follow symlinks, it won't work on some systems.
|
||||
$configuration->setTrusting(true); // Paranoid
|
||||
$configuration->setOutputFile($output);
|
||||
$configuration->setStaticMode(false);
|
||||
// Official PHP file extensions that are missing from the default configuration (whatever)
|
||||
$configuration->setInclude(ComponentFileExtensions::PHP);
|
||||
$configuration->setQuietMode(true);
|
||||
$configuration->setTolerantMode(true);
|
||||
|
||||
// Construct factory
|
||||
$factory = new Factory();
|
||||
$factory->setConfig($configuration);
|
||||
|
||||
// Create Collector
|
||||
$result = self::runCollector($factory, $configuration);
|
||||
|
||||
// Exception raises when there are no files in the project that can be processed by the autoloader
|
||||
$template = IO::fread($configuration->getTemplate());
|
||||
return $factory->getRenderer($result)->render($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the target directories through the collector and returns the collector results.
|
||||
*
|
||||
* @param Factory $factory
|
||||
* @param Config $config
|
||||
* @return CollectorResult
|
||||
* @throws CollectorException
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function runCollector(Factory $factory, Config $config): CollectorResult
|
||||
{
|
||||
$collector = $factory->getCollector();
|
||||
foreach($config->getDirectories() as $directory)
|
||||
{
|
||||
if(is_dir($directory))
|
||||
{
|
||||
$scanner = $factory->getScanner()->getIterator($directory);
|
||||
$collector->processDirectory($scanner);
|
||||
unset($scanner);
|
||||
}
|
||||
else
|
||||
{
|
||||
$file = new SplFileInfo($directory);
|
||||
$filter = $factory->getFilter(new ArrayIterator(array($file)));
|
||||
foreach($filter as $file)
|
||||
{
|
||||
$collector->processFile($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $collector->getResult();
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PhpExtension;
|
||||
|
||||
use Exception;
|
||||
use ncc\Enums\Options\RuntimeImportOptions;
|
||||
use ncc\Classes\NccExtension\ConstantCompiler;
|
||||
use ncc\Exceptions\ImportException;
|
||||
use ncc\Exceptions\IntegrityException;
|
||||
use ncc\Interfaces\RuntimeInterface;
|
||||
use ncc\Objects\PackageLock\VersionEntry;
|
||||
use ncc\Objects\ProjectConfiguration\Assembly;
|
||||
use ncc\Runtime\Constants;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
|
||||
class PhpRuntime implements RuntimeInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Attempts to import a PHP package
|
||||
*
|
||||
* @param VersionEntry $versionEntry
|
||||
* @param array $options
|
||||
* @return bool
|
||||
* @throws ImportException
|
||||
*/
|
||||
public static function import(VersionEntry $versionEntry, array $options=[]): bool
|
||||
{
|
||||
$autoload_path = $versionEntry->getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
$static_files = $versionEntry->getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin';
|
||||
$constants_path = $versionEntry->getInstallPaths()->getDataPath() . DIRECTORY_SEPARATOR . 'const';
|
||||
$assembly_path = $versionEntry->getInstallPaths()->getDataPath() . DIRECTORY_SEPARATOR . 'assembly';
|
||||
|
||||
if(!file_exists($assembly_path))
|
||||
{
|
||||
throw new ImportException('Cannot locate assembly file \'' . $assembly_path . '\'');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$assembly_content = ZiProto::decode(IO::fread($assembly_path));
|
||||
$assembly = Assembly::fromArray($assembly_content);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new ImportException('Failed to load assembly file \'' . $assembly_path . '\': ' . $e->getMessage());
|
||||
}
|
||||
|
||||
if(file_exists($constants_path))
|
||||
{
|
||||
try
|
||||
{
|
||||
$constants = ZiProto::decode(IO::fread($constants_path));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new ImportException('Failed to load constants file \'' . $constants_path . '\': ' . $e->getMessage());
|
||||
}
|
||||
|
||||
foreach($constants as $name => $value)
|
||||
{
|
||||
$value = ConstantCompiler::compileRuntimeConstants($value);
|
||||
|
||||
try
|
||||
{
|
||||
Constants::register($assembly->getPackage(), $name, $value, true);
|
||||
}
|
||||
catch (IntegrityException $e)
|
||||
{
|
||||
trigger_error('Cannot set constant \'' . $name . '\', ' . $e->getMessage(), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(file_exists($autoload_path) && !in_array(RuntimeImportOptions::IMPORT_AUTOLOADER, $options, true))
|
||||
{
|
||||
require_once($autoload_path);
|
||||
}
|
||||
|
||||
if(file_exists($static_files) && !in_array(RuntimeImportOptions::IMPORT_STATIC_FILES, $options, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
$static_files = ZiProto::decode(IO::fread($static_files));
|
||||
foreach($static_files as $file)
|
||||
{
|
||||
require_once($file);
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new ImportException('Failed to load static files: ' . $e->getMessage(), $e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return !(!file_exists($autoload_path) && !file_exists($static_files));
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
if (PHP_SAPI !== 'cli')
|
||||
{
|
||||
print('%ASSEMBLY.PACKAGE% must be run from the command line.' . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!isset($argv))
|
||||
{
|
||||
trigger_error('No $argv found, maybe you are using php-cgi?', E_USER_ERROR);
|
||||
}
|
||||
|
||||
require('ncc');
|
||||
import('%ASSEMBLY.PACKAGE%', 'latest');
|
||||
|
||||
\%ASSEMBLY.NAME%\Program::main($argv);
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PhpExtension;
|
||||
namespace ncc\Classes\PhpExtension\Templates;
|
||||
|
||||
use ncc\Classes\NccExtension\ConstantCompiler;
|
||||
use ncc\Enums\Options\ProjectOptions;
|
||||
|
@ -33,7 +33,7 @@
|
|||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class PhpCliTemplate implements TemplateInterface
|
||||
class CliTemplate implements TemplateInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
|
@ -71,7 +71,7 @@
|
|||
IO::fwrite(
|
||||
$project_manager->getProjectSourcePath() . DIRECTORY_SEPARATOR . 'Program.php',
|
||||
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
|
||||
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Program.php.tpl')
|
||||
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'Program.php.tpl')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@
|
|||
IO::fwrite(
|
||||
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'main',
|
||||
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
|
||||
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'main.php.tpl')
|
||||
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'main.php.tpl')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -107,7 +107,7 @@
|
|||
IO::fwrite(
|
||||
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'Makefile',
|
||||
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
|
||||
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Makefile.tpl')
|
||||
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'Makefile.tpl')
|
||||
)
|
||||
);
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PhpExtension;
|
||||
namespace ncc\Classes\PhpExtension\Templates;
|
||||
|
||||
use ncc\Classes\NccExtension\ConstantCompiler;
|
||||
use ncc\Exceptions\IOException;
|
||||
|
@ -29,7 +29,7 @@
|
|||
use ncc\Managers\ProjectManager;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class PhpLibraryTemplate implements TemplateInterface
|
||||
class LibraryTemplate implements TemplateInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
|
@ -7,11 +7,12 @@
|
|||
/**
|
||||
* %ASSEMBLY.NAME% main entry point
|
||||
*
|
||||
* @param string[] $args
|
||||
* @return void
|
||||
* @param string[] $args Command-line arguments
|
||||
* @return int Exit code
|
||||
*/
|
||||
public static function main(array $args): void
|
||||
public static function main(array $args): int
|
||||
{
|
||||
print("Hello World from %ASSEMBLY.PACKAGE%!" . PHP_EOL);
|
||||
return 0;
|
||||
}
|
||||
}
|
24
src/ncc/Classes/PhpExtension/Templates/main.php.tpl
Normal file
24
src/ncc/Classes/PhpExtension/Templates/main.php.tpl
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
if (PHP_SAPI !== 'cli')
|
||||
{
|
||||
print('%ASSEMBLY.PACKAGE% must be run from the command line.' . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!isset($argv))
|
||||
{
|
||||
if(isset($_SERVER['argv']))
|
||||
{
|
||||
$argv = $_SERVER['argv'];
|
||||
}
|
||||
else
|
||||
{
|
||||
print('%ASSEMBLY.PACKAGE% failed to run, no $argv found.' . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
require('ncc');
|
||||
\ncc\Classes\Runtime::import('%ASSEMBLY.PACKAGE%', 'latest');
|
||||
exit(\%ASSEMBLY.NAME%\Program::main($argv));
|
53
src/ncc/Classes/PhpExtension/bootstrap_main.c
Normal file
53
src/ncc/Classes/PhpExtension/bootstrap_main.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Get the program's file path
|
||||
char programPath[PATH_MAX];
|
||||
ssize_t pathLength = readlink("/proc/self/exe", programPath, sizeof(programPath) - 1);
|
||||
if (pathLength == -1)
|
||||
{
|
||||
perror("readlink");
|
||||
return 1;
|
||||
}
|
||||
|
||||
programPath[pathLength] = '\0';
|
||||
|
||||
// Calculate the total length needed for the command string
|
||||
size_t totalLength = snprintf(NULL, 0, "ncc exec --package=\"%s\" --exec-args", programPath);
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
totalLength += snprintf(NULL, 0, " \"%s\"", argv[i]) + 1; // +1 for space or null terminator
|
||||
}
|
||||
|
||||
// Allocate memory for the command string
|
||||
char *command = (char *)malloc(totalLength + 1); // +1 for null terminator
|
||||
if (command == NULL)
|
||||
{
|
||||
perror("malloc");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Construct the command to execute
|
||||
snprintf(command, totalLength + 1, "ncc exec --package=\"%s\" --exec-args", programPath);
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
snprintf(command + strlen(command), totalLength - strlen(command) + 1, " \"%s\"", argv[i]);
|
||||
}
|
||||
|
||||
// Execute the ncc command
|
||||
int result = system(command);
|
||||
free(command);
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
perror("system");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return WEXITSTATUS(result);
|
||||
}
|
|
@ -22,44 +22,47 @@
|
|||
|
||||
namespace ncc\Classes\PythonExtension;
|
||||
|
||||
use Exception;
|
||||
use ncc\Classes\ExecutionUnitRunner;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Exceptions\OperationException;
|
||||
use ncc\Interfaces\RunnerInterface;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
|
||||
class PythonRunner implements RunnerInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param string $path
|
||||
* @param ExecutionPolicy $policy
|
||||
* @return ExecutionUnit
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* @throws OperationException
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
|
||||
{
|
||||
$execution_unit = new ExecutionUnit();
|
||||
$tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.py';
|
||||
IO::fwrite($tmp, $unit->getData(), 0777);
|
||||
|
||||
if(!file_exists($path) && !is_file($path))
|
||||
try
|
||||
{
|
||||
throw new PathNotFoundException($path);
|
||||
$process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
|
||||
$process->run(static function($type, $buffer) use ($unit)
|
||||
{
|
||||
if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
|
||||
{
|
||||
print($buffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new OperationException(sprintf('There was an error executing the python execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
unlink($tmp);
|
||||
}
|
||||
|
||||
$execution_unit->setExecutionPolicy($policy);
|
||||
$execution_unit->setData(IO::fread($path));
|
||||
|
||||
return $execution_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getFileExtension(): string
|
||||
{
|
||||
return '.py';
|
||||
return $process->getExitCode();
|
||||
}
|
||||
}
|
257
src/ncc/Classes/Runtime.php
Normal file
257
src/ncc/Classes/Runtime.php
Normal file
|
@ -0,0 +1,257 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Classes;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use ncc\Enums\FileDescriptor;
|
||||
use ncc\Enums\Runners;
|
||||
use ncc\Enums\Versions;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\ImportException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use ncc\Managers\PackageManager;
|
||||
use ncc\Objects\Package\Metadata;
|
||||
use ncc\Utilities\IO;
|
||||
use RuntimeException;
|
||||
|
||||
class Runtime
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $imported_packages = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $class_map = [];
|
||||
|
||||
/**
|
||||
* @var PackageManager|null
|
||||
*/
|
||||
private static $package_manager;
|
||||
|
||||
/**
|
||||
* Executes the main execution point of an imported package and returns the evaluated result
|
||||
* This method may exit the program without returning a value
|
||||
*
|
||||
* @param string $package
|
||||
* @return mixed
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
public static function execute(string $package): int
|
||||
{
|
||||
if(!self::isImported($package))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Package %s is not imported', $package));
|
||||
}
|
||||
|
||||
if(self::$imported_packages[$package] instanceof PackageReader)
|
||||
{
|
||||
return ExecutionUnitRunner::executeFromPackage(
|
||||
self::$imported_packages[$package],
|
||||
self::$imported_packages[$package]->getMetadata()->getMainExecutionPolicy()
|
||||
);
|
||||
}
|
||||
|
||||
if(is_string(self::$imported_packages[$package]))
|
||||
{
|
||||
$metadata_path = self::$imported_packages[$package] . DIRECTORY_SEPARATOR . FileDescriptor::METADATA;
|
||||
|
||||
if(!is_file($metadata_path))
|
||||
{
|
||||
throw new RuntimeException(sprintf('The package %s does not have a metadata file (is it corrupted?)', $package));
|
||||
}
|
||||
|
||||
return ExecutionUnitRunner::executeFromSystem(
|
||||
self::$imported_packages[$package],
|
||||
Metadata::fromArray(ZiProto::decode(IO::fread($metadata_path)))->getMainExecutionPolicy()
|
||||
);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Unable to execute the main execution point of the package, this is probably a bug');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @return string
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws ImportException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public static function import(string $package, string $version=Versions::LATEST): string
|
||||
{
|
||||
if(self::isImported($package))
|
||||
{
|
||||
return $package;
|
||||
}
|
||||
|
||||
if(is_file($package))
|
||||
{
|
||||
return self::importFromPackage(realpath($package));
|
||||
}
|
||||
|
||||
if(self::getPackageManager()->getPackageLock()->entryExists($package))
|
||||
{
|
||||
return self::importFromSystem($package, $version);
|
||||
}
|
||||
|
||||
throw new RuntimeException('Importing from a package name is not supported yet');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @return string
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
private static function importFromSystem(string $package, string $version=Versions::LATEST): string
|
||||
{
|
||||
$entry = self::getPackageManager()->getPackageLock()->getEntry($package);
|
||||
|
||||
foreach($entry->getClassMap($version) as $class => $component_name)
|
||||
{
|
||||
$component_path = $entry->getPath($version) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . $component_name;
|
||||
self::$class_map[strtolower($class)] = $component_path;
|
||||
}
|
||||
|
||||
self::$imported_packages[$package] = $entry->getPath($version);
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a package from a package file
|
||||
*
|
||||
* @param string $package_path
|
||||
* @return string
|
||||
* @throws ConfigurationException
|
||||
* @throws ImportException
|
||||
*/
|
||||
private static function importFromPackage(string $package_path): string
|
||||
{
|
||||
try
|
||||
{
|
||||
$package_reader = new PackageReader($package_path);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new RuntimeException(sprintf('Failed to import package from file "%s" due to an exception: %s', $package_path, $e->getMessage()), 0, $e);
|
||||
}
|
||||
|
||||
// Check if the package is already imported
|
||||
if(in_array($package_reader->getAssembly()->getPackage(), self::$imported_packages, true))
|
||||
{
|
||||
$package_name = $package_reader->getAssembly()->getPackage();
|
||||
unset($package_reader);
|
||||
return $package_name;
|
||||
}
|
||||
|
||||
// Import the package
|
||||
$package_name = $package_reader->getAssembly()->getPackage();
|
||||
self::$imported_packages[$package_name] = $package_reader;
|
||||
|
||||
// Register the autoloader
|
||||
foreach($package_reader->getClassMap() as $value)
|
||||
{
|
||||
self::$class_map[strtolower($value)] = static function() use ($value, $package_name)
|
||||
{
|
||||
return self::$imported_packages[$package_name]->getComponentByClass($value)->getData();
|
||||
};
|
||||
}
|
||||
|
||||
return $package_reader->getAssembly()->getPackage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the package is already imported
|
||||
*
|
||||
* @param string $package
|
||||
* @return bool
|
||||
*/
|
||||
public static function isImported(string $package): bool
|
||||
{
|
||||
return isset(self::$imported_packages[$package]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the packages that is currently imported
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getImportedPackages(): array
|
||||
{
|
||||
return array_keys(self::$imported_packages);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @return void
|
||||
*/
|
||||
public static function autoloadHandler(string $class): void
|
||||
{
|
||||
$class = strtolower($class);
|
||||
|
||||
if(!isset(self::$class_map[$class]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_callable(self::$class_map[$class]))
|
||||
{
|
||||
eval(self::$class_map[$class]());
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_string(self::$class_map[$class]) && is_file(self::$class_map[$class]))
|
||||
{
|
||||
require_once self::$class_map[$class];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PackageManager
|
||||
*/
|
||||
private static function getPackageManager(): PackageManager
|
||||
{
|
||||
if(self::$package_manager === null)
|
||||
{
|
||||
self::$package_manager = new PackageManager();
|
||||
}
|
||||
|
||||
return self::$package_manager;
|
||||
}
|
||||
}
|
|
@ -25,4 +25,5 @@
|
|||
final class BuildOutputType
|
||||
{
|
||||
public const NCC_PACKAGE = 'ncc';
|
||||
public const EXECUTABLE = 'executable';
|
||||
}
|
|
@ -34,11 +34,6 @@
|
|||
*/
|
||||
public const PLAIN = 'plain';
|
||||
|
||||
/**
|
||||
* Indicates whether the component is represented as bytecode
|
||||
*/
|
||||
public const BYTECODE = 'bytecode';
|
||||
|
||||
/**
|
||||
* Indicates whether the component is represented as binary or executable
|
||||
*/
|
||||
|
|
34
src/ncc/Enums/FileDescriptor.php
Normal file
34
src/ncc/Enums/FileDescriptor.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Enums;
|
||||
|
||||
final class FileDescriptor
|
||||
{
|
||||
public const ASSEMBLY = 'ASSEMBLY';
|
||||
|
||||
public const METADATA = 'METADATA';
|
||||
|
||||
public const INSTALLER = 'INSTALLER';
|
||||
|
||||
public const CLASS_MAP = 'CLASS_MAP';
|
||||
}
|
|
@ -20,46 +20,17 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PythonExtension;
|
||||
namespace ncc\Enums\Flags;
|
||||
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\RunnerInterface;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class Python2Runner implements RunnerInterface
|
||||
final class ComponentFlags
|
||||
{
|
||||
/**
|
||||
* Indicates that the component is the AST of a PHP file encoded with msgpack.
|
||||
*/
|
||||
public const PHP_AST = 'php_ast';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param string $path
|
||||
* @param ExecutionPolicy $policy
|
||||
* @return ExecutionUnit
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
* Indicates that the component is a PHP file encoded with base64.
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
{
|
||||
$execution_unit = new ExecutionUnit();
|
||||
|
||||
if(!file_exists($path) && !is_file($path))
|
||||
{
|
||||
throw new PathNotFoundException($path);
|
||||
}
|
||||
|
||||
$execution_unit->setExecutionPolicy($policy);
|
||||
$execution_unit->setData(IO::fread($path));
|
||||
|
||||
return $execution_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getFileExtension(): string
|
||||
{
|
||||
return '.py';
|
||||
}
|
||||
public const PHP_B64 = 'php_b64';
|
||||
}
|
34
src/ncc/Enums/Flags/PackageFlags.php
Normal file
34
src/ncc/Enums/Flags/PackageFlags.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Enums\Flags;
|
||||
|
||||
final class PackageFlags
|
||||
{
|
||||
public const COMPRESSION = 'gzip';
|
||||
|
||||
public const LOW_COMPRESSION = 'low_gz`';
|
||||
|
||||
public const MEDIUM_COMPRESSION = 'medium_gz';
|
||||
|
||||
public const HIGH_COMPRESSION = 'high_gz';
|
||||
}
|
28
src/ncc/Enums/Options/BuildConfigurationOptions.php
Normal file
28
src/ncc/Enums/Options/BuildConfigurationOptions.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Enums\Options;
|
||||
|
||||
final class BuildConfigurationOptions
|
||||
{
|
||||
public const COMPRESSION = 'compression';
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Enums\Options\BuildConfigurationOptions;
|
||||
|
||||
final class CompressionOptions
|
||||
{
|
||||
public const HIGH = 'high';
|
||||
|
||||
public const MEDIUM = 'medium';
|
||||
|
||||
public const LOW = 'low';
|
||||
}
|
28
src/ncc/Enums/Options/ComponentDecodeOptions.php
Normal file
28
src/ncc/Enums/Options/ComponentDecodeOptions.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Enums\Options;
|
||||
|
||||
final class ComponentDecodeOptions
|
||||
{
|
||||
public const AS_FILE = 'as_file';
|
||||
}
|
|
@ -20,46 +20,23 @@
|
|||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Classes\PythonExtension;
|
||||
namespace ncc\Enums;
|
||||
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\RunnerInterface;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class Python3Runner implements RunnerInterface
|
||||
final class PackageDirectory
|
||||
{
|
||||
public const ASSEMBLY = 0x61737365;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @param string $path
|
||||
* @param ExecutionPolicy $policy
|
||||
* @return ExecutionUnit
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
{
|
||||
$execution_unit = new ExecutionUnit();
|
||||
public const METADATA = 0x6D657461;
|
||||
|
||||
if(!file_exists($path) && !is_file($path))
|
||||
{
|
||||
throw new PathNotFoundException($path);
|
||||
}
|
||||
public const INSTALLER = 0x696E7374;
|
||||
|
||||
$execution_unit->setExecutionPolicy($policy);
|
||||
$execution_unit->setData(IO::fread($path));
|
||||
public const DEPENDENCIES = 0x64657065;
|
||||
|
||||
return $execution_unit;
|
||||
}
|
||||
public const EXECUTION_UNITS = 0x65786563;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getFileExtension(): string
|
||||
{
|
||||
return '.py';
|
||||
}
|
||||
public const COMPONENTS = 0x636F6D70;
|
||||
|
||||
public const RESOURCES = 0x7265736F;
|
||||
|
||||
public const CLASS_POINTER = 0x636C6173;
|
||||
}
|
|
@ -30,10 +30,6 @@ namespace ncc\Enums;
|
|||
|
||||
public const PYTHON = 'python';
|
||||
|
||||
public const PYTHON_3 = 'python3';
|
||||
|
||||
public const PYTHON_2 = 'python2';
|
||||
|
||||
public const PERL = 'perl';
|
||||
|
||||
public const LUA = 'lua';
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Enums;
|
||||
|
||||
|
@ -32,12 +32,12 @@
|
|||
/**
|
||||
* The current version of the package structure file format
|
||||
*/
|
||||
public const PACKAGE_STRUCTURE_VERSION = '1.0';
|
||||
public const PACKAGE_STRUCTURE_VERSION = '2.0';
|
||||
|
||||
/**
|
||||
* The current version of the package lock structure file format
|
||||
*/
|
||||
public const PACKAGE_LOCK_VERSION = '1.0.0';
|
||||
public const PACKAGE_LOCK_VERSION = '2.0.0';
|
||||
|
||||
/**
|
||||
* Generic version of the package structure file format (latest)
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Abstracts;
|
||||
namespace ncc\Extensions\ZiProto\Abstracts;
|
||||
|
||||
/**
|
||||
* Class Options
|
||||
* @package ncc\ZiProto\Abstracts
|
||||
*/
|
||||
abstract class Options
|
||||
final class Options
|
||||
{
|
||||
const BIGINT_AS_STR = 0b001;
|
||||
const BIGINT_AS_GMP = 0b010;
|
||||
const BIGINT_AS_EXCEPTION = 0b100;
|
||||
const FORCE_STR = 0b00000001;
|
||||
const FORCE_BIN = 0b00000010;
|
||||
const DETECT_STR_BIN = 0b00000100;
|
||||
const FORCE_ARR = 0b00001000;
|
||||
const FORCE_MAP = 0b00010000;
|
||||
const DETECT_ARR_MAP = 0b00100000;
|
||||
const FORCE_FLOAT32 = 0b01000000;
|
||||
const FORCE_FLOAT64 = 0b10000000;
|
||||
public const BIGINT_AS_STR = 0b001;
|
||||
public const BIGINT_AS_GMP = 0b010;
|
||||
public const BIGINT_AS_EXCEPTION = 0b100;
|
||||
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;
|
||||
}
|
|
@ -1,34 +1,34 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Abstracts;
|
||||
namespace ncc\Extensions\ZiProto\Abstracts;
|
||||
|
||||
/**
|
||||
* Class Regex
|
||||
* @package ncc\ZiProto\Abstracts
|
||||
*/
|
||||
abstract class Regex
|
||||
final class Regex
|
||||
{
|
||||
const UTF8_REGEX = '/\A(?:
|
||||
public const UTF8_REGEX = '/\A(?:
|
||||
[\x00-\x7F]++ # ASCII
|
||||
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding over longs
|
||||
|
|
|
@ -1,37 +1,40 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto;
|
||||
|
||||
use function gmp_init;
|
||||
use function ord;
|
||||
use function sprintf;
|
||||
use function substr;
|
||||
use function unpack;
|
||||
use ncc\ZiProto\Exception\InsufficientDataException;
|
||||
use ncc\ZiProto\Exception\IntegerOverflowException;
|
||||
use ncc\ZiProto\Exception\DecodingFailedException;
|
||||
use ncc\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\ncc\ZiProto\TypeTransformer\Extension;
|
||||
use ncc\Extensions\ZiProto\Exception\InsufficientDataException;
|
||||
use ncc\Extensions\ZiProto\Exception\IntegerOverflowException;
|
||||
use ncc\Extensions\ZiProto\Exception\DecodingFailedException;
|
||||
use ncc\Extensions\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\Extensions\ZiProto\TypeTransformer\Extension;
|
||||
|
||||
/**
|
||||
* Class BufferStream
|
||||
|
@ -52,12 +55,12 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isBigIntAsStr;
|
||||
private $big_int_as_str;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isBigIntAsGmp;
|
||||
private $big_int_as_gmp;
|
||||
|
||||
/**
|
||||
* @var Extension[]|null
|
||||
|
@ -66,11 +69,10 @@ namespace ncc\ZiProto;
|
|||
|
||||
/**
|
||||
* @param string $buffer
|
||||
* @param DecodingOptions|int|null $options
|
||||
*
|
||||
* @param int|DecodingOptions|null $options
|
||||
* @throws InvalidOptionException
|
||||
*/
|
||||
public function __construct(string $buffer = '', $options = null)
|
||||
public function __construct(string $buffer = '', DecodingOptions|int|null $options=null)
|
||||
{
|
||||
if (null === $options)
|
||||
{
|
||||
|
@ -85,8 +87,8 @@ namespace ncc\ZiProto;
|
|||
$options = DecodingOptions::fromBitmask($options);
|
||||
}
|
||||
|
||||
$this->isBigIntAsStr = $options->isBigIntAsStrMode();
|
||||
$this->isBigIntAsGmp = $options->isBigIntAsGmpMode();
|
||||
$this->big_int_as_str = $options->isBigIntAsStrMode();
|
||||
$this->big_int_as_gmp = $options->isBigIntAsGmpMode();
|
||||
$this->buffer = $buffer;
|
||||
}
|
||||
|
||||
|
@ -94,7 +96,7 @@ namespace ncc\ZiProto;
|
|||
* @param Extension $transformer
|
||||
* @return BufferStream
|
||||
*/
|
||||
public function registerTransformer(Extension $transformer) : self
|
||||
public function registerTransformer(Extension $transformer): self
|
||||
{
|
||||
$this->transformers[$transformer->getType()] = $transformer;
|
||||
return $this;
|
||||
|
@ -114,7 +116,7 @@ namespace ncc\ZiProto;
|
|||
* @param string $buffer
|
||||
* @return BufferStream
|
||||
*/
|
||||
public function reset(string $buffer = '') : self
|
||||
public function reset(string $buffer='') : self
|
||||
{
|
||||
$this->buffer = $buffer;
|
||||
$this->offset = 0;
|
||||
|
@ -203,64 +205,61 @@ namespace ncc\ZiProto;
|
|||
return $c - 0x100;
|
||||
}
|
||||
|
||||
switch ($c)
|
||||
return match ($c)
|
||||
{
|
||||
case 0xc0: return null;
|
||||
case 0xc2: return false;
|
||||
case 0xc3: return true;
|
||||
0xc0 => null,
|
||||
0xc2 => false,
|
||||
0xc3 => true,
|
||||
|
||||
// bin
|
||||
case 0xd9:
|
||||
case 0xc4: return $this->decodeStrData($this->decodeUint8());
|
||||
case 0xda:
|
||||
case 0xc5: return $this->decodeStrData($this->decodeUint16());
|
||||
case 0xdb:
|
||||
case 0xc6: return $this->decodeStrData($this->decodeUint32());
|
||||
0xd9, 0xc4 => $this->decodeStrData($this->decodeUint8()),
|
||||
0xda, 0xc5 => $this->decodeStrData($this->decodeUint16()),
|
||||
0xdb, 0xc6 => $this->decodeStrData($this->decodeUint32()),
|
||||
|
||||
// float
|
||||
case 0xca: return $this->decodeFloat32();
|
||||
case 0xcb: return $this->decodeFloat64();
|
||||
0xca => $this->decodeFloat32(),
|
||||
0xcb => $this->decodeFloat64(),
|
||||
|
||||
// uint
|
||||
case 0xcc: return $this->decodeUint8();
|
||||
case 0xcd: return $this->decodeUint16();
|
||||
case 0xce: return $this->decodeUint32();
|
||||
case 0xcf: return $this->decodeUint64();
|
||||
0xcc => $this->decodeUint8(),
|
||||
0xcd => $this->decodeUint16(),
|
||||
0xce => $this->decodeUint32(),
|
||||
0xcf => $this->decodeUint64(),
|
||||
|
||||
// int
|
||||
case 0xd0: return $this->decodeInt8();
|
||||
case 0xd1: return $this->decodeInt16();
|
||||
case 0xd2: return $this->decodeInt32();
|
||||
case 0xd3: return $this->decodeInt64();
|
||||
0xd0 => $this->decodeInt8(),
|
||||
0xd1 => $this->decodeInt16(),
|
||||
0xd2 => $this->decodeInt32(),
|
||||
0xd3 => $this->decodeInt64(),
|
||||
|
||||
// str
|
||||
|
||||
// array
|
||||
case 0xdc: return $this->decodeArrayData($this->decodeUint16());
|
||||
case 0xdd: return $this->decodeArrayData($this->decodeUint32());
|
||||
0xdc => $this->decodeArrayData($this->decodeUint16()),
|
||||
0xdd => $this->decodeArrayData($this->decodeUint32()),
|
||||
|
||||
// map
|
||||
case 0xde: return $this->decodeMapData($this->decodeUint16());
|
||||
case 0xdf: return $this->decodeMapData($this->decodeUint32());
|
||||
0xde => $this->decodeMapData($this->decodeUint16()),
|
||||
0xdf => $this->decodeMapData($this->decodeUint32()),
|
||||
|
||||
// ext
|
||||
case 0xd4: return $this->decodeExtData(1);
|
||||
case 0xd5: return $this->decodeExtData(2);
|
||||
case 0xd6: return $this->decodeExtData(4);
|
||||
case 0xd7: return $this->decodeExtData(8);
|
||||
case 0xd8: return $this->decodeExtData(16);
|
||||
case 0xc7: return $this->decodeExtData($this->decodeUint8());
|
||||
case 0xc8: return $this->decodeExtData($this->decodeUint16());
|
||||
case 0xc9: return $this->decodeExtData($this->decodeUint32());
|
||||
}
|
||||
0xd4 => $this->decodeExtData(1),
|
||||
0xd5 => $this->decodeExtData(2),
|
||||
0xd6 => $this->decodeExtData(4),
|
||||
0xd7 => $this->decodeExtData(8),
|
||||
0xd8 => $this->decodeExtData(16),
|
||||
0xc7 => $this->decodeExtData($this->decodeUint8()),
|
||||
0xc8 => $this->decodeExtData($this->decodeUint16()),
|
||||
0xc9 => $this->decodeExtData($this->decodeUint32()),
|
||||
|
||||
throw DecodingFailedException::unknownCode($c);
|
||||
default => throw DecodingFailedException::unknownCode($c), // Default case
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
* @return void
|
||||
*/
|
||||
public function decodeNil()
|
||||
public function decodeNil(): void
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -270,7 +269,7 @@ namespace ncc\ZiProto;
|
|||
if ("\xc0" === $this->buffer[$this->offset])
|
||||
{
|
||||
++$this->offset;
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
throw DecodingFailedException::unexpectedCode(ord($this->buffer[$this->offset++]), 'nil');
|
||||
|
@ -279,7 +278,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function decodeBool()
|
||||
public function decodeBool(): bool
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -348,7 +347,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function decodeFloat()
|
||||
public function decodeFloat(): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -374,7 +373,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function decodeStr()
|
||||
public function decodeStr(): string
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -410,7 +409,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function decodeBin()
|
||||
public function decodeBin(): string
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -441,7 +440,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function decodeArray()
|
||||
public function decodeArray(): array
|
||||
{
|
||||
$size = $this->decodeArrayHeader();
|
||||
$array = [];
|
||||
|
@ -457,7 +456,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function decodeArrayHeader()
|
||||
public function decodeArrayHeader(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -488,7 +487,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function decodeMap()
|
||||
public function decodeMap(): array
|
||||
{
|
||||
$size = $this->decodeMapHeader();
|
||||
$map = [];
|
||||
|
@ -504,7 +503,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function decodeMapHeader()
|
||||
public function decodeMapHeader(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -535,7 +534,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return mixed|Ext
|
||||
*/
|
||||
public function decodeExt()
|
||||
public function decodeExt(): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -563,7 +562,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function decodeUint8()
|
||||
private function decodeUint8(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -576,7 +575,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function decodeUint16()
|
||||
private function decodeUint16(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 1]))
|
||||
{
|
||||
|
@ -593,7 +592,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function decodeUint32()
|
||||
private function decodeUint32(): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 3]))
|
||||
{
|
||||
|
@ -625,7 +624,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function decodeInt8()
|
||||
private function decodeInt8(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset]))
|
||||
{
|
||||
|
@ -641,7 +640,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function decodeInt16()
|
||||
private function decodeInt16(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 1]))
|
||||
{
|
||||
|
@ -658,7 +657,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function decodeInt32()
|
||||
private function decodeInt32(): int
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 3]))
|
||||
{
|
||||
|
@ -674,7 +673,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function decodeInt64()
|
||||
private function decodeInt64(): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 7]))
|
||||
{
|
||||
|
@ -690,7 +689,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function decodeFloat32()
|
||||
private function decodeFloat32(): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 3]))
|
||||
{
|
||||
|
@ -706,7 +705,7 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function decodeFloat64()
|
||||
private function decodeFloat64(): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + 7]))
|
||||
{
|
||||
|
@ -723,7 +722,7 @@ namespace ncc\ZiProto;
|
|||
* @param $length
|
||||
* @return string
|
||||
*/
|
||||
private function decodeStrData($length)
|
||||
private function decodeStrData($length): string
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + $length - 1]))
|
||||
{
|
||||
|
@ -740,7 +739,7 @@ namespace ncc\ZiProto;
|
|||
* @param $size
|
||||
* @return array
|
||||
*/
|
||||
private function decodeArrayData($size)
|
||||
private function decodeArrayData($size): array
|
||||
{
|
||||
$array = [];
|
||||
|
||||
|
@ -756,7 +755,7 @@ namespace ncc\ZiProto;
|
|||
* @param $size
|
||||
* @return array
|
||||
*/
|
||||
private function decodeMapData($size)
|
||||
private function decodeMapData($size): array
|
||||
{
|
||||
$map = [];
|
||||
|
||||
|
@ -772,7 +771,7 @@ namespace ncc\ZiProto;
|
|||
* @param $length
|
||||
* @return mixed|Ext
|
||||
*/
|
||||
private function decodeExtData($length)
|
||||
private function decodeExtData($length): mixed
|
||||
{
|
||||
if (!isset($this->buffer[$this->offset + $length - 1]))
|
||||
{
|
||||
|
@ -801,12 +800,12 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
private function handleIntOverflow($value)
|
||||
{
|
||||
if ($this->isBigIntAsStr)
|
||||
if ($this->big_int_as_str)
|
||||
{
|
||||
return sprintf('%u', $value);
|
||||
}
|
||||
|
||||
if ($this->isBigIntAsGmp)
|
||||
if ($this->big_int_as_gmp)
|
||||
{
|
||||
return gmp_init(sprintf('%u', $value));
|
||||
}
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
use ncc\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\ZiProto\Abstracts\Options;
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto;
|
||||
|
||||
use ncc\Extensions\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\Extensions\ZiProto\Abstracts\Options;
|
||||
|
||||
/**
|
||||
* Class DecodingOptions
|
||||
|
@ -33,9 +36,9 @@ namespace ncc\ZiProto;
|
|||
{
|
||||
|
||||
/**
|
||||
* @var
|
||||
* @var int
|
||||
*/
|
||||
private $bigIntMode;
|
||||
private $big_int_mode;
|
||||
|
||||
/**
|
||||
* DecodingOptions constructor.
|
||||
|
@ -48,7 +51,7 @@ namespace ncc\ZiProto;
|
|||
public static function fromDefaults() : self
|
||||
{
|
||||
$self = new self();
|
||||
$self->bigIntMode = Options::BIGINT_AS_STR;
|
||||
$self->big_int_mode = Options::BIGINT_AS_STR;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
@ -61,7 +64,7 @@ namespace ncc\ZiProto;
|
|||
{
|
||||
$self = new self();
|
||||
|
||||
$self->bigIntMode = self::getSingleOption($bitmask,
|
||||
$self->big_int_mode = self::getSingleOption($bitmask,
|
||||
Options::BIGINT_AS_STR |
|
||||
Options::BIGINT_AS_GMP |
|
||||
Options::BIGINT_AS_EXCEPTION
|
||||
|
@ -75,7 +78,7 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isBigIntAsStrMode() : bool
|
||||
{
|
||||
return Options::BIGINT_AS_STR === $this->bigIntMode;
|
||||
return Options::BIGINT_AS_STR === $this->big_int_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,17 +86,17 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isBigIntAsGmpMode() : bool
|
||||
{
|
||||
return Options::BIGINT_AS_GMP === $this->bigIntMode;
|
||||
return Options::BIGINT_AS_GMP === $this->big_int_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $bitmask
|
||||
* @param int $validBitmask
|
||||
* @param int $valid_bitmask
|
||||
* @return int
|
||||
*/
|
||||
private static function getSingleOption(int $bitmask, int $validBitmask) : int
|
||||
private static function getSingleOption(int $bitmask, int $valid_bitmask) : int
|
||||
{
|
||||
$option = $bitmask & $validBitmask;
|
||||
$option = $bitmask & $valid_bitmask;
|
||||
if ($option === ($option & -$option))
|
||||
{
|
||||
return $option;
|
||||
|
@ -105,12 +108,14 @@ namespace ncc\ZiProto;
|
|||
Options::BIGINT_AS_EXCEPTION => 'BIGINT_AS_EXCEPTION',
|
||||
];
|
||||
|
||||
$validOptions = [];
|
||||
for ($i = $validBitmask & -$validBitmask; $i <= $validBitmask; $i <<= 1)
|
||||
$valid_options = [];
|
||||
|
||||
/** @noinspection SuspiciousLoopInspection */
|
||||
for ($i = $valid_bitmask & -$valid_bitmask; $i <= $valid_bitmask; $i <<= 1)
|
||||
{
|
||||
$validOptions[] = __CLASS__.'::'.$map[$i];
|
||||
$valid_options[] = __CLASS__.'::'.$map[$i];
|
||||
}
|
||||
|
||||
throw InvalidOptionException::outOfRange('bigint', $validOptions);
|
||||
throw InvalidOptionException::outOfRange('bigint', $valid_options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
use ncc\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\ZiProto\Abstracts\Options;
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto;
|
||||
|
||||
use ncc\Extensions\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\Extensions\ZiProto\Abstracts\Options;
|
||||
|
||||
/**
|
||||
* Class EncodingOptions
|
||||
|
@ -34,17 +37,17 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $strBinMode;
|
||||
private $str_bin_mode;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $arrMapMode;
|
||||
private $array_map_mode;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $floatMode;
|
||||
private $float_mode;
|
||||
|
||||
/**
|
||||
* EncodingOptions constructor.
|
||||
|
@ -57,9 +60,10 @@ namespace ncc\ZiProto;
|
|||
public static function fromDefaults() : self
|
||||
{
|
||||
$self = new self();
|
||||
$self->strBinMode = Options::DETECT_STR_BIN;
|
||||
$self->arrMapMode = Options::DETECT_ARR_MAP;
|
||||
$self->floatMode = Options::FORCE_FLOAT64;
|
||||
|
||||
$self->str_bin_mode = Options::DETECT_STR_BIN;
|
||||
$self->array_map_mode = Options::DETECT_ARR_MAP;
|
||||
$self->float_mode = Options::FORCE_FLOAT64;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
@ -74,7 +78,7 @@ namespace ncc\ZiProto;
|
|||
|
||||
if (self::getSingleOption('str/bin', $bitmask, Options::FORCE_STR | Options::FORCE_BIN | Options::DETECT_STR_BIN))
|
||||
{
|
||||
$self->strBinMode = self::getSingleOption('str/bin', $bitmask,
|
||||
$self->str_bin_mode = self::getSingleOption('str/bin', $bitmask,
|
||||
Options::FORCE_STR |
|
||||
Options::FORCE_BIN |
|
||||
Options::DETECT_STR_BIN
|
||||
|
@ -82,12 +86,12 @@ namespace ncc\ZiProto;
|
|||
}
|
||||
else
|
||||
{
|
||||
$self->strBinMode = Options::DETECT_STR_BIN;
|
||||
$self->str_bin_mode = Options::DETECT_STR_BIN;
|
||||
}
|
||||
|
||||
if (self::getSingleOption('arr/map', $bitmask, Options::FORCE_ARR | Options::FORCE_MAP | Options::DETECT_ARR_MAP))
|
||||
{
|
||||
$self->arrMapMode = self::getSingleOption('arr/map', $bitmask,
|
||||
$self->array_map_mode = self::getSingleOption('arr/map', $bitmask,
|
||||
Options::FORCE_ARR |
|
||||
Options::FORCE_MAP |
|
||||
Options::DETECT_ARR_MAP
|
||||
|
@ -95,19 +99,19 @@ namespace ncc\ZiProto;
|
|||
}
|
||||
else
|
||||
{
|
||||
$self->arrMapMode = Options::DETECT_ARR_MAP;
|
||||
$self->array_map_mode = Options::DETECT_ARR_MAP;
|
||||
}
|
||||
|
||||
if (self::getSingleOption('float', $bitmask, Options::FORCE_FLOAT32 | Options::FORCE_FLOAT64))
|
||||
{
|
||||
$self->floatMode = self::getSingleOption('float', $bitmask,
|
||||
$self->float_mode = self::getSingleOption('float', $bitmask,
|
||||
Options::FORCE_FLOAT32 |
|
||||
Options::FORCE_FLOAT64
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$self->floatMode = Options::FORCE_FLOAT64;
|
||||
$self->float_mode = Options::FORCE_FLOAT64;
|
||||
}
|
||||
|
||||
return $self;
|
||||
|
@ -118,7 +122,7 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isDetectStrBinMode() : bool
|
||||
{
|
||||
return Options::DETECT_STR_BIN === $this->strBinMode;
|
||||
return Options::DETECT_STR_BIN === $this->str_bin_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +130,7 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isForceStrMode() : bool
|
||||
{
|
||||
return Options::FORCE_STR === $this->strBinMode;
|
||||
return Options::FORCE_STR === $this->str_bin_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,7 +138,7 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isDetectArrMapMode() : bool
|
||||
{
|
||||
return Options::DETECT_ARR_MAP === $this->arrMapMode;
|
||||
return Options::DETECT_ARR_MAP === $this->array_map_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,7 +146,7 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isForceArrMode() : bool
|
||||
{
|
||||
return Options::FORCE_ARR === $this->arrMapMode;
|
||||
return Options::FORCE_ARR === $this->array_map_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,18 +154,18 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function isForceFloat32Mode() : bool
|
||||
{
|
||||
return Options::FORCE_FLOAT32 === $this->floatMode;
|
||||
return Options::FORCE_FLOAT32 === $this->float_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int $bitmask
|
||||
* @param int $validBitmask
|
||||
* @param int $valid_bitmask
|
||||
* @return int
|
||||
*/
|
||||
private static function getSingleOption(string $name, int $bitmask, int $validBitmask) : int
|
||||
private static function getSingleOption(string $name, int $bitmask, int $valid_bitmask) : int
|
||||
{
|
||||
$option = $bitmask & $validBitmask;
|
||||
$option = $bitmask & $valid_bitmask;
|
||||
|
||||
if ($option === ($option & -$option))
|
||||
{
|
||||
|
@ -179,13 +183,14 @@ namespace ncc\ZiProto;
|
|||
Options::FORCE_FLOAT64 => 'FORCE_FLOAT64',
|
||||
];
|
||||
|
||||
$validOptions = [];
|
||||
$valid_options = [];
|
||||
|
||||
for ($i = $validBitmask & -$validBitmask; $i <= $validBitmask; $i <<= 1)
|
||||
/** @noinspection SuspiciousLoopInspection */
|
||||
for($i = $valid_bitmask & -$valid_bitmask; $i <= $valid_bitmask; $i <<= 1)
|
||||
{
|
||||
$validOptions[] = __CLASS__.'::'.$map[$i];
|
||||
$valid_options[] = __CLASS__.'::'.$map[$i];
|
||||
}
|
||||
|
||||
throw InvalidOptionException::outOfRange($name, $validOptions);
|
||||
throw InvalidOptionException::outOfRange($name, $valid_options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Exception;
|
||||
namespace ncc\Extensions\ZiProto\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
use function sprintf;
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Exception;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto\Exception;
|
||||
|
||||
use function get_class;
|
||||
use function gettype;
|
||||
|
@ -46,7 +49,7 @@ namespace ncc\ZiProto\Exception;
|
|||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct($value, string $message = '', Throwable $previous = null)
|
||||
public function __construct($value, string $message='', Throwable $previous=null)
|
||||
{
|
||||
parent::__construct($message, 0, $previous);
|
||||
$this->value = $value;
|
||||
|
@ -55,7 +58,7 @@ namespace ncc\ZiProto\Exception;
|
|||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue()
|
||||
public function getValue(): mixed
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Exception;
|
||||
namespace ncc\Extensions\ZiProto\Exception;
|
||||
|
||||
use function strlen;
|
||||
|
||||
|
@ -33,13 +33,13 @@ namespace ncc\ZiProto\Exception;
|
|||
/**
|
||||
* @param string $buffer
|
||||
* @param int $offset
|
||||
* @param int $expectedLength
|
||||
* @param int $expected_length
|
||||
* @return InsufficientDataException
|
||||
*/
|
||||
public static function unexpectedLength(string $buffer, int $offset, int $expectedLength) : self
|
||||
public static function unexpectedLength(string $buffer, int $offset, int $expected_length) : self
|
||||
{
|
||||
$actualLength = strlen($buffer) - $offset;
|
||||
$message = "Not enough data to unpack: expected $expectedLength, got $actualLength.";
|
||||
$actual_length = strlen($buffer) - $offset;
|
||||
$message = "Not enough data to unpack: expected $expected_length, got $actual_length.";
|
||||
return new self($message);
|
||||
}
|
||||
}
|
|
@ -1,26 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Exception;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto\Exception;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Exception;
|
||||
namespace ncc\Extensions\ZiProto\Exception;
|
||||
|
||||
use function array_pop;
|
||||
use function count;
|
||||
|
@ -35,15 +35,15 @@ namespace ncc\ZiProto\Exception;
|
|||
class InvalidOptionException extends InvalidArgumentException
|
||||
{
|
||||
/**
|
||||
* @param string $invalidOption
|
||||
* @param array $validOptions
|
||||
* @param string $invalid_option
|
||||
* @param array $valid_options
|
||||
* @return InvalidOptionException
|
||||
*/
|
||||
public static function outOfRange(string $invalidOption, array $validOptions) : self
|
||||
public static function outOfRange(string $invalid_option, array $valid_options) : 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.");
|
||||
$use = count($valid_options) > 2
|
||||
? sprintf('one of %2$s or %1$s', array_pop($valid_options), implode(', ', $valid_options))
|
||||
: implode(' or ', $valid_options);
|
||||
return new self("Invalid option $invalid_option, use $use.");
|
||||
}
|
||||
}
|
|
@ -1,45 +1,45 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/**
|
||||
* Class Ext
|
||||
* @package ZiProto
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto;
|
||||
|
||||
final class Ext
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $type;
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $data;
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* Ext constructor.
|
||||
*
|
||||
* @param int $type
|
||||
* @param string $data
|
||||
*/
|
||||
|
@ -48,4 +48,20 @@ namespace ncc\ZiProto;
|
|||
$this->type = $type;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getType(): int
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getData(): string
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
|
@ -1,27 +1,31 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto;
|
||||
|
||||
use JsonSerializable;
|
||||
use function array_values;
|
||||
use function chr;
|
||||
use function count;
|
||||
|
@ -33,10 +37,10 @@ namespace ncc\ZiProto;
|
|||
use function pack;
|
||||
use function preg_match;
|
||||
use function strlen;
|
||||
use ncc\ZiProto\Abstracts\Regex;
|
||||
use ncc\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\ZiProto\Exception\EncodingFailedException;
|
||||
use ncc\ncc\ZiProto\TypeTransformer\Validator;
|
||||
use ncc\Extensions\ZiProto\Abstracts\Regex;
|
||||
use ncc\Extensions\ZiProto\Exception\InvalidOptionException;
|
||||
use ncc\Extensions\ZiProto\Exception\EncodingFailedException;
|
||||
use ncc\Extensions\ZiProto\TypeTransformer\Validator;
|
||||
|
||||
/**
|
||||
* Class Packet
|
||||
|
@ -47,41 +51,43 @@ namespace ncc\ZiProto;
|
|||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isDetectStrBin;
|
||||
private $bin_mode;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isForceStr;
|
||||
private $force_string;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isDetectArrMap;
|
||||
private $detect_array_map;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isForceArr;
|
||||
private $force_array;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isForceFloat32;
|
||||
private $force_float32;
|
||||
|
||||
/**
|
||||
* @var Validator[]|null
|
||||
* @var Validator[]
|
||||
*/
|
||||
private $transformers;
|
||||
|
||||
/**
|
||||
* @param EncodingOptions|int|null $options
|
||||
* Packet constructor.
|
||||
*
|
||||
* @param int|EncodingOptions|null $options
|
||||
* @see EncodingOptions
|
||||
* @throws InvalidOptionException
|
||||
*/
|
||||
public function __construct($options = null)
|
||||
public function __construct(int|EncodingOptions|null $options=null)
|
||||
{
|
||||
if (null === $options)
|
||||
if ($options === null)
|
||||
{
|
||||
$options = EncodingOptions::fromDefaults();
|
||||
}
|
||||
|
@ -90,21 +96,23 @@ namespace ncc\ZiProto;
|
|||
$options = EncodingOptions::fromBitmask($options);
|
||||
}
|
||||
|
||||
$this->isDetectStrBin = $options->isDetectStrBinMode();
|
||||
$this->isForceStr = $options->isForceStrMode();
|
||||
$this->isDetectArrMap = $options->isDetectArrMapMode();
|
||||
$this->isForceArr = $options->isForceArrMode();
|
||||
$this->isForceFloat32 = $options->isForceFloat32Mode();
|
||||
$this->bin_mode = $options->isDetectStrBinMode();
|
||||
$this->force_string = $options->isForceStrMode();
|
||||
$this->detect_array_map = $options->isDetectArrMapMode();
|
||||
$this->force_array = $options->isForceArrMode();
|
||||
$this->force_float32 = $options->isForceFloat32Mode();
|
||||
$this->transformers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a transformer.
|
||||
*
|
||||
* @param Validator $transformer
|
||||
* @return Packet
|
||||
*/
|
||||
public function registerTransformer(Validator $transformer) : self
|
||||
public function registerTransformer(Validator $transformer): self
|
||||
{
|
||||
$this->transformers[] = $transformer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -121,12 +129,12 @@ namespace ncc\ZiProto;
|
|||
|
||||
if (is_string($value))
|
||||
{
|
||||
if ($this->isForceStr)
|
||||
if ($this->force_string)
|
||||
{
|
||||
return $this->encodeStr($value);
|
||||
}
|
||||
|
||||
if ($this->isDetectStrBin)
|
||||
if ($this->bin_mode)
|
||||
{
|
||||
return preg_match(Regex::UTF8_REGEX, $value)
|
||||
? $this->encodeStr($value)
|
||||
|
@ -138,14 +146,14 @@ namespace ncc\ZiProto;
|
|||
|
||||
if (is_array($value))
|
||||
{
|
||||
if ($this->isDetectArrMap)
|
||||
if ($this->detect_array_map)
|
||||
{
|
||||
return array_values($value) === $value
|
||||
? $this->encodeArray($value)
|
||||
: $this->encodeMap($value);
|
||||
}
|
||||
|
||||
return $this->isForceArr ? $this->encodeArray($value) : $this->encodeMap($value);
|
||||
return $this->force_array ? $this->encodeArray($value) : $this->encodeMap($value);
|
||||
}
|
||||
|
||||
if (null === $value)
|
||||
|
@ -165,7 +173,12 @@ namespace ncc\ZiProto;
|
|||
|
||||
if ($value instanceof Ext)
|
||||
{
|
||||
return $this->encodeExt($value->type, $value->data);
|
||||
return $this->encodeExt($value->getType(), $value->getData());
|
||||
}
|
||||
|
||||
if($value instanceof JsonSerializable)
|
||||
{
|
||||
return $this->encode($value->jsonSerialize());
|
||||
}
|
||||
|
||||
if ($this->transformers)
|
||||
|
@ -259,7 +272,7 @@ namespace ncc\ZiProto;
|
|||
*/
|
||||
public function encodeFloat($float): string
|
||||
{
|
||||
return $this->isForceFloat32
|
||||
return $this->force_float32
|
||||
? "\xca". pack('G', $float)
|
||||
: "\xcb". pack('E', $float);
|
||||
}
|
||||
|
@ -354,7 +367,7 @@ namespace ncc\ZiProto;
|
|||
{
|
||||
$data = $this->encodeMapHeader(count($map));
|
||||
|
||||
if ($this->isForceStr)
|
||||
if ($this->force_string)
|
||||
{
|
||||
foreach ($map as $key => $val)
|
||||
{
|
||||
|
@ -365,7 +378,7 @@ namespace ncc\ZiProto;
|
|||
return $data;
|
||||
}
|
||||
|
||||
if ($this->isDetectStrBin)
|
||||
if ($this->bin_mode)
|
||||
{
|
||||
foreach ($map as $key => $val)
|
||||
{
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Type;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto\Type;
|
||||
|
||||
/**
|
||||
* Class Binary
|
||||
|
@ -31,7 +34,7 @@ namespace ncc\ZiProto\Type;
|
|||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $data;
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* Binary constructor.
|
||||
|
@ -41,4 +44,12 @@ namespace ncc\ZiProto\Type;
|
|||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getData(): string
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
|
@ -1,26 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\Type;
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\Extensions\ZiProto\Type;
|
||||
|
||||
/**
|
||||
* Class Map
|
||||
|
@ -31,7 +34,7 @@ namespace ncc\ZiProto\Type;
|
|||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $map;
|
||||
private $map;
|
||||
|
||||
/**
|
||||
* Map constructor.
|
||||
|
@ -41,4 +44,12 @@ namespace ncc\ZiProto\Type;
|
|||
{
|
||||
$this->map = $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMap(): array
|
||||
{
|
||||
return $this->map;
|
||||
}
|
||||
}
|
|
@ -1,29 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ncc\ZiProto\TypeTransformer;
|
||||
namespace ncc\Extensions\ZiProto\TypeTransformer;
|
||||
|
||||
use ncc\ZiProto\Packet;
|
||||
use ncc\ZiProto\Type\Binary;
|
||||
use ncc\Extensions\ZiProto\Packet;
|
||||
use ncc\Extensions\ZiProto\Type\Binary;
|
||||
|
||||
/**
|
||||
* Class BinaryTransformer
|
||||
|
@ -40,7 +40,7 @@ namespace ncc\ncc\ZiProto\TypeTransformer;
|
|||
{
|
||||
if ($value instanceof Binary)
|
||||
{
|
||||
return $packer->encodeBin($value->data);
|
||||
return $packer->encodeBin($value->getData());
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ncc\ZiProto\TypeTransformer;
|
||||
namespace ncc\Extensions\ZiProto\TypeTransformer;
|
||||
|
||||
use ncc\ZiProto\BufferStream;
|
||||
use ncc\Extensions\ZiProto\BufferStream;
|
||||
|
||||
/**
|
||||
* Interface Extension
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto\TypeTransformer;
|
||||
namespace ncc\Extensions\ZiProto\TypeTransformer;
|
||||
|
||||
use ncc\ZiProto\Packet;
|
||||
use ncc\ZiProto\Type\Map;
|
||||
use ncc\Extensions\ZiProto\Packet;
|
||||
use ncc\Extensions\ZiProto\Type\Map;
|
||||
|
||||
/**
|
||||
* Class MapTransformer
|
||||
|
@ -40,7 +40,7 @@ namespace ncc\ZiProto\TypeTransformer;
|
|||
{
|
||||
if ($value instanceof Map)
|
||||
{
|
||||
return $packer->encodeMap($value->map);
|
||||
return $packer->encodeMap($value->getMap());
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ncc\ZiProto\TypeTransformer;
|
||||
namespace ncc\Extensions\ZiProto\TypeTransformer;
|
||||
|
||||
use ncc\ZiProto\Packet;
|
||||
use ncc\Extensions\ZiProto\Packet;
|
||||
|
||||
/**
|
||||
* Interface Validator
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ncc\ZiProto;
|
||||
namespace ncc\Extensions\ZiProto;
|
||||
|
||||
use ncc\ZiProto\Exception\DecodingFailedException;
|
||||
use ncc\ZiProto\Exception\EncodingFailedException;
|
||||
use ncc\ZiProto\Exception\InvalidOptionException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* ZiProto Class
|
||||
|
@ -35,30 +35,42 @@ namespace ncc\ZiProto;
|
|||
class ZiProto
|
||||
{
|
||||
/**
|
||||
* Encodes the given value to a msgpack string.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param EncodingOptions|int|null $options
|
||||
*
|
||||
* @throws InvalidOptionException
|
||||
* @throws EncodingFailedException
|
||||
*
|
||||
* @param int|null $options
|
||||
* @see EncodingOptions
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($value, $options = null) : string
|
||||
public static function encode(mixed $value, ?int $options=null) : string
|
||||
{
|
||||
return (new Packet($options))->encode($value);
|
||||
try
|
||||
{
|
||||
return (new Packet($options))->encode($value);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the given msgpack string.
|
||||
*
|
||||
* @param string $data
|
||||
* @param DecodingOptions|int|null $options
|
||||
*
|
||||
* @throws InvalidOptionException
|
||||
* @throws DecodingFailedException
|
||||
*
|
||||
* @return mixed
|
||||
* @param int|null $options
|
||||
* @see DecodingOptions
|
||||
* @return array|bool|int|mixed|Ext|resource|string|null
|
||||
*/
|
||||
public static function decode(string $data, $options = null)
|
||||
public static function decode(string $data, ?int $options=null): mixed
|
||||
{
|
||||
return (new BufferStream($data, $options))->decode();
|
||||
try
|
||||
{
|
||||
return (new BufferStream($data, $options))->decode();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
use ncc\Exceptions\BuildException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Managers\ProjectManager;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\ProjectConfiguration;
|
||||
|
||||
|
@ -34,60 +35,15 @@
|
|||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* @param ProjectConfiguration $project
|
||||
* @param string $path
|
||||
* @param ProjectManager $project_manager
|
||||
*/
|
||||
public function __construct(ProjectConfiguration $project, string $path);
|
||||
public function __construct(ProjectManager $project_manager);
|
||||
|
||||
/**
|
||||
* Prepares the package for the build process, this method is called before build()
|
||||
* Builds the project and returns the path to the built package
|
||||
*
|
||||
* @param string $build_configuration The build configuration to use to build the project
|
||||
* @return void
|
||||
* @param string $build_configuration
|
||||
* @return string
|
||||
*/
|
||||
public function prepare(string $build_configuration=BuildConfigurationValues::DEFAULT): void;
|
||||
|
||||
/**
|
||||
* Executes the compiler process in the correct order and returns the finalized Package object
|
||||
*
|
||||
* @return Package|null
|
||||
* @throws BuildException
|
||||
* @throws PathNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public function build(): ?Package;
|
||||
|
||||
/**
|
||||
* Compiles the components of the package
|
||||
*
|
||||
* @return void
|
||||
* @throws PathNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public function compileComponents(): void;
|
||||
|
||||
/**
|
||||
* Compiles the resources of the package
|
||||
*
|
||||
* @return void
|
||||
* @throws PathNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public function compileResources(): void;
|
||||
|
||||
/**
|
||||
* Compiles the execution policies of the package
|
||||
*
|
||||
* @return void
|
||||
* @throws PathNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public function compileExecutionPolicies(): void;
|
||||
|
||||
/**
|
||||
* Returns the current state of the package
|
||||
*
|
||||
* @return Package|null
|
||||
*/
|
||||
public function getPackage(): ?Package;
|
||||
public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string;
|
||||
}
|
|
@ -29,19 +29,12 @@
|
|||
interface RunnerInterface
|
||||
{
|
||||
/**
|
||||
* Processes the ExecutionPolicy
|
||||
* Executes the unit and returns the exit code of the process
|
||||
*
|
||||
* @param string $path
|
||||
* @param ExecutionPolicy $policy
|
||||
* @return ExecutionUnit
|
||||
* @throws IOException
|
||||
* @param ExecutionUnit $unit The execution unit to execute
|
||||
* @param array $args The arguments to pass to the execution unit
|
||||
* @param bool $local Whether to execute the execution unit locally on disk or from a memory buffer
|
||||
* @return int The exit code of the process
|
||||
*/
|
||||
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit;
|
||||
|
||||
/**
|
||||
* Returns the file extension to use for the target file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFileExtension(): string;
|
||||
public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int;
|
||||
}
|
|
@ -36,7 +36,7 @@
|
|||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class CredentialManager
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use RuntimeException;
|
||||
|
||||
class ExecutionPointerManager
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\RuntimeCache;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class PackageLockManager
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load diff
1030
src/ncc/Managers/PackageManagerOld.php
Normal file
1030
src/ncc/Managers/PackageManagerOld.php
Normal file
File diff suppressed because it is too large
Load diff
|
@ -25,9 +25,10 @@
|
|||
|
||||
namespace ncc\Managers;
|
||||
|
||||
use ncc\Classes\PhpExtension\ExecutableCompiler;
|
||||
use ncc\Classes\PhpExtension\NccCompiler;
|
||||
use ncc\Classes\PhpExtension\PhpCliTemplate;
|
||||
use ncc\Classes\PhpExtension\PhpLibraryTemplate;
|
||||
use ncc\Classes\PhpExtension\Templates\CliTemplate;
|
||||
use ncc\Classes\PhpExtension\Templates\LibraryTemplate;
|
||||
use ncc\Enums\BuildOutputType;
|
||||
use ncc\Enums\CompilerExtensions;
|
||||
use ncc\Enums\ComponentFileExtensions;
|
||||
|
@ -155,8 +156,10 @@
|
|||
|
||||
return match (strtolower($this->project_configuration->getProject()->getCompiler()->getExtension()))
|
||||
{
|
||||
CompilerExtensions::PHP => match (strtolower($configuration->getBuildType())) {
|
||||
CompilerExtensions::PHP => match (strtolower($configuration->getBuildType()))
|
||||
{
|
||||
BuildOutputType::NCC_PACKAGE => (new NccCompiler($this))->build($build_configuration),
|
||||
BuildOutputType::EXECUTABLE => (new ExecutableCompiler($this))->build($build_configuration),
|
||||
default => throw new BuildException(sprintf('php cannot produce the build type \'%s\'', $configuration->getBuildType())),
|
||||
},
|
||||
default => throw new NotSupportedException(sprintf('The compiler extension \'%s\' is not supported', $this->project_configuration->getProject()->getCompiler()->getExtension())),
|
||||
|
@ -178,11 +181,11 @@
|
|||
switch(strtolower($template_name))
|
||||
{
|
||||
case ProjectTemplates::PHP_CLI:
|
||||
PhpCliTemplate::applyTemplate($this);
|
||||
CliTemplate::applyTemplate($this);
|
||||
break;
|
||||
|
||||
case ProjectTemplates::PHP_LIBRARY:
|
||||
PhpLibraryTemplate::applyTemplate($this);
|
||||
LibraryTemplate::applyTemplate($this);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -283,7 +286,6 @@
|
|||
{
|
||||
$configuration = $this->project_configuration->getBuild()->getBuildConfiguration($build_configuration);
|
||||
|
||||
/** @noinspection ArrayMergeMissUseInspection */
|
||||
return array_merge(
|
||||
$configuration->getDefineConstants(),
|
||||
$this->project_configuration->getBuild()->getDefineConstants()
|
||||
|
@ -301,7 +303,6 @@
|
|||
{
|
||||
$configuration = $this->project_configuration->getBuild()->getBuildConfiguration($build_configuration);
|
||||
|
||||
/** @noinspection ArrayMergeMissUseInspection */
|
||||
return array_merge(
|
||||
$configuration->getOptions(),
|
||||
$this->project_configuration->getBuild()->getOptions()
|
||||
|
@ -314,7 +315,7 @@
|
|||
* @param string $project_path The directory for the project to be initialized in
|
||||
* @param string $name The name of the project eg; ProjectLib
|
||||
* @param string $package The standard package name eg; com.example.project
|
||||
* @param Compiler $compiler The compiler to use for this project
|
||||
* @param string $compiler The compiler to use for this project
|
||||
* @param array $options An array of options to use when initializing the project
|
||||
* @return ProjectManager
|
||||
* @throws ConfigurationException
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class RemoteSourcesManager
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class SymlinkManager
|
||||
{
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
use ncc\Objects\Package\Component;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\Package\Metadata;
|
||||
use ncc\Objects\Package\Installer;
|
||||
use ncc\Objects\Package\MagicBytes;
|
||||
use ncc\Objects\Package\Resource;
|
||||
use ncc\Objects\ProjectConfiguration\Assembly;
|
||||
|
@ -43,7 +42,7 @@
|
|||
use ncc\Objects\ProjectConfiguration\Dependency;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
|
||||
class Package implements BytecodeObjectInterface
|
||||
{
|
||||
|
@ -75,13 +74,6 @@
|
|||
*/
|
||||
private $dependencies;
|
||||
|
||||
/**
|
||||
* The installer object that is used to install the package if the package is install-able
|
||||
*
|
||||
* @var Installer|null
|
||||
*/
|
||||
private $installer;
|
||||
|
||||
/**
|
||||
* An array of execution units defined in the package
|
||||
*
|
||||
|
|
|
@ -24,10 +24,17 @@
|
|||
|
||||
namespace ncc\Objects\Package;
|
||||
|
||||
use Exception;
|
||||
use ncc\Classes\PhpExtension\AstWalker;
|
||||
use ncc\Enums\ComponentDataType;
|
||||
use ncc\Enums\Flags\ComponentFlags;
|
||||
use ncc\Enums\Options\ComponentDecodeOptions;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use ncc\Interfaces\BytecodeObjectInterface;
|
||||
use ncc\ThirdParty\nikic\PhpParser\PrettyPrinter\Standard;
|
||||
use ncc\Utilities\Functions;
|
||||
use RuntimeException;
|
||||
|
||||
class Component implements BytecodeObjectInterface
|
||||
{
|
||||
|
@ -162,11 +169,63 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the decoded data of the component, this will decode the data based on the data type and flags of the
|
||||
* component.
|
||||
*
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function getData(): string
|
||||
public function getData(array $options=[]): string
|
||||
{
|
||||
return $this->data;
|
||||
switch($this->data_type)
|
||||
{
|
||||
case ComponentDataType::PLAIN:
|
||||
case ComponentDataType::BINARY:
|
||||
return $this->data;
|
||||
|
||||
case ComponentDataType::BASE64_ENCODED:
|
||||
if(in_array(ComponentFlags::PHP_B64, $this->flags, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
if(in_array(ComponentDecodeOptions::AS_FILE, $options, true))
|
||||
{
|
||||
return (new Standard())->prettyPrintFile(AstWalker::decodeRecursive(base64_decode($this->data)));
|
||||
}
|
||||
|
||||
return (new Standard())->prettyPrint(AstWalker::decodeRecursive(base64_decode($this->data)));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new RuntimeException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_B64, $e->getMessage()), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
return base64_decode($this->data);
|
||||
|
||||
case ComponentDataType::AST:
|
||||
if(in_array(ComponentFlags::PHP_AST, $this->flags, true))
|
||||
{
|
||||
try
|
||||
{
|
||||
if(in_array(ComponentDecodeOptions::AS_FILE, $options, true))
|
||||
{
|
||||
return (new Standard())->prettyPrintFile(AstWalker::decodeRecursive(ZiProto::decode($this->data)));
|
||||
}
|
||||
|
||||
return (new Standard())->prettyPrint(AstWalker::decodeRecursive(ZiProto::decode($this->data)));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new RuntimeException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_AST, $e->getMessage()), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Cannot decode component %s with data type %s because the component does not have a flag to decode it properly', $this->name, 'AST'));
|
||||
|
||||
default:
|
||||
throw new RuntimeException(sprintf('Unknown component data type "%s"', $this->data_type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
|||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Interfaces\BytecodeObjectInterface;
|
||||
use ncc\Objects\ProjectConfiguration\Compiler;
|
||||
use ncc\Objects\ProjectConfiguration\Installer;
|
||||
use ncc\Objects\ProjectConfiguration\UpdateSource;
|
||||
use ncc\Utilities\Functions;
|
||||
|
||||
|
@ -238,6 +239,8 @@
|
|||
($bytecode ? Functions::cbc('runtime_constants') : 'runtime_constants') => $this->runtime_constants,
|
||||
($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->compiler_version,
|
||||
($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->update_source?->toArray($bytecode)),
|
||||
($bytecode ? Functions::cbc('installer') : 'installer') => ($this->installer?->toArray($bytecode)),
|
||||
($bytecode ? Functions::cbc('main_execution_policy') : 'main_execution_policy') => $this->main_execution_policy,
|
||||
($bytecode ? Functions::cbc('options') : 'options') => $this->options,
|
||||
];
|
||||
}
|
||||
|
@ -259,12 +262,20 @@
|
|||
$object->compiler_version = Functions::array_bc($data, 'compiler_version');
|
||||
$object->update_source = Functions::array_bc($data, 'update_source');
|
||||
$object->options = Functions::array_bc($data, 'options');
|
||||
$object->update_source = Functions::array_bc($data, 'update_source');
|
||||
$object->main_execution_policy = Functions::array_bc($data, 'main_execution_policy');
|
||||
$object->installer = Functions::array_bc($data, 'installer');
|
||||
|
||||
if($object->update_source !== null)
|
||||
{
|
||||
$object->update_source = UpdateSource::fromArray($object->update_source);
|
||||
}
|
||||
|
||||
if($object->installer !== null)
|
||||
{
|
||||
$object->installer = Installer::fromArray($object->installer);
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
|
@ -24,9 +24,10 @@
|
|||
|
||||
namespace ncc\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use ncc\Classes\PackageReader;
|
||||
use ncc\Enums\Versions;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Interfaces\BytecodeObjectInterface;
|
||||
use ncc\Objects\PackageLock\PackageEntry;
|
||||
use ncc\Utilities\Console;
|
||||
|
@ -53,15 +54,36 @@
|
|||
*
|
||||
* @var PackageEntry[]
|
||||
*/
|
||||
private $packages;
|
||||
private $entries;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(array $entries=[], string $package_lock_version=Versions::PACKAGE_LOCK_VERSION, ?int $last_updated_timestamp=null)
|
||||
{
|
||||
$this->package_lock_version = Versions::PACKAGE_LOCK_VERSION;
|
||||
$this->packages = [];
|
||||
$this->entries = $entries;
|
||||
$this->package_lock_version = $package_lock_version;
|
||||
$this->last_updated_timestamp = $last_updated_timestamp ?? time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the package lock structure version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPackageLockVersion(): string
|
||||
{
|
||||
return $this->package_lock_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Unix Timestamp for when this package lock file was last updated
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastUpdatedTimestamp(): int
|
||||
{
|
||||
return $this->last_updated_timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,188 +98,141 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Package $package
|
||||
* @param string $install_path
|
||||
* Adds a new PackageEntry to the PackageLock file from a PackageReader
|
||||
*
|
||||
* @param PackageReader $package_reader
|
||||
* @return void
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function addPackage(Package $package, string $install_path): void
|
||||
public function addPackage(PackageReader $package_reader): void
|
||||
{
|
||||
Console::outVerbose("Adding package {$package->getAssembly()->getPackage()} to package lock file");
|
||||
Console::outVerbose("Adding package {$package_reader->getAssembly()->getPackage()} to package lock file");
|
||||
|
||||
if(!isset($this->packages[$package->getAssembly()->getPackage()]))
|
||||
if(!$this->entryExists($package_reader->getAssembly()->getPackage()))
|
||||
{
|
||||
$package_entry = new PackageEntry();
|
||||
$package_entry->addVersion($package, $install_path, true);
|
||||
$package_entry->setName($package->getAssembly()->getPackage());
|
||||
$package_entry->setUpdateSource($package->getMetadata()->getUpdateSource());
|
||||
$this->packages[$package->getAssembly()->getPackage()] = $package_entry;
|
||||
$this->update();
|
||||
$package_entry = new PackageEntry($package_reader->getAssembly()->getPackage());
|
||||
$package_entry->addVersion($package_reader);
|
||||
$this->addEntry($package_entry);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->packages[$package->getAssembly()->getPackage()]->setUpdateSource($package->getMetadata()->getUpdateSource());
|
||||
$this->packages[$package->getAssembly()->getPackage()]->addVersion($package, $install_path, true);
|
||||
$package_entry = $this->getEntry($package_reader->getAssembly()->getPackage());
|
||||
$package_entry->addVersion($package_reader);
|
||||
$this->addEntry($package_entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns True if the package entry exists
|
||||
*
|
||||
* @param string $package_name
|
||||
* @return bool
|
||||
*/
|
||||
public function entryExists(string $package_name): bool
|
||||
{
|
||||
foreach($this->entries as $entry)
|
||||
{
|
||||
if($entry->getName() === $package_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing package entry
|
||||
*
|
||||
* @param string $package_name
|
||||
* @return PackageEntry
|
||||
*/
|
||||
public function getEntry(string $package_name): PackageEntry
|
||||
{
|
||||
foreach($this->entries as $entry)
|
||||
{
|
||||
if($entry->getName() === $package_name)
|
||||
{
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Package entry %s does not exist', $package_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new package entry to the package lock file
|
||||
*
|
||||
* @param PackageEntry $entry
|
||||
* @param bool $overwrite
|
||||
* @return void
|
||||
*/
|
||||
public function addEntry(PackageEntry $entry, bool $overwrite=true): void
|
||||
{
|
||||
if($this->entryExists($entry->getName()))
|
||||
{
|
||||
if(!$overwrite)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->removeEntry($entry->getName());
|
||||
}
|
||||
|
||||
$this->update();
|
||||
$this->entries[] = $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a package version entry, removes the entire entry if there are no installed versions
|
||||
* Removes a package entry from the package lock file
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @return bool
|
||||
* @param string $package_name
|
||||
* @return void
|
||||
*/
|
||||
public function removePackageVersion(string $package, string $version): bool
|
||||
public function removeEntry(string $package_name): void
|
||||
{
|
||||
Console::outVerbose(sprintf('Removing package %s version %s from package lock file', $package, $version));
|
||||
|
||||
if(isset($this->packages[$package]))
|
||||
foreach($this->entries as $index => $entry)
|
||||
{
|
||||
$r = $this->packages[$package]->removeVersion($version);
|
||||
|
||||
// Remove the entire package entry if there's no installed versions
|
||||
if($r && $this->packages[$package]->getLatestVersion() === null)
|
||||
if($entry->getName() === $package_name)
|
||||
{
|
||||
unset($this->packages[$package]);
|
||||
}
|
||||
|
||||
$this->update();
|
||||
return $r;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an entire package entry
|
||||
*
|
||||
* @param string $package
|
||||
* @return bool
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function removePackage(string $package): bool
|
||||
{
|
||||
Console::outVerbose(sprintf('Removing package %s from package lock file', $package));
|
||||
if(isset($this->packages[$package]))
|
||||
{
|
||||
unset($this->packages[$package]);
|
||||
$this->update();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an existing package entry, returns null if no such entry exists
|
||||
*
|
||||
* @param string $package
|
||||
* @return PackageEntry|null
|
||||
*/
|
||||
public function getPackage(string $package): ?PackageEntry
|
||||
{
|
||||
Console::outDebug(sprintf('getting package %s from package lock file', $package));
|
||||
return $this->packages[$package] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the requested package exists in the package lock
|
||||
*
|
||||
* @param string $package
|
||||
* @param string|null $version
|
||||
* @return bool
|
||||
*/
|
||||
public function packageExists(string $package, ?string $version=null): bool
|
||||
{
|
||||
$package_entry = $this->getPackage($package);
|
||||
|
||||
if($package_entry === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if($version !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$version_entry = $package_entry->getVersion($version);
|
||||
}
|
||||
catch (IOException $e)
|
||||
{
|
||||
unset($e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if($version_entry === null)
|
||||
{
|
||||
return false;
|
||||
unset($this->entries[$index]);
|
||||
$this->update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all packages and their installed versions
|
||||
* Returns an array of package entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPackages(): array
|
||||
public function getEntries(): array
|
||||
{
|
||||
$results = [];
|
||||
|
||||
foreach($this->packages as $package => $entry)
|
||||
{
|
||||
$results[$package] = $entry->getVersions();
|
||||
}
|
||||
|
||||
return $results;
|
||||
return array_map(static function(PackageEntry $entry) {
|
||||
return $entry->getName();
|
||||
}, $this->entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path where the package is installed
|
||||
*
|
||||
* @param string $package_name
|
||||
* @param string $version
|
||||
* @return string
|
||||
*/
|
||||
public function getPackageLockVersion(): string
|
||||
public function getPath(string $package_name, string $version): string
|
||||
{
|
||||
return $this->package_lock_version;
|
||||
return $this->getEntry($package_name)->getPath($version);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $package_lock_version
|
||||
*/
|
||||
public function setPackageLockVersion(string $package_lock_version): void
|
||||
{
|
||||
$this->package_lock_version = $package_lock_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLastUpdatedTimestamp(): int
|
||||
{
|
||||
return $this->last_updated_timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $last_updated_timestamp
|
||||
*/
|
||||
public function setLastUpdatedTimestamp(int $last_updated_timestamp): void
|
||||
{
|
||||
$this->last_updated_timestamp = $last_updated_timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @param bool $bytecode
|
||||
* @return array
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
$package_entries = [];
|
||||
foreach($this->packages as $entry)
|
||||
foreach($this->entries as $entry)
|
||||
{
|
||||
$package_entries[] = $entry->toArray($bytecode);
|
||||
}
|
||||
|
@ -265,33 +240,30 @@
|
|||
return [
|
||||
($bytecode ? Functions::cbc('package_lock_version') : 'package_lock_version') => $this->package_lock_version,
|
||||
($bytecode ? Functions::cbc('last_updated_timestamp') : 'last_updated_timestamp') => $this->last_updated_timestamp,
|
||||
($bytecode ? Functions::cbc('packages') : 'packages') => $package_entries
|
||||
($bytecode ? Functions::cbc('entries') : 'entries') => $package_entries
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return static
|
||||
* @inheritDoc
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
$entries_array = Functions::array_bc($data, 'entries') ?? [];
|
||||
$entries = array_map(static function($entry) {
|
||||
return PackageEntry::fromArray($entry);
|
||||
}, $entries_array);
|
||||
|
||||
$packages = Functions::array_bc($data, 'packages');
|
||||
if($packages !== null)
|
||||
|
||||
$package_lock_version = Functions::array_bc($data, 'package_lock_version') ?? Versions::PACKAGE_LOCK_VERSION;
|
||||
$last_updated_timestamp = Functions::array_bc($data, 'last_updated_timestamp') ?? time();
|
||||
|
||||
if($package_lock_version === null)
|
||||
{
|
||||
foreach($packages as $_datum)
|
||||
{
|
||||
$entry = PackageEntry::fromArray($_datum);
|
||||
$object->packages[$entry->getName()] = $entry;
|
||||
}
|
||||
throw new ConfigurationException('Package lock version is missing');
|
||||
}
|
||||
|
||||
$object->package_lock_version = Functions::array_bc($data, 'package_lock_version');
|
||||
$object->last_updated_timestamp = Functions::array_bc($data, 'last_updated_timestamp');
|
||||
|
||||
return $object;
|
||||
return new self($entries, $package_lock_version, $last_updated_timestamp);
|
||||
}
|
||||
}
|
|
@ -24,18 +24,23 @@
|
|||
|
||||
namespace ncc\Objects\PackageLock;
|
||||
|
||||
use ncc\Enums\Scopes;
|
||||
use InvalidArgumentException;
|
||||
use ncc\Classes\PackageReader;
|
||||
use ncc\Enums\FileDescriptor;
|
||||
use ncc\Enums\Versions;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use ncc\Interfaces\BytecodeObjectInterface;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\Package\Metadata;
|
||||
use ncc\Objects\ProjectConfiguration\Assembly;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Objects\ProjectConfiguration\Installer;
|
||||
use ncc\Objects\ProjectConfiguration\UpdateSource;
|
||||
use ncc\ThirdParty\jelix\Version\VersionComparator;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class PackageEntry implements BytecodeObjectInterface
|
||||
{
|
||||
|
@ -46,13 +51,6 @@
|
|||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* The latest version of the package entry, this is updated automatically
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $latest_version;
|
||||
|
||||
/**
|
||||
* An array of installed versions for this package
|
||||
*
|
||||
|
@ -70,25 +68,114 @@
|
|||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(string $name, array $versions=[])
|
||||
{
|
||||
$this->versions = [];
|
||||
$this->name = $name;
|
||||
$this->versions = $versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches and returns a version of the package
|
||||
* Returns the name of the package entry
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Returns the update source of the package entry
|
||||
*
|
||||
* @return UpdateSource|null
|
||||
*/
|
||||
public function getUpdateSource(): ?UpdateSource
|
||||
{
|
||||
return $this->update_source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to where the package is installed
|
||||
*
|
||||
* @param string $version
|
||||
* @param bool $throw_exception
|
||||
* @return VersionEntry|null
|
||||
* @throws IOException
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion(string $version, bool $throw_exception=false): ?VersionEntry
|
||||
public function getPath(string $version): string
|
||||
{
|
||||
if($version === Versions::LATEST && $this->latest_version !== null)
|
||||
return $this->getVersion($version)->getPath($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new version entry to the package, if overwrite is true then
|
||||
* the entry will be overwritten if it exists, otherwise it will return
|
||||
* false.
|
||||
*
|
||||
* @param PackageReader $package_reader
|
||||
* @param bool $overwrite
|
||||
* @return bool
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public function addVersion(PackageReader $package_reader, bool $overwrite=false): bool
|
||||
{
|
||||
if($this->versionExists($package_reader->getAssembly()->getVersion()))
|
||||
{
|
||||
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
|
||||
$version = $this->latest_version;
|
||||
if(!$overwrite)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->removeVersion($package_reader->getAssembly()->getVersion());
|
||||
}
|
||||
|
||||
$version_entry = new VersionEntry($package_reader->getAssembly()->getVersion());
|
||||
$version_entry->setMainExecutionPolicy($package_reader->getMetadata()->getMainExecutionPolicy());
|
||||
|
||||
//foreach($package_reader->getDependencies() as $dependency)
|
||||
//{
|
||||
// TODO: Implement this functionality
|
||||
//}
|
||||
|
||||
foreach($package_reader->getExecutionUnits() as $unit)
|
||||
{
|
||||
$version_entry->addExecutionPolicy($package_reader->getExecutionUnit($unit)->getExecutionPolicy());
|
||||
}
|
||||
|
||||
$this->versions[] = $version_entry;
|
||||
$this->update_source =$package_reader->getMetadata()->getUpdateSource();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns True if the given version exists in the entry
|
||||
*
|
||||
* @param string $version
|
||||
* @return bool
|
||||
*/
|
||||
public function versionExists(string $version): bool
|
||||
{
|
||||
foreach($this->versions as $versionEntry)
|
||||
{
|
||||
if($versionEntry->getVersion() === $version)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version entry by version
|
||||
*
|
||||
* @param string $version
|
||||
* @return VersionEntry
|
||||
*/
|
||||
public function getVersion(string $version): VersionEntry
|
||||
{
|
||||
if($version === Versions::LATEST)
|
||||
{
|
||||
$version = $this->getLatestVersion();
|
||||
}
|
||||
|
||||
foreach($this->versions as $versionEntry)
|
||||
|
@ -99,20 +186,54 @@
|
|||
}
|
||||
}
|
||||
|
||||
if($throw_exception)
|
||||
{
|
||||
throw new IOException(sprintf('Version %s of %s is not installed', $version, $this->name));
|
||||
}
|
||||
|
||||
return null;
|
||||
throw new InvalidArgumentException(sprintf('Version %s does not exist in package %s', $version, $this->name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes version entry from the package
|
||||
* Updates and returns the latest version of this package entry
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getLatestVersion(): string
|
||||
{
|
||||
$latest_version = null;
|
||||
|
||||
foreach($this->versions as $version)
|
||||
{
|
||||
$version = $version->getVersion();
|
||||
|
||||
if($latest_version === null)
|
||||
{
|
||||
$latest_version = $version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(VersionComparator::compareVersion($version, $latest_version))
|
||||
{
|
||||
$latest_version = $version;
|
||||
}
|
||||
}
|
||||
|
||||
return $latest_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all versions installed
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVersions(): array
|
||||
{
|
||||
return array_map(static function(VersionEntry $versionEntry) {
|
||||
return $versionEntry->getVersion();
|
||||
}, $this->versions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes version entry from the package entry
|
||||
*
|
||||
* @param string $version
|
||||
* @return bool
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public function removeVersion(string $version): bool
|
||||
{
|
||||
|
@ -133,7 +254,6 @@
|
|||
if($found_node)
|
||||
{
|
||||
unset($this->versions[$count]);
|
||||
$this->updateLatestVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -141,157 +261,121 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Adds a new version entry to the package, if overwrite is true then
|
||||
* the entry will be overwritten if it exists, otherwise it will return
|
||||
* false.
|
||||
* Returns the assembly of the package entry
|
||||
*
|
||||
* @param Package $package
|
||||
* @param string $install_path
|
||||
* @param bool $overwrite
|
||||
* @return bool
|
||||
*/
|
||||
public function addVersion(Package $package, string $install_path, bool $overwrite=false): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
if ($this->getVersion($package->getAssembly()->getVersion()) !== null)
|
||||
{
|
||||
if(!$overwrite)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->removeVersion($package->getAssembly()->getVersion());
|
||||
}
|
||||
}
|
||||
catch (IOException $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
|
||||
$version = new VersionEntry();
|
||||
$version->setVersion($package->getAssembly()->getVersion());
|
||||
$version->setCompiler($package->getMetadata()->getCompilerExtension());
|
||||
$version->setExecutionUnits($package->getExecutionUnits());
|
||||
$version->main_execution_policy = $package->getMainExecutionPolicy();
|
||||
$version->location = $install_path;
|
||||
|
||||
foreach($version->getExecutionUnits() as $unit)
|
||||
{
|
||||
$unit->setData(null);
|
||||
}
|
||||
|
||||
foreach($package->getDependencies() as $dependency)
|
||||
{
|
||||
$version->addDependency(new DependencyEntry($dependency));
|
||||
}
|
||||
|
||||
$this->versions[] = $version;
|
||||
$this->updateLatestVersion();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates and returns the latest version of this package entry
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function updateLatestVersion(): void
|
||||
{
|
||||
$latest_version = null;
|
||||
|
||||
foreach($this->versions as $version)
|
||||
{
|
||||
$version = $version->getVersion();
|
||||
|
||||
if($latest_version === null)
|
||||
{
|
||||
$latest_version = $version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(VersionComparator::compareVersion($version, $latest_version))
|
||||
{
|
||||
$latest_version = $version;
|
||||
}
|
||||
}
|
||||
|
||||
$this->latest_version = $latest_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getLatestVersion(): ?string
|
||||
{
|
||||
return $this->latest_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all versions installed
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVersions(): array
|
||||
{
|
||||
$r = [];
|
||||
|
||||
foreach($this->versions as $version)
|
||||
{
|
||||
$r[] = $version->getVersion();
|
||||
}
|
||||
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @param string $version
|
||||
* @return Assembly
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public function getDataPath(): string
|
||||
public function getAssembly(string $version=Versions::LATEST): Assembly
|
||||
{
|
||||
$path = PathFinder::getPackageDataPath($this->name);
|
||||
|
||||
if(!file_exists($path) && Resolver::resolveScope() === Scopes::SYSTEM)
|
||||
$assembly_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::ASSEMBLY;
|
||||
if(!is_file($assembly_path))
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
$filesystem->mkdir($path);
|
||||
throw new IOException(sprintf('Assembly file for package %s version %s does not exist (Expected %s)', $this->name, $version, $assembly_path));
|
||||
}
|
||||
|
||||
return $path;
|
||||
return Assembly::fromArray(ZiProto::decode(IO::fread($assembly_path)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the metadata of the package entry
|
||||
*
|
||||
* @param string $version
|
||||
* @return Metadata
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public function getMetadata(string $version=Versions::LATEST): Metadata
|
||||
{
|
||||
$metadata_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::METADATA;
|
||||
if(!is_file($metadata_path))
|
||||
{
|
||||
throw new IOException(sprintf('Metadata file for package %s version %s does not exist (Expected %s)', $this->name, $version, $metadata_path));
|
||||
}
|
||||
|
||||
return Metadata::fromArray(ZiProto::decode(IO::fread($metadata_path)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional. Returns the installer details of the package entry
|
||||
*
|
||||
* @param string $version
|
||||
* @return Installer|null
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public function getInstaller(string $version=Versions::LATEST): ?Installer
|
||||
{
|
||||
$installer_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::INSTALLER;
|
||||
if(!is_file($installer_path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Installer::fromArray(ZiProto::decode(IO::fread($installer_path)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class map of the package entry
|
||||
*
|
||||
* @param string $version
|
||||
* @return array
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public function getClassMap(string $version=Versions::LATEST): array
|
||||
{
|
||||
$class_map_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::CLASS_MAP;
|
||||
if(!is_file($class_map_path))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return ZiProto::decode(IO::fread($class_map_path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the execution policy of the package entry
|
||||
*
|
||||
* @param string $policy_name
|
||||
* @param string $version
|
||||
* @return ExecutionPolicy
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws PathNotFoundException
|
||||
*/
|
||||
public function getExecutionPolicy(string $policy_name, string $version=Versions::LATEST): ExecutionPolicy
|
||||
{
|
||||
$execution_policy_path = $this->getPath($version) . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $policy_name . '.policy';
|
||||
if(!is_file($execution_policy_path))
|
||||
{
|
||||
throw new IOException(sprintf('Execution policy %s for package %s version %s does not exist (Expected %s)', $policy_name, $this->name, $version, $execution_policy_path));
|
||||
}
|
||||
|
||||
return ExecutionPolicy::fromArray(ZiProto::decode(IO::fread($execution_policy_path)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the execution binary of the package entry of a given policy name
|
||||
*
|
||||
* @param string $policy_name
|
||||
* @param string $version
|
||||
* @return string
|
||||
* @throws IOException
|
||||
*/
|
||||
public function getName(): string
|
||||
public function getExecutionBinaryPath(string $policy_name, string $version=Versions::LATEST): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
$execution_binary_path = $this->getPath($version) . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $policy_name;
|
||||
if(!is_file($execution_binary_path))
|
||||
{
|
||||
throw new IOException(sprintf('Execution binary %s for package %s version %s does not exist (Expected %s)', $policy_name, $this->name, $version, $execution_binary_path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName(string $name): void
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UpdateSource|null
|
||||
*/
|
||||
public function getUpdateSource(): ?UpdateSource
|
||||
{
|
||||
return $this->update_source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UpdateSource|null $update_source
|
||||
*/
|
||||
public function setUpdateSource(?UpdateSource $update_source): void
|
||||
{
|
||||
$this->update_source = $update_source;
|
||||
return $execution_binary_path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -311,7 +395,6 @@
|
|||
|
||||
return [
|
||||
($bytecode ? Functions::cbc('name') : 'name') => $this->name,
|
||||
($bytecode ? Functions::cbc('latest_version') : 'latest_version') => $this->latest_version,
|
||||
($bytecode ? Functions::cbc('versions') : 'versions') => $versions,
|
||||
($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->update_source?->toArray($bytecode)),
|
||||
];
|
||||
|
@ -322,28 +405,26 @@
|
|||
*
|
||||
* @param array $data
|
||||
* @return PackageEntry
|
||||
* @throws ConfigurationException
|
||||
*/
|
||||
public static function fromArray(array $data): PackageEntry
|
||||
{
|
||||
$object = new self();
|
||||
$name = Functions::array_bc($data, 'name');
|
||||
$raw_versions = Functions::array_bc($data, 'versions') ?? [];
|
||||
$versions = [];
|
||||
|
||||
$object->name = Functions::array_bc($data, 'name');
|
||||
$object->latest_version = Functions::array_bc($data, 'latest_version');
|
||||
if($name === null)
|
||||
{
|
||||
throw new ConfigurationException('PackageEntry is missing name');
|
||||
}
|
||||
|
||||
foreach($raw_versions as $raw_version)
|
||||
{
|
||||
$versions[] = VersionEntry::fromArray($raw_version);
|
||||
}
|
||||
|
||||
$object = new self($name, $versions);
|
||||
$object->update_source = Functions::array_bc($data, 'update_source');
|
||||
$versions = Functions::array_bc($data, 'versions');
|
||||
|
||||
if($object->update_source !== null)
|
||||
{
|
||||
$object->update_source = UpdateSource::fromArray($object->update_source);
|
||||
}
|
||||
|
||||
if($versions !== null)
|
||||
{
|
||||
foreach($versions as $_datum)
|
||||
{
|
||||
$object->versions[] = VersionEntry::fromArray($_datum);
|
||||
}
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
namespace ncc\Objects\PackageLock;
|
||||
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Interfaces\BytecodeObjectInterface;
|
||||
use ncc\Objects\InstallationPaths;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\Compiler;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\PathFinder;
|
||||
|
||||
class VersionEntry implements BytecodeObjectInterface
|
||||
{
|
||||
|
@ -39,13 +39,6 @@
|
|||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* The compiler extension used for the package
|
||||
*
|
||||
* @var Compiler
|
||||
*/
|
||||
private $compiler;
|
||||
|
||||
/**
|
||||
* An array of packages that this package depends on
|
||||
*
|
||||
|
@ -54,9 +47,9 @@
|
|||
private $dependencies;
|
||||
|
||||
/**
|
||||
* @var ExecutionUnit[]
|
||||
* @var ExecutionPolicy[]
|
||||
*/
|
||||
public $execution_units;
|
||||
public $execution_policies;
|
||||
|
||||
/**
|
||||
* The main execution policy for this version entry if applicable
|
||||
|
@ -65,33 +58,20 @@
|
|||
*/
|
||||
public $main_execution_policy;
|
||||
|
||||
/**
|
||||
* The path where the package is located
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $location;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
public function __construct(string $version)
|
||||
{
|
||||
$this->version = $version;
|
||||
$this->dependencies = [];
|
||||
$this->execution_units = [];
|
||||
$this->execution_policies = [];
|
||||
$this->main_execution_policy = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns installation paths
|
||||
* Returns the version of the package that's installed
|
||||
*
|
||||
* @return InstallationPaths
|
||||
*/
|
||||
public function getInstallPaths(): InstallationPaths
|
||||
{
|
||||
return new InstallationPaths($this->location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion(): string
|
||||
|
@ -100,71 +80,8 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
*/
|
||||
public function setVersion(string $version): void
|
||||
{
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Compiler
|
||||
*/
|
||||
public function getCompiler(): Compiler
|
||||
{
|
||||
return $this->compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Compiler $compiler
|
||||
*/
|
||||
public function setCompiler(Compiler $compiler): void
|
||||
{
|
||||
$this->compiler = $compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|DependencyEntry[]
|
||||
*/
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|DependencyEntry[] $dependencies
|
||||
*/
|
||||
public function setDependencies(array $dependencies): void
|
||||
{
|
||||
$this->dependencies = $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DependencyEntry $dependency
|
||||
* @return void
|
||||
*/
|
||||
public function addDependency(DependencyEntry $dependency): void
|
||||
{
|
||||
$this->dependencies[] = $dependency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|ExecutionUnit[]
|
||||
*/
|
||||
public function getExecutionUnits(): array
|
||||
{
|
||||
return $this->execution_units;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|ExecutionUnit[] $execution_units
|
||||
*/
|
||||
public function setExecutionUnits(array $execution_units): void
|
||||
{
|
||||
$this->execution_units = $execution_units;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main execution policy for this version entry if applicable
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMainExecutionPolicy(): ?string
|
||||
|
@ -173,27 +90,115 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string|null $main_execution_policy
|
||||
* Sets the main execution policy for this version entry if applicable
|
||||
*
|
||||
* @param string|null $policy
|
||||
* @return void
|
||||
*/
|
||||
public function setMainExecutionPolicy(?string $main_execution_policy): void
|
||||
public function setMainExecutionPolicy(?string $policy): void
|
||||
{
|
||||
$this->main_execution_policy = $main_execution_policy;
|
||||
$this->main_execution_policy = $policy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of packages that this package depends on
|
||||
*
|
||||
* @return DependencyEntry[]
|
||||
*/
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dependency by name if it exists
|
||||
*
|
||||
* @param string $name
|
||||
* @return DependencyEntry|null
|
||||
*/
|
||||
public function getDependency(string $name): ?DependencyEntry
|
||||
{
|
||||
foreach($this->dependencies as $dependency)
|
||||
{
|
||||
if($dependency->getPackageName() === $name)
|
||||
{
|
||||
return $dependency;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dependency to the version entry
|
||||
*
|
||||
* @param DependencyEntry $dependency
|
||||
* @return void
|
||||
*/
|
||||
public function addDependency(DependencyEntry $dependency): void
|
||||
{
|
||||
if($this->getDependency($dependency->getPackageName()) !== null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->dependencies[] = $dependency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of execution policies for this version entry
|
||||
*
|
||||
* @return ExecutionPolicy[]
|
||||
*/
|
||||
public function getExecutionPolicies(): array
|
||||
{
|
||||
return $this->execution_policies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main execution policy for this version entry if it exists
|
||||
*
|
||||
* @param string $name
|
||||
* @return ExecutionPolicy|null
|
||||
*/
|
||||
public function getExecutionPolicy(string $name): ?ExecutionPolicy
|
||||
{
|
||||
foreach($this->execution_policies as $executionPolicy)
|
||||
{
|
||||
if($executionPolicy->getName() === $name)
|
||||
{
|
||||
return $executionPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an execution policy to the version entry
|
||||
*
|
||||
* @param ExecutionPolicy $executionPolicy
|
||||
* @return void
|
||||
*/
|
||||
public function addExecutionPolicy(ExecutionPolicy $executionPolicy): void
|
||||
{
|
||||
if($this->getExecutionPolicy($executionPolicy->getName()) !== null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->execution_policies[] = $executionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path where the package is installed
|
||||
*
|
||||
* @param string $package_name
|
||||
* @return string
|
||||
*/
|
||||
public function getLocation(): string
|
||||
public function getPath(string $package_name): string
|
||||
{
|
||||
return $this->location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
*/
|
||||
public function setLocation(string $location): void
|
||||
{
|
||||
$this->location = $location;
|
||||
return PathFinder::getPackagesPath() . DIRECTORY_SEPARATOR . sprintf('%s=%s', $package_name, $this->getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,19 +215,17 @@
|
|||
$dependencies[] = $dependency->toArray($bytecode);
|
||||
}
|
||||
|
||||
$execution_units = [];
|
||||
foreach($this->execution_units as $executionUnit)
|
||||
$execution_policies = [];
|
||||
foreach($this->execution_policies as $policy)
|
||||
{
|
||||
$execution_units[] = $executionUnit->toArray($bytecode);
|
||||
$execution_policies[] = $policy->toArray($bytecode);
|
||||
}
|
||||
|
||||
return [
|
||||
($bytecode ? Functions::cbc('version') : 'version') => $this->version,
|
||||
($bytecode ? Functions::cbc('compiler') : 'compiler') => $this->compiler->toArray(),
|
||||
($bytecode ? Functions::cbc('dependencies') : 'dependencies') => $dependencies,
|
||||
($bytecode ? Functions::cbc('execution_units') : 'execution_units') => $execution_units,
|
||||
($bytecode ? Functions::cbc('execution_policies') : 'execution_policies') => $execution_policies,
|
||||
($bytecode ? Functions::cbc('main_execution_policy') : 'main_execution_policy') => $this->main_execution_policy,
|
||||
($bytecode ? Functions::cbc('location') : 'location') => $this->location,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -234,11 +237,15 @@
|
|||
*/
|
||||
public static function fromArray(array $data): VersionEntry
|
||||
{
|
||||
$object = new self();
|
||||
$object->version = Functions::array_bc($data, 'version');
|
||||
$object->compiler = Compiler::fromArray(Functions::array_bc($data, 'compiler'));
|
||||
$version = Functions::array_bc($data, 'version');
|
||||
|
||||
if($version === null)
|
||||
{
|
||||
throw new ConfigurationException('VersionEntry is missing version');
|
||||
}
|
||||
|
||||
$object = new self($version);
|
||||
$object->main_execution_policy = Functions::array_bc($data, 'main_execution_policy');
|
||||
$object->location = Functions::array_bc($data, 'location');
|
||||
|
||||
$dependencies = Functions::array_bc($data, 'dependencies');
|
||||
if($dependencies !== null)
|
||||
|
@ -249,12 +256,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
$execution_units = Functions::array_bc($data, 'execution_units');
|
||||
if($execution_units !== null)
|
||||
$execution_policies = Functions::array_bc($data, 'execution_policies');
|
||||
if($execution_policies !== null)
|
||||
{
|
||||
foreach($execution_units as $_datum)
|
||||
foreach($execution_policies as $_datum)
|
||||
{
|
||||
$object->execution_units[] = ExecutionUnit::fromArray($_datum);
|
||||
$object->execution_policies[] = ExecutionPolicy::fromArray($_datum);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -436,7 +436,6 @@
|
|||
public static function fromArray(array $data): BuildConfiguration
|
||||
{
|
||||
$name = Functions::array_bc($data, 'name');
|
||||
$build_type = Functions::array_bc($data, 'build_type');
|
||||
$output_path = Functions::array_bc($data, 'output_path');
|
||||
|
||||
if($name === null)
|
||||
|
@ -451,6 +450,7 @@
|
|||
|
||||
$object = new BuildConfiguration($name, $output_path);
|
||||
|
||||
$object->build_type = Functions::array_bc($data, 'build_type') ?? BuildOutputType::NCC_PACKAGE;
|
||||
$object->options = Functions::array_bc($data, 'options') ?? [];
|
||||
$object->define_constants = Functions::array_bc($data, 'define_constants') ?? [];
|
||||
$object->exclude_files = Functions::array_bc($data, 'exclude_files') ?? [];
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
use ncc\Objects\Vault\Password\AccessToken;
|
||||
use ncc\Objects\Vault\Password\UsernamePassword;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ncc\Extensions\ZiProto\ZiProto;
|
||||
use RuntimeException;
|
||||
|
||||
class Entry implements BytecodeObjectInterface
|
||||
|
|
|
@ -1,242 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (c) Nosial 2022-2023, all rights reserved.
|
||||
*
|
||||
* 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 NON-INFRINGEMENT. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc;
|
||||
|
||||
use Exception;
|
||||
use ncc\Enums\CompilerExtensions;
|
||||
use ncc\Enums\Versions;
|
||||
use ncc\Classes\PhpExtension\PhpRuntime;
|
||||
use ncc\Exceptions\ConfigurationException;
|
||||
use ncc\Exceptions\ImportException;
|
||||
use ncc\Exceptions\IntegrityException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PackageException;
|
||||
use ncc\Managers\PackageManager;
|
||||
use ncc\Objects\PackageLock\VersionEntry;
|
||||
use ncc\Objects\ProjectConfiguration\Dependency;
|
||||
use ncc\Runtime\Constants;
|
||||
|
||||
class Runtime
|
||||
{
|
||||
/**
|
||||
* @var PackageManager
|
||||
*/
|
||||
private static $package_manager;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $imported_packages;
|
||||
|
||||
/**
|
||||
* Determines if the package is already imported
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @return bool
|
||||
* @throws IOException
|
||||
*/
|
||||
private static function isImported(string $package, string $version=Versions::LATEST): bool
|
||||
{
|
||||
if($version === Versions::LATEST)
|
||||
{
|
||||
$version = self::getPackageManager()->getPackage($package)->getLatestVersion();
|
||||
}
|
||||
|
||||
$entry = "$package=$version";
|
||||
|
||||
return isset(self::$imported_packages[$entry]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a package to the imported packages list
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @return void
|
||||
*/
|
||||
private static function addImport(string $package, string $version): void
|
||||
{
|
||||
$entry = "$package=$version";
|
||||
self::$imported_packages[$entry] = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $package
|
||||
* @param string $version
|
||||
* @param array $options
|
||||
* @return void
|
||||
* @throws IOException
|
||||
* @throws ImportException
|
||||
*/
|
||||
public static function import(string $package, string $version=Versions::LATEST, array $options=[]): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$package_entry = self::getPackageManager()->getPackage($package);
|
||||
}
|
||||
catch (IOException $e)
|
||||
{
|
||||
throw new ImportException(sprintf('Failed to import package "%s" due to a package lock exception: %s', $package, $e->getMessage()), $e);
|
||||
}
|
||||
|
||||
if($package_entry === null)
|
||||
{
|
||||
throw new ImportException(sprintf("Package '%s' not found", $package));
|
||||
}
|
||||
|
||||
if($version === Versions::LATEST)
|
||||
{
|
||||
$version = $package_entry->getLatestVersion();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
/** @var VersionEntry $version_entry */
|
||||
$version_entry = $package_entry->getVersion($version);
|
||||
|
||||
if($version_entry === null)
|
||||
{
|
||||
throw new ImportException(sprintf('Version %s of %s is not installed', $version, $package));
|
||||
}
|
||||
}
|
||||
catch (IOException $e)
|
||||
{
|
||||
throw new ImportException(sprintf('Version %s of %s is not installed', $version, $package), $e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (self::isImported($package, $version))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (IOException $e)
|
||||
{
|
||||
throw new ImportException(sprintf('Failed to check if package %s is imported', $package), $e);
|
||||
}
|
||||
|
||||
if(count($version_entry->getDependencies()) > 0)
|
||||
{
|
||||
// Import all dependencies first
|
||||
/** @var Dependency $dependency */
|
||||
foreach($version_entry->getDependencies() as $dependency)
|
||||
{
|
||||
self::import($dependency->getPackageName(), $dependency->getVersion(), $options);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch($version_entry->getCompiler()->getExtension())
|
||||
{
|
||||
case CompilerExtensions::PHP:
|
||||
PhpRuntime::import($version_entry, $options);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ImportException(sprintf('Compiler extension %s is not supported in this runtime', $version_entry->getCompiler()->getExtension()));
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new ImportException(sprintf('Failed to import package %s', $package), $e);
|
||||
}
|
||||
|
||||
self::addImport($package, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data path of the package
|
||||
*
|
||||
* @param string $package
|
||||
* @return string
|
||||
* @throws ConfigurationException
|
||||
* @throws IOException
|
||||
* @throws PackageException
|
||||
*/
|
||||
public static function getDataPath(string $package): string
|
||||
{
|
||||
$package = self::getPackageManager()->getPackage($package);
|
||||
|
||||
if($package === null)
|
||||
{
|
||||
throw new PackageException('Package not found (null entry error, possible bug)');
|
||||
}
|
||||
|
||||
return $package->getDataPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return PackageManager
|
||||
*/
|
||||
private static function getPackageManager(): PackageManager
|
||||
{
|
||||
if(self::$package_manager === null)
|
||||
{
|
||||
self::$package_manager = new PackageManager();
|
||||
}
|
||||
|
||||
return self::$package_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all the packages that is currently imported
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getImportedPackages(): array
|
||||
{
|
||||
return array_keys(self::$imported_packages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a registered constant
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getConstant(string $package, string $name): ?string
|
||||
{
|
||||
return Constants::get($package, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new constant
|
||||
*
|
||||
* @param string $package
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return void
|
||||
* @throws IntegrityException
|
||||
*/
|
||||
public static function setConstant(string $package, string $name, string $value): void
|
||||
{
|
||||
Constants::register($package, $name, $value);
|
||||
}
|
||||
}
|
247
src/ncc/ThirdParty/theseer/Autoload/Application.php
vendored
247
src/ncc/ThirdParty/theseer/Autoload/Application.php
vendored
|
@ -1,247 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*
|
||||
*/
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class Application {
|
||||
|
||||
private $logger;
|
||||
private $factory;
|
||||
private $config;
|
||||
|
||||
public function __construct(Logger $logger, Config $config, Factory $factory) {
|
||||
$this->logger = $logger;
|
||||
$this->config = $config;
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
$result = $this->runCollector();
|
||||
if (!$result->hasUnits()) {
|
||||
throw new ApplicationException('No units were found - process aborted.', ApplicationException::NoUnitsFound);
|
||||
}
|
||||
if ($result->hasDuplicates()) {
|
||||
return $this->showDuplicatesError($result->getDuplicates());
|
||||
}
|
||||
|
||||
if ($this->config->isCacheEnabled()) {
|
||||
$this->factory->getCache()->persist($this->config->getCacheFile());
|
||||
}
|
||||
|
||||
$template = @file_get_contents($this->config->getTemplate());
|
||||
if ($template === false) {
|
||||
throw new ApplicationException("Failed to read the template file.");
|
||||
}
|
||||
|
||||
$builder = $this->factory->getRenderer($result);
|
||||
$code = $builder->render($template);
|
||||
if ($this->config->isLintMode()) {
|
||||
return $this->runLint($code);
|
||||
}
|
||||
return $this->runSaver($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CollectorResult
|
||||
*/
|
||||
private function runCollector() {
|
||||
if ($this->config->isFollowSymlinks()) {
|
||||
$this->logger->log('Following symbolic links is enabled.' . "\n\n");
|
||||
}
|
||||
$collector = $this->factory->getCollector();
|
||||
foreach ($this->config->getDirectories() as $directory) {
|
||||
if (is_dir($directory)) {
|
||||
$this->logger->log('Scanning directory ' . $directory . "\n");
|
||||
$scanner = $this->factory->getScanner()->getIterator($directory);
|
||||
$collector->processDirectory($scanner);
|
||||
// this unset is needed to "fix" a segfault on shutdown in some PHP Versions
|
||||
unset($scanner);
|
||||
} else {
|
||||
$file = new \SplFileInfo($directory);
|
||||
$filter = $this->factory->getFilter(new \ArrayIterator(array($file)));
|
||||
foreach($filter as $file) {
|
||||
$this->logger->log('Scanning file ' . $file . "\n");
|
||||
$collector->processFile($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $collector->getResult();
|
||||
}
|
||||
|
||||
private function runSaver($code) {
|
||||
$output = $this->config->getOutputFile();
|
||||
if (!$this->config->isPharMode()) {
|
||||
if ($output === 'STDOUT') {
|
||||
$this->logger->log("\n");
|
||||
echo $code;
|
||||
$this->logger->log("\n\n");
|
||||
return CLI::RC_OK;
|
||||
}
|
||||
// @codingStandardsIgnoreStart
|
||||
$written = @file_put_contents($output, $code);
|
||||
// @codingStandardsIgnoreEnd
|
||||
if ($written != strlen($code)) {
|
||||
$this->logger->log("Writing to file '$output' failed.", STDERR);
|
||||
return CLI::RC_EXEC_ERROR;
|
||||
}
|
||||
$this->logger->log("\nAutoload file {$output} generated.\n\n");
|
||||
return CLI::RC_OK;
|
||||
}
|
||||
if (strpos($code, '__HALT_COMPILER();') === FALSE) {
|
||||
$this->logger->log(
|
||||
"Warning: Template used in phar mode did not contain required __HALT_COMPILER() call\n" .
|
||||
"which has been added automatically. The used stub code may not work as intended.\n\n", STDERR);
|
||||
$code .= $this->config->getLinebreak() . '__HALT_COMPILER();';
|
||||
}
|
||||
$pharBuilder = $this->factory->getPharBuilder();
|
||||
if ($keyfile = $this->config->getPharKey()) {
|
||||
$pharBuilder->setSignatureKey($this->loadPharSignatureKey($keyfile));
|
||||
}
|
||||
if ($aliasName = $this->config->getPharAliasName()) {
|
||||
$pharBuilder->setAliasName($aliasName);
|
||||
}
|
||||
if ($this->config->hasPharHashAlgorithm()) {
|
||||
$pharBuilder->setSignatureType($this->config->getPharHashAlgorithm());
|
||||
}
|
||||
$pharBuilder->build($output, $code);
|
||||
$this->logger->log("\nphar archive '{$output}' generated.\n\n");
|
||||
return CLI::RC_OK;
|
||||
}
|
||||
|
||||
private function loadPharSignatureKey($keyfile) {
|
||||
if (!extension_loaded('openssl')) {
|
||||
throw new ApplicationException('Extension for OpenSSL not loaded - cannot sign phar archive - process aborted.',
|
||||
ApplicationException::OpenSSLError);
|
||||
}
|
||||
$keydata = file_get_contents($keyfile);
|
||||
if (strpos($keydata, 'ENCRYPTED') !== FALSE) {
|
||||
$this->logger->log("Passphrase for key '$keyfile': ");
|
||||
$g = shell_exec('stty -g');
|
||||
shell_exec('stty -echo');
|
||||
$passphrase = trim(fgets(STDIN));
|
||||
$this->logger->log("\n");
|
||||
shell_exec('stty ' . $g);
|
||||
$private = openssl_pkey_get_private($keydata, $passphrase);
|
||||
} else {
|
||||
$private = openssl_pkey_get_private($keydata);
|
||||
}
|
||||
if (!$private) {
|
||||
throw new ApplicationException("Opening private key '$keyfile' failed - process aborted.\n\n", ApplicationException::OpenSSLError);
|
||||
}
|
||||
return $private;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute a lint check on generated code
|
||||
*
|
||||
* @param string $code Generated code to lint
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function runLint($code) {
|
||||
$dsp = array(
|
||||
0 => array('pipe', 'r'),
|
||||
1 => array('pipe', 'w'),
|
||||
2 => array('pipe', 'w')
|
||||
);
|
||||
|
||||
$binary = $this->config->getPhp();
|
||||
|
||||
$process = proc_open($binary . ' -l', $dsp, $pipes);
|
||||
|
||||
if (!is_resource($process)) {
|
||||
$this->logger->log("Opening php binary for linting failed.\n", STDERR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fwrite($pipes[0], $code);
|
||||
fclose($pipes[0]);
|
||||
fclose($pipes[1]);
|
||||
|
||||
$stderr = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[2]);
|
||||
|
||||
$rc = proc_close($process);
|
||||
|
||||
if ($rc == 255) {
|
||||
$this->logger->log("Syntax errors during lint:\n" .
|
||||
str_replace('in - on line', 'in generated code on line', $stderr) .
|
||||
"\n", STDERR);
|
||||
return CLI::RC_LINT_ERROR;
|
||||
}
|
||||
|
||||
$this->logger->log("Lint check of geneated code okay\n\n");
|
||||
return CLI::RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $duplicates
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function showDuplicatesError(array $duplicates) {
|
||||
$this->logger->log(
|
||||
sprintf("\nMultiple declarations of trait(s), interface(s) or class(es). Could not generate autoload map.\n"),
|
||||
STDERR
|
||||
);
|
||||
foreach($duplicates as $unit => $files) {
|
||||
$this->logger->log(
|
||||
sprintf("\nUnit '%s' defined in:\n", $unit),
|
||||
STDERR
|
||||
);
|
||||
|
||||
/** @var array $files */
|
||||
foreach($files as $file) {
|
||||
$this->logger->log(
|
||||
sprintf(" - %s\n", $file),
|
||||
STDERR
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
return CLI::RC_DUPLICATES_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ApplicationException extends \Exception {
|
||||
const NoUnitsFound = 1;
|
||||
const OpenSSLError = 2;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,297 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*/
|
||||
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
/**
|
||||
* Builds spl based autoload code for inclusion into projects
|
||||
*
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
*/
|
||||
class AutoloadRenderer {
|
||||
|
||||
/**
|
||||
* Associative array of classes (key) and the files (value) they are in
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $classes;
|
||||
|
||||
/**
|
||||
* An optional base dir to strip for the realpath of the filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $baseDir = '';
|
||||
|
||||
/**
|
||||
* Indenting char(s)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $indent = ' ';
|
||||
|
||||
/**
|
||||
* Char(s) used as linebreak
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $linebreak = "\n";
|
||||
|
||||
/**
|
||||
* Timestamp of production start
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $timestamp;
|
||||
|
||||
/**
|
||||
* Format string supplied to date() for use with ___CREATED___
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dateformat = 'r';
|
||||
|
||||
/**
|
||||
* Variables for templates
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $variables = array();
|
||||
|
||||
/**
|
||||
* Flag to toggle PHP 5.2 compat mode
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $compat = false;
|
||||
|
||||
/**
|
||||
* Flag to pass on to spl_autoload_register to prepend
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $usePrepend = false;
|
||||
|
||||
/**
|
||||
* Flag to pass on to spl_autoload_register to optionally throw exceptions on registration error
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $throwExceptions = false;
|
||||
|
||||
/**
|
||||
* Constructor of AutoloadRenderer class
|
||||
*
|
||||
* @param array $classlist Array of classes
|
||||
*
|
||||
*/
|
||||
public function __construct(array $classlist) {
|
||||
$this->classes = $classlist;
|
||||
ksort($this->classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle PHP 5.2 compat mode
|
||||
*
|
||||
* @param boolean $mode Mode to set compat to
|
||||
*/
|
||||
public function setCompat($mode) {
|
||||
$this->compat = $mode;
|
||||
}
|
||||
|
||||
public function enableExceptions() {
|
||||
$this->throwExceptions = true;
|
||||
}
|
||||
|
||||
public function prependAutoloader() {
|
||||
$this->usePrepend = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the Basedir
|
||||
*
|
||||
* @param string $dir Path to strip from beginning of filenames
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setBaseDir($dir) {
|
||||
$this->baseDir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite default or previously set indenting option
|
||||
*
|
||||
* @param string $indent Char(s) to use for indenting
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setIndent($indent) {
|
||||
$this->indent = $indent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite default or previously set linebreak chars
|
||||
*
|
||||
* @param string $lbs Code to set linebreak
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLineBreak($lbs) {
|
||||
$this->linebreak = $lbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor for current linebreak setting
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLineBreak() {
|
||||
return $this->linebreak;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter to use allow usage of fixed date/time for ___CREATED___
|
||||
*
|
||||
* @param integer $time unix timestamp
|
||||
*
|
||||
* @throws AutoloadBuilderException
|
||||
*/
|
||||
public function setTimestamp($time) {
|
||||
if (!is_int($time) && null !== $time) {
|
||||
throw new AutoloadBuilderException("'$time' is not a unix timestamp", AutoloadBuilderException::InvalidTimestamp);
|
||||
}
|
||||
$this->timestamp = $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter to adjust the date/time format output of ___CREATED___
|
||||
*
|
||||
* @param string $frmt Date/Time format string
|
||||
*/
|
||||
public function setDateTimeFormat($frmt) {
|
||||
$this->dateformat = $frmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a variable for use with template code
|
||||
*
|
||||
* @param string $name Key name (use as ___key___ in template)
|
||||
* @param string $value Value to use
|
||||
*/
|
||||
public function setVariable($name, $value) {
|
||||
$this->variables['___'.$name.'___'] = $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolve relative location of file path to basedir if one is set and fix potential
|
||||
* broken windows pathnames when run on windows.
|
||||
*
|
||||
* @param string $fname
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function resolvePath($fname) {
|
||||
if (empty($this->baseDir)) {
|
||||
return str_replace('\\', '/', $fname);
|
||||
}
|
||||
$basedir = explode(DIRECTORY_SEPARATOR, $this->baseDir);
|
||||
$filedir = explode(DIRECTORY_SEPARATOR, dirname(realpath($fname)));
|
||||
$pos = 0;
|
||||
$max = count($basedir);
|
||||
while (isset($filedir[$pos]) && $filedir[$pos] == $basedir[$pos]) {
|
||||
$pos++;
|
||||
if ($pos == $max) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($pos == 0) {
|
||||
return str_replace('\\', '/', $fname);
|
||||
}
|
||||
$rel = join('/', array_slice($filedir, $pos));
|
||||
if (!empty($rel)) {
|
||||
$rel .= '/';
|
||||
}
|
||||
if ($pos<count($basedir)) {
|
||||
$rel = str_repeat('../', count($basedir)-$pos) . $rel;
|
||||
}
|
||||
return '/' . $rel . basename($fname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render autoload code into a string
|
||||
*
|
||||
* @param string $template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render($template) {
|
||||
$entries = array();
|
||||
foreach($this->classes as $class => $file) {
|
||||
$fname = $this->resolvePath($file);
|
||||
$entries[] = "'". addslashes($class). "' => '$fname'";
|
||||
}
|
||||
|
||||
$baseDir = '';
|
||||
if ($this->baseDir) {
|
||||
$baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . ';
|
||||
}
|
||||
|
||||
$replace = array_merge($this->variables, array(
|
||||
'___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()),
|
||||
'___CLASSLIST___' => join( ',' . $this->linebreak . $this->indent, $entries),
|
||||
'___BASEDIR___' => $baseDir,
|
||||
'___AUTOLOAD___' => 'autoload' . md5(serialize($entries)),
|
||||
'___EXCEPTION___' => $this->throwExceptions ? 'true' : 'false',
|
||||
'___PREPEND___' => $this->usePrepend ? 'true' : 'false'
|
||||
));
|
||||
return str_replace(array_keys($replace), array_values($replace), $template);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class AutoloadBuilderException extends \Exception {
|
||||
|
||||
const TemplateNotFound = 1;
|
||||
const InvalidTimestamp = 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
607
src/ncc/ThirdParty/theseer/Autoload/CLI.php
vendored
607
src/ncc/ThirdParty/theseer/Autoload/CLI.php
vendored
|
@ -1,607 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*/
|
||||
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
/**
|
||||
* CLI interface to AutoloadRenderer / StaticRenderer
|
||||
*
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
*/
|
||||
class CLI {
|
||||
|
||||
const RC_OK = 0;
|
||||
const RC_EXEC_ERROR = 1;
|
||||
const RC_PARAM_ERROR = 3;
|
||||
const RC_LINT_ERROR = 4;
|
||||
const RC_DUPLICATES_ERROR = 5;
|
||||
|
||||
private $pharOption;
|
||||
private $staticOption;
|
||||
private $helpOption;
|
||||
private $versionOption;
|
||||
private $onceOption;
|
||||
|
||||
/**
|
||||
* @var Factory
|
||||
*/
|
||||
private $factory;
|
||||
|
||||
|
||||
public function __construct(Factory $factory) {
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main executor method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run() {
|
||||
|
||||
try {
|
||||
|
||||
$this->preBootstrap();
|
||||
|
||||
$input = $this->setupInput();
|
||||
$input->process();
|
||||
|
||||
if ($input->getOption('help')->value === TRUE) {
|
||||
$this->showVersion();
|
||||
$this->showUsage();
|
||||
exit(CLI::RC_OK);
|
||||
}
|
||||
|
||||
if ($input->getOption('version')->value === TRUE ) {
|
||||
$this->showVersion();
|
||||
exit(CLI::RC_OK);
|
||||
}
|
||||
|
||||
$config = $this->configure($input);
|
||||
$this->factory->setConfig($config);
|
||||
if (!$config->isQuietMode()) {
|
||||
$this->showVersion();
|
||||
}
|
||||
$rc = $this->factory->getApplication()->run();
|
||||
exit($rc);
|
||||
|
||||
} catch (CLIEnvironmentException $e) {
|
||||
$this->showVersion();
|
||||
fwrite(STDERR, 'Sorry, but your PHP environment is currently not able to run phpab due to');
|
||||
fwrite(STDERR, "\nthe following issue(s):\n\n" . $e->getMessage() . "\n\n");
|
||||
fwrite(STDERR, "Please adjust your PHP configuration and try again.\n\n");
|
||||
exit(CLI::RC_EXEC_ERROR);
|
||||
} catch (\ezcConsoleException $e) {
|
||||
$this->showVersion();
|
||||
echo $e->getMessage() . "\n\n";
|
||||
$this->showUsage();
|
||||
exit(CLI::RC_PARAM_ERROR);
|
||||
} catch (CollectorException $e) {
|
||||
switch($e->getCode()) {
|
||||
case CollectorException::InFileRedeclarationFound:
|
||||
case CollectorException::RedeclarationFound:
|
||||
case CollectorException::ParseErrror: {
|
||||
$message = $e->getMessage();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
$message = 'Unexpected error in collector process: ' . $e->getMessage() . "\n\nPlease report this as a bug.\n\n";
|
||||
}
|
||||
}
|
||||
$this->showVersion();
|
||||
fwrite(STDERR, $message . "\n\n");
|
||||
exit(CLI::RC_EXEC_ERROR);
|
||||
} catch (\Exception $e) {
|
||||
$this->showVersion();
|
||||
fwrite(STDERR, "\nError while processing request:\n - " . $e->getMessage()."\n");
|
||||
exit(CLI::RC_EXEC_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ezcConsoleInput $input
|
||||
*
|
||||
* @return \ncc\ThirdParty\theseer\Autoload\Config
|
||||
*/
|
||||
private function configure(\ezcConsoleInput $input) {
|
||||
$config = new Config($input->getArguments());
|
||||
if ($input->getOption('quiet')->value) {
|
||||
$config->setQuietMode(TRUE);
|
||||
}
|
||||
if ($input->getOption('compat')->value) {
|
||||
$config->setCompatMode(TRUE);
|
||||
}
|
||||
if ($input->getOption('tolerant')->value) {
|
||||
$config->setTolerantMode(TRUE);
|
||||
}
|
||||
if ($output = $input->getOption('output')->value) {
|
||||
$config->setOutputFile($output);
|
||||
}
|
||||
if ($input->getOption('phar')->value) {
|
||||
$compression = \Phar::NONE;
|
||||
if ($input->getOption('bzip2')->value === TRUE) {
|
||||
$compression = \Phar::BZ2;
|
||||
} else if ($input->getOption('gzip')->value === TRUE) {
|
||||
$compression = \Phar::GZ;
|
||||
}
|
||||
$config->enablePharMode(
|
||||
$compression,
|
||||
$input->getOption('all')->value,
|
||||
$input->getOption('key')->value,
|
||||
$input->getOption('alias')->value
|
||||
);
|
||||
$config->setVariable('PHAR',
|
||||
$input->getOption('alias')->value ? $input->getOption('alias')->value : basename($output)
|
||||
);
|
||||
if ($hashAlgorithm = $input->getOption('hash')->value) {
|
||||
$config->setPharHashAlgorithm($hashAlgorithm);
|
||||
}
|
||||
}
|
||||
|
||||
if ($input->getOption('cache')->value) {
|
||||
$config->setCacheFile($input->getOption('cache')->value);
|
||||
}
|
||||
|
||||
if ($basedir = $input->getOption('basedir')->value) {
|
||||
$config->setBaseDirectory($basedir);
|
||||
}
|
||||
|
||||
$include = $input->getOption('include')->value;
|
||||
if (!is_array($include)) {
|
||||
$include = array($include);
|
||||
}
|
||||
$config->setInclude($include);
|
||||
|
||||
if ($exclude = $input->getOption('exclude')->value) {
|
||||
if (!is_array($exclude)) {
|
||||
$exclude = array($exclude);
|
||||
}
|
||||
$config->setExclude($exclude);
|
||||
}
|
||||
|
||||
$whitelist = $input->getOption('whitelist')->value;
|
||||
if (!is_array($whitelist)) {
|
||||
$whitelist = array($whitelist);
|
||||
}
|
||||
$config->setWhitelist($whitelist);
|
||||
|
||||
if ($blacklist = $input->getOption('blacklist')->value) {
|
||||
if (!is_array($blacklist)) {
|
||||
$blacklist = array($blacklist);
|
||||
}
|
||||
$config->setBlacklist($blacklist);
|
||||
}
|
||||
|
||||
if ($input->getOption('static')->value) {
|
||||
$config->setStaticMode(TRUE);
|
||||
}
|
||||
if ($input->getOption('once')->value) {
|
||||
$config->setOnceMode(TRUE);
|
||||
}
|
||||
|
||||
if ($input->getOption('warm')->value) {
|
||||
$config->setWarmMode(TRUE);
|
||||
}
|
||||
if ($input->getOption('reset')->value) {
|
||||
$config->setResetMode(TRUE);
|
||||
}
|
||||
|
||||
if ($input->getOption('follow')->value) {
|
||||
$config->setFollowSymlinks(TRUE);
|
||||
}
|
||||
|
||||
if ($input->getOption('prepend')->value) {
|
||||
$config->enablePrepend();
|
||||
}
|
||||
|
||||
if ($input->getOption('no-exception')->value) {
|
||||
$config->disableExceptions();
|
||||
}
|
||||
|
||||
$indent = $input->getOption('indent')->value;
|
||||
if ($indent !== FALSE) {
|
||||
$config->setIndent($indent);
|
||||
}
|
||||
if ($template = $input->getOption('template')->value) {
|
||||
$config->setTemplate($template);
|
||||
}
|
||||
if ($linebreak = $input->getOption('linebreak')->value) {
|
||||
$config->setLinebreak($linebreak);
|
||||
}
|
||||
if ($input->getOption('nolower')->value) {
|
||||
$config->setLowercaseMode(FALSE);
|
||||
}
|
||||
if ($variables = $input->getOption('var')->value) {
|
||||
foreach($variables as $var) {
|
||||
if (strpos($var, '=')===FALSE) {
|
||||
throw new \RuntimeException("Variable defintion '$var' is invalid and cannot be processed.");
|
||||
}
|
||||
list($name, $value) = explode('=', $var, 2);
|
||||
$config->setVariable($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($input->getOption('paranoid')->value || !$input->getOption('trusting')->value) {
|
||||
$config->setTrusting(FALSE);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to output version information
|
||||
*/
|
||||
protected function showVersion() {
|
||||
static $shown = false;
|
||||
if (!$shown) {
|
||||
$shown = true;
|
||||
echo Version::getInfoString() . "\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to output usage information
|
||||
*/
|
||||
protected function showUsage() {
|
||||
print <<<EOF
|
||||
Usage: phpab [switches] <directory1|file1|/path/to/composer.json> [...<directoryN|fileN>]
|
||||
|
||||
-i, --include File pattern to include (default: *.php)
|
||||
-e, --exclude File pattern to exclude
|
||||
|
||||
--blacklist Blacklist classname or namespace (wildcards supported)
|
||||
--whitelist Whitelist classname or namespace (wildcards supported)
|
||||
|
||||
-b, --basedir Basedir for filepaths
|
||||
-t, --template Path to code template to use
|
||||
|
||||
-o, --output Output file for generated code (default: STDOUT)
|
||||
|
||||
-p, --phar Create a phar archive (requires -o )
|
||||
--all Include all files in given directory when creating a phar
|
||||
--alias Specify explicit internal phar alias filename (default: output filename)
|
||||
--hash Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p, conflicts with --key)
|
||||
--bzip2 Compress phar archive using bzip2 (requires -p) (bzip2 required)
|
||||
--gzip Compress phar archive using gzip (requires -p) (gzip required)
|
||||
--key OpenSSL key file to use for signing phar archive (requires -p) (openssl required)
|
||||
|
||||
-c, --compat Generate PHP 5.2 compatible code
|
||||
-s, --static Generate a static require file
|
||||
|
||||
-w, --warm Generate a static opcache warming file
|
||||
--reset Add opcache reset call when generating opcache warming file
|
||||
|
||||
-1, --prepend Register as first autoloader (prepend to stack, default: append)
|
||||
-d, --no-exception Do not throw exception on registration problem (default: throw exception)
|
||||
|
||||
-n, --nolower Do not lowercase classnames for case insensitivity
|
||||
|
||||
-q, --quiet Quiet mode, do not output any processing errors or information
|
||||
|
||||
--cache <file> Enable caching and set filename to use for cache storage
|
||||
|
||||
--follow Enables following symbolic links (not compatible with phar mode)
|
||||
--format Dateformat string for timestamp
|
||||
--linebreak Linebreak style (CR, CRLF or LF, default: LF)
|
||||
--indent String used for indenting or number of spaces (default: 16 (compat 12) spaces)
|
||||
|
||||
--tolerant Ignore Class Redeclarations in the same file
|
||||
--once Use require_once instead of require when creating a static require file
|
||||
|
||||
|
||||
--trusting Do not check mimetype of files prior to parsing (default)
|
||||
--paranoid Do check mimetype of files prior to parsing
|
||||
|
||||
--var name=foo Assign value 'foo' to variable 'name' to be used in (custom) templates
|
||||
|
||||
--lint Run lint on generated code and exit
|
||||
--lint-php PHP binary to use for linting (default: /usr/bin/php or c:\php\php.exe)
|
||||
|
||||
-h, --help Prints this usage information
|
||||
-v, --version Prints the version and exits
|
||||
|
||||
EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \ezcConsoleInput
|
||||
*/
|
||||
protected function setupInput() {
|
||||
$input = new \ezcConsoleInput();
|
||||
|
||||
$this->versionOption = $input->registerOption( new \ezcConsoleOption( 'v', 'version' ) );
|
||||
$this->versionOption->shorthelp = 'Prints the version and exits';
|
||||
$this->versionOption->isHelpOption = TRUE;
|
||||
|
||||
$this->helpOption = $input->registerOption( new \ezcConsoleOption( 'h', 'help' ) );
|
||||
$this->helpOption->isHelpOption = TRUE;
|
||||
$this->helpOption->shorthelp = 'Prints this usage information';
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'cache', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Enable cache and set cache filename'
|
||||
));
|
||||
|
||||
$this->outputOption = $input->registerOption( new \ezcConsoleOption(
|
||||
'o', 'output', \ezcConsoleInput::TYPE_STRING, 'STDOUT', FALSE,
|
||||
'Output file for generated code (default: STDOUT)'
|
||||
));
|
||||
|
||||
$this->pharOption = $input->registerOption( new \ezcConsoleOption(
|
||||
'p', 'phar', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Build a phar archive of directory contents',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'o' ) ) )
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'all', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Add all files from src dir to phar',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'alias', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Provide explicit internal alias filename for phar',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
|
||||
));
|
||||
|
||||
$bzip2 = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'bzip2', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Compress files phar with bzip2',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
|
||||
));
|
||||
|
||||
$gzip = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'gzip', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Compress files phar with gzip',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ),
|
||||
array( new \ezcConsoleOptionRule( $bzip2 ) )
|
||||
));
|
||||
$bzip2->addExclusion(new \ezcConsoleOptionRule($gzip));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'key', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Keyfile to use for signing phar archive',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
|
||||
));
|
||||
|
||||
$this->outputOption = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'hash', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p)',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ),
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'key' ) ) )
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'i', 'include', \ezcConsoleInput::TYPE_STRING, '*.php', TRUE,
|
||||
'File pattern to include (default: *.php)'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'blacklist', \ezcConsoleInput::TYPE_STRING, NULL, TRUE,
|
||||
'Name pattern to exclude'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'whitelist', \ezcConsoleInput::TYPE_STRING, '*', TRUE,
|
||||
'Name pattern to include (default: *)'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'e', 'exclude', \ezcConsoleInput::TYPE_STRING, NULL, TRUE,
|
||||
'File pattern to exclude'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'b', 'basedir', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Basedir for filepaths'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
't', 'template', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Path to code template to use'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'follow', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Enables following symbolic links',
|
||||
NULL,
|
||||
array(),
|
||||
array( new \ezcConsoleOptionRule($this->pharOption) )
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'format', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Dateformat string for timestamp'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'linebreak', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'Linebreak style (CR, CR/LF or LF)'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'indent', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'String used for indenting (default: 3 spaces)'
|
||||
));
|
||||
|
||||
$this->lintOption = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'lint', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Run lint on generated code'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'lint-php', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
|
||||
'PHP binary path for linting (default: /usr/bin/php or c:\\php\\php.exe)',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 'lint' ) ) )
|
||||
));
|
||||
|
||||
$compat = $input->registerOption( new \ezcConsoleOption(
|
||||
'c', 'compat', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Generate PHP 5.2 compliant code'
|
||||
));
|
||||
|
||||
$this->staticOption = $input->registerOption( new \ezcConsoleOption(
|
||||
's', 'static', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Build a static require file'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'tolerant', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Ignore Class Redeclarations in the same file'
|
||||
));
|
||||
|
||||
$trusting = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'trusting', \ezcConsoleInput::TYPE_NONE, TRUE, FALSE,
|
||||
'Do not check mimetype of files prior to parsing'
|
||||
));
|
||||
$paranoid = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'paranoid', \ezcConsoleInput::TYPE_NONE, FALSE, FALSE,
|
||||
'Do check mimetype of files prior to parsing',
|
||||
NULL,
|
||||
array(),
|
||||
array( new \ezcConsoleOptionRule($trusting) )
|
||||
));
|
||||
$trusting->addExclusion(new \ezcConsoleOptionRule($paranoid));
|
||||
|
||||
$this->onceOption = $input->registerOption( new \ezcConsoleOption(
|
||||
'', 'once', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Use require_once in static require mode',
|
||||
NULL,
|
||||
array( new \ezcConsoleOptionRule( $input->getOption( 's' ) ) )
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'n', 'nolower', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Do not lowercase classnames for case insensitivity'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'q', 'quiet', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Run in quiet mode, no output'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'1', 'prepend', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Prepend autoloader to stack',
|
||||
NULL,
|
||||
array(),
|
||||
array( new \ezcConsoleOptionRule( $compat ) )
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'd', 'no-exception', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'Disable exceptions on registration error'
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'var', \ezcConsoleInput::TYPE_STRING, array(), TRUE,
|
||||
'Assign variable'
|
||||
));
|
||||
|
||||
$warm = $input->registerOption( new \ezcConsoleOption(
|
||||
'w', 'warm', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'generate opcache warming file',
|
||||
NULL,
|
||||
array(),
|
||||
array(
|
||||
new \ezcConsoleOptionRule($this->pharOption),
|
||||
new \ezcConsoleOptionRule($this->staticOption)
|
||||
)
|
||||
));
|
||||
|
||||
$input->registerOption( new \ezcConsoleOption(
|
||||
'', 'reset', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
|
||||
'add reset call to generated opcache warming file',
|
||||
NULL,
|
||||
array(
|
||||
new \ezcConsoleOptionRule($warm)
|
||||
)
|
||||
));
|
||||
|
||||
$input->argumentDefinition = new \ezcConsoleArguments();
|
||||
$input->argumentDefinition[0] = new \ezcConsoleArgument('directory');
|
||||
$input->argumentDefinition[0]->shorthelp = 'The directory to process.';
|
||||
$input->argumentDefinition[0]->multiple = TRUE;
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
private function preBootstrap() {
|
||||
$required = array('tokenizer', 'fileinfo');
|
||||
$missing = array();
|
||||
foreach($required as $test) {
|
||||
if (!extension_loaded($test)) {
|
||||
$missing[] = sprintf('ext/%s not installed/enabled', $test);
|
||||
}
|
||||
}
|
||||
if (count($missing)) {
|
||||
throw new CLIEnvironmentException(
|
||||
join("\n", $missing),
|
||||
CLIEnvironmentException::ExtensionMissing
|
||||
);
|
||||
}
|
||||
|
||||
if (extension_loaded('xdebug')) {
|
||||
ini_set('xdebug.scream', 0);
|
||||
ini_set('xdebug.max_nesting_level', 8192);
|
||||
ini_set('xdebug.show_exception_trace', 0);
|
||||
if (function_exists('xdebug_disable')) { // Xdebug v2
|
||||
xdebug_disable();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CLIEnvironmentException extends \Exception {
|
||||
const ExtensionMissing = 1;
|
||||
}
|
||||
}
|
||||
|
62
src/ncc/ThirdParty/theseer/Autoload/Cache.php
vendored
62
src/ncc/ThirdParty/theseer/Autoload/Cache.php
vendored
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class Cache {
|
||||
|
||||
/**
|
||||
* @var CacheEntry[]
|
||||
*/
|
||||
private $loadedEntries = array();
|
||||
|
||||
/**
|
||||
* @var CacheEntry[]
|
||||
*/
|
||||
private $usedEntries = array();
|
||||
|
||||
|
||||
public function __construct(array $initialEntries) {
|
||||
$this->loadedEntries = $initialEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SourceFile $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasResult(SourceFile $file) {
|
||||
$pathname = $file->getPathname();
|
||||
if (!isset($this->loadedEntries[$pathname])) {
|
||||
return false;
|
||||
}
|
||||
return $this->loadedEntries[$pathname]->getTimestamp() === $file->getMTime();
|
||||
}
|
||||
|
||||
public function getResult(SourceFile $file) {
|
||||
if (!$this->hasResult($file)) {
|
||||
throw new CacheException('Entry not found');
|
||||
}
|
||||
$pathname = $file->getPathname();
|
||||
$entry = $this->loadedEntries[$pathname];
|
||||
$this->usedEntries[$pathname] = $entry;
|
||||
return $entry->getResult();
|
||||
}
|
||||
|
||||
public function addResult(SourceFile $file, ParseResult $result) {
|
||||
$this->usedEntries[$file->getPathname()] = new CacheEntry($file->getMTime(), $result);
|
||||
}
|
||||
|
||||
public function persist($fname) {
|
||||
if (file_exists($fname)) {
|
||||
unlink($fname);
|
||||
}
|
||||
file_put_contents($fname, serialize($this->usedEntries));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CacheException extends \Exception {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class CacheEntry {
|
||||
|
||||
/**
|
||||
* @var ParseResult
|
||||
*/
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $timestamp;
|
||||
|
||||
public function __construct($timestamp, ParseResult $result) {
|
||||
$this->timestamp = $timestamp;
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParseResult
|
||||
*/
|
||||
public function getResult() {
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp() {
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload;
|
||||
|
||||
use ncc\ThirdParty\theseer\Autoload\StaticListRenderer;
|
||||
|
||||
class CacheWarmingListRenderer implements StaticListRenderer {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $addReset;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $indent;
|
||||
|
||||
private $linebreak;
|
||||
|
||||
/**
|
||||
* @param boolean $addReset
|
||||
* @param string $indent
|
||||
* @param string $getLinebreak
|
||||
*/
|
||||
public function __construct($addReset, $indent, $linebreak) {
|
||||
$this->addReset = $addReset;
|
||||
$this->indent = $indent;
|
||||
$this->linebreak = $linebreak;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render(array $list) {
|
||||
$line = $this->indent . 'opcache_compile_file(___BASEDIR___\'';
|
||||
$glue = '\');' . $this->linebreak . $line;
|
||||
|
||||
$firstLine = $this->addReset ? $this->indent . 'opcache_reset();' . $this->linebreak : '';
|
||||
return $firstLine . $line . implode($glue, $list) . '\');';
|
||||
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
use ncc\ThirdParty\theseer\Autoload\ParserInterface;
|
||||
|
||||
class CachingParser implements ParserInterface {
|
||||
|
||||
/**
|
||||
* @var ParserInterface
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
public function __construct(Cache $cache, ParserInterface $parser) {
|
||||
$this->cache = $cache;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given file for defintions of classes, traits and interfaces
|
||||
*
|
||||
* @param SourceFile $source file to process
|
||||
*
|
||||
* @return ParseResult
|
||||
*/
|
||||
public function parse(SourceFile $source) {
|
||||
if ($this->cache->hasResult($source)) {
|
||||
return $this->cache->getResult($source);
|
||||
}
|
||||
$result = $this->parser->parse($source);
|
||||
$this->cache->addResult($source, $result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
use ncc\ThirdParty\theseer\DirectoryScanner\PHPFilterIterator;
|
||||
|
||||
class Collector {
|
||||
|
||||
/**
|
||||
* @var ParserInterface
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var CollectorResult
|
||||
*/
|
||||
private $collectorResult;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $tolerantMode;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $trustingMode;
|
||||
|
||||
/**
|
||||
* Collector constructor.
|
||||
*
|
||||
* @param ParserInterface $parser
|
||||
* @param bool $tolerantMode
|
||||
* @param bool $trustingMode
|
||||
* @param array $whitelist
|
||||
* @param array $blacklist
|
||||
*/
|
||||
public function __construct(ParserInterface $parser, $tolerantMode = false, $trustingMode = true, Array $whitelist = array('*'), Array $blacklist = array()) {
|
||||
$this->parser = $parser;
|
||||
$this->tolerantMode = $tolerantMode;
|
||||
$this->trustingMode = $trustingMode;
|
||||
$this->collectorResult = new CollectorResult($whitelist, $blacklist);
|
||||
}
|
||||
|
||||
public function getResult() {
|
||||
return $this->collectorResult;
|
||||
}
|
||||
|
||||
public function processDirectory(\Iterator $sources) {
|
||||
$worker = $this->trustingMode ? $sources : new PHPFilterIterator($sources);
|
||||
foreach($worker as $file) {
|
||||
$this->processFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function processFile(\SplFileInfo $file) {
|
||||
if ($this->collectorResult->hasResultFor($file)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$parseResult = $this->parser->parse(new SourceFile($file->getRealPath()));
|
||||
if ($parseResult->hasRedeclarations() && !$this->tolerantMode) {
|
||||
throw new CollectorException(
|
||||
sprintf(
|
||||
"Duplicate (potentially conditional) definitions of the following unit(s) found:\n\n\tUnit(s): %s\n\tFile: %s",
|
||||
join(', ', $parseResult->getRedeclarations()),
|
||||
$file->getRealPath()
|
||||
),
|
||||
CollectorException::InFileRedeclarationFound
|
||||
);
|
||||
}
|
||||
$this->collectorResult->addParseResult($file, $parseResult);
|
||||
} catch(ParserException $e) {
|
||||
throw new CollectorException(
|
||||
sprintf(
|
||||
"Could not process file '%s' due to parse errors: %s",
|
||||
$file->getRealPath(),
|
||||
$e->getMessage()
|
||||
),
|
||||
CollectorException::ParseErrror,
|
||||
$e
|
||||
);
|
||||
} catch(CollectorResultException $e) {
|
||||
throw new CollectorException(
|
||||
$e->getMessage(),
|
||||
CollectorException::RedeclarationFound
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CollectorException extends \Exception {
|
||||
const ParseErrror = 1;
|
||||
const RedeclarationFound = 2;
|
||||
const InFileRedeclarationFound = 3;
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class CollectorResult {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $whitelist;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $blacklist;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $units = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $dependencies = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $seenFiles = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $duplicates = array();
|
||||
|
||||
public function __construct(array $whitelist, array $blacklist) {
|
||||
$this->whitelist = $whitelist;
|
||||
$this->blacklist = $blacklist;
|
||||
}
|
||||
|
||||
public function hasResultFor(\SplFileInfo $file) {
|
||||
return isset($this->seenFiles[$file->getRealPath()]);
|
||||
}
|
||||
|
||||
public function addParseResult(\SplFileInfo $file, ParseResult $result) {
|
||||
if (!$result->hasUnits()) {
|
||||
return;
|
||||
}
|
||||
$filename = $file->getRealPath();
|
||||
$this->seenFiles[$filename] = true;
|
||||
|
||||
foreach($result->getUnits() as $unit) {
|
||||
if (!$this->accept($unit)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($this->units[$unit])) {
|
||||
if (!isset($this->duplicates[$unit])) {
|
||||
$this->duplicates[$unit] = array( $this->units[$unit] );
|
||||
}
|
||||
$this->duplicates[$unit][] = $filename;
|
||||
continue;
|
||||
}
|
||||
$this->units[$unit] = $filename;
|
||||
$this->dependencies[$unit] = $result->getDependenciesForUnit($unit);
|
||||
}
|
||||
}
|
||||
|
||||
public function hasUnits() {
|
||||
return count($this->units) > 0;
|
||||
}
|
||||
|
||||
public function hasDuplicates() {
|
||||
return count($this->duplicates) > 0;
|
||||
}
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDependencies() {
|
||||
return $this->dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getUnits() {
|
||||
return $this->units;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $unit
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function accept($unit) {
|
||||
foreach($this->blacklist as $entry) {
|
||||
if (fnmatch($entry, $unit)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach($this->whitelist as $entry) {
|
||||
if (fnmatch($entry, $unit)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDuplicates() {
|
||||
return $this->duplicates;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CollectorResultException extends \Exception {
|
||||
const DuplicateUnitName = 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,183 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
use Exception;
|
||||
use Iterator;
|
||||
use ReturnTypeWillChange;
|
||||
use SplFileInfo;
|
||||
|
||||
class ComposerIterator implements Iterator {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $directories = array();
|
||||
|
||||
private $seen = array();
|
||||
|
||||
private $pos = 0;
|
||||
|
||||
public function __construct(SplFileInfo $composerFile) {
|
||||
if (!$composerFile->isFile() || !$composerFile->isReadable()) {
|
||||
throw new ComposerIteratorException(
|
||||
sprintf('Composer file "%s" not found or not readable', $composerFile->getPathname()),
|
||||
ComposerIteratorException::InvalidComposerJsonFile
|
||||
);
|
||||
}
|
||||
$composerDir = dirname($composerFile->getRealPath());
|
||||
$composerData = json_decode(file_get_contents($composerFile->getRealPath()), true);
|
||||
if (isset($composerData['require'])) {
|
||||
foreach($composerData['require'] as $require => $version) {
|
||||
if ($require === 'php' || strpos($require, 'ext-') === 0) {
|
||||
continue;
|
||||
}
|
||||
$this->processRequire($composerDir, $require);
|
||||
}
|
||||
}
|
||||
if (isset($composerData['autoload'])) {
|
||||
$this->processAutoload($composerDir, $composerData['autoload']);
|
||||
}
|
||||
}
|
||||
|
||||
private function processAutoload($baseDir, array $map) {
|
||||
if (isset($map['classmap'])) {
|
||||
foreach($map['classmap'] as $dir) {
|
||||
$this->addDirectory($baseDir . '/' . $dir);
|
||||
}
|
||||
}
|
||||
foreach(array('psr-0', 'psr-4') as $psr) {
|
||||
if (isset($map[$psr])) {
|
||||
foreach ($map[$psr] as $node => $dir) {
|
||||
if ($dir === '') {
|
||||
$this->addDirectory($baseDir);
|
||||
continue;
|
||||
}
|
||||
if (is_array($dir)) {
|
||||
foreach($dir as $d) {
|
||||
$this->addDirectory($baseDir . '/' . $d);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
$this->addDirectory($baseDir . '/' . $dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function processRequire($basedir, $require) {
|
||||
if (isset($this->seen[$require])) {
|
||||
return;
|
||||
}
|
||||
$this->seen[$require] = true;
|
||||
|
||||
$requireDir = $basedir . '/vendor/' . $require;
|
||||
$jsonFile = $this->findComposerJson($requireDir);
|
||||
if ($jsonFile === null) {
|
||||
return;
|
||||
}
|
||||
$jsonData = json_decode(file_get_contents($jsonFile), true);
|
||||
|
||||
if (isset($jsonData['require'])) {
|
||||
foreach($jsonData['require'] as $entry => $version) {
|
||||
if ($entry === 'php' || strpos($entry, 'ext-') === 0 || strpos($entry, 'lib-') === 0) {
|
||||
continue;
|
||||
}
|
||||
$this->processRequire($basedir, $entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($jsonData['autoload'])) {
|
||||
$this->processAutoload($requireDir, $jsonData['autoload']);
|
||||
return;
|
||||
}
|
||||
$this->addDirectory($requireDir);
|
||||
}
|
||||
|
||||
private function findComposerJson($dir) {
|
||||
if (file_exists($dir . '/composer.json')) {
|
||||
return $dir . '/composer.json';
|
||||
}
|
||||
foreach(glob($dir . '/*', GLOB_ONLYDIR) as $subDir) {
|
||||
$result = $this->findComposerJson($subDir);
|
||||
if ($result !== NULL) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function addDirectory($dir) {
|
||||
$dir = rtrim($dir, '/');
|
||||
if (!in_array($dir, $this->directories)) {
|
||||
$this->directories[] = $dir;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the current element
|
||||
*
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return mixed Can return any type.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function current() {
|
||||
return $this->directories[$this->pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Move forward to next element
|
||||
*
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function next() {
|
||||
$this->pos++;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the key of the current element
|
||||
*
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return mixed scalar on success, or null on failure.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function key() {
|
||||
return $this->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Checks if current position is valid
|
||||
*
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean The return value will be casted to boolean and then evaluated.
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function valid() {
|
||||
return $this->pos < count($this->directories);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Rewind the Iterator to the first element
|
||||
*
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function rewind() {
|
||||
$this->pos = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ComposerIteratorException extends Exception {
|
||||
const InvalidComposerJsonFile = 1;
|
||||
}
|
||||
|
||||
}
|
435
src/ncc/ThirdParty/theseer/Autoload/Config.php
vendored
435
src/ncc/ThirdParty/theseer/Autoload/Config.php
vendored
|
@ -1,435 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*
|
||||
*/
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class Config {
|
||||
|
||||
private $quietMode = FALSE;
|
||||
private $directories = array();
|
||||
private $outputFile = 'STDOUT';
|
||||
private $pharMode = FALSE;
|
||||
private $include = array('*.php');
|
||||
private $exclude = array();
|
||||
private $whitelist = array('*');
|
||||
private $blacklist = array();
|
||||
private $baseDirectory = NULL;
|
||||
private $template;
|
||||
private $linebreak = "\n";
|
||||
private $indent;
|
||||
private $lint = FALSE;
|
||||
private $php;
|
||||
private $compatMode = FALSE;
|
||||
private $staticMode = FALSE;
|
||||
private $warmMode = FALSE;
|
||||
private $tolerant = FALSE;
|
||||
private $trusting = TRUE;
|
||||
private $once = FALSE;
|
||||
private $reset = FALSE;
|
||||
private $lowercase = TRUE;
|
||||
private $dateFormat;
|
||||
private $variable = array();
|
||||
private $pharCompression = 'NONE';
|
||||
private $pharKey;
|
||||
private $pharAll = false;
|
||||
private $pharAliasName = '';
|
||||
private $pharHashAlgorithm;
|
||||
private $followSymlinks = false;
|
||||
private $cacheFilename;
|
||||
private $prepend = false;
|
||||
private $exceptions = true;
|
||||
|
||||
public function __construct(Array $directories) {
|
||||
$this->directories = $directories;
|
||||
$this->php = (PHP_OS === 'WIN' ? 'C:\php\php.exe' : '/usr/bin/php');
|
||||
}
|
||||
|
||||
public function setBaseDirectory($baseDirectory) {
|
||||
$this->baseDirectory = $baseDirectory;
|
||||
}
|
||||
|
||||
public function getBaseDirectory() {
|
||||
if ($this->baseDirectory !== NULL) {
|
||||
return realpath($this->baseDirectory);
|
||||
}
|
||||
if ($this->isPharMode()) {
|
||||
$comparator = new PathComparator($this->directories);
|
||||
return $comparator->getCommonBase();
|
||||
}
|
||||
if ($this->outputFile != 'STDOUT') {
|
||||
return realpath(dirname($this->outputFile) ?: '.');
|
||||
}
|
||||
$tmp = $this->getDirectories();
|
||||
return realpath(is_dir($tmp[0]) ? $tmp[0] : (dirname($tmp[0]) ?: '.'));
|
||||
}
|
||||
|
||||
public function setCompatMode($compatMode) {
|
||||
$this->compatMode = $compatMode;
|
||||
}
|
||||
|
||||
public function isCompatMode() {
|
||||
return $this->compatMode === true;
|
||||
}
|
||||
|
||||
public function setDateFormat($dateFormat) {
|
||||
$this->dateFormat = $dateFormat;
|
||||
}
|
||||
|
||||
public function getDateFormat() {
|
||||
return $this->dateFormat;
|
||||
}
|
||||
|
||||
public function setExclude(Array $exclude) {
|
||||
$this->exclude = $exclude;
|
||||
}
|
||||
|
||||
public function getExclude() {
|
||||
return $this->exclude;
|
||||
}
|
||||
|
||||
public function setInclude(Array $include) {
|
||||
$this->include = $include;
|
||||
}
|
||||
|
||||
public function getInclude() {
|
||||
return $this->include;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getBlacklist() {
|
||||
return $this->blacklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $blacklist
|
||||
*/
|
||||
public function setBlacklist($blacklist) {
|
||||
$this->blacklist = $blacklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getWhitelist() {
|
||||
return $this->whitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $whitelist
|
||||
*/
|
||||
public function setWhitelist($whitelist) {
|
||||
$this->whitelist = $whitelist;
|
||||
}
|
||||
|
||||
public function setIndent($indent) {
|
||||
$this->indent = $indent;
|
||||
}
|
||||
|
||||
public function getIndent() {
|
||||
if ($this->indent !== NULL) {
|
||||
if (is_numeric($this->indent) && (int)$this->indent == $this->indent) {
|
||||
return str_repeat(' ', (int)$this->indent);
|
||||
}
|
||||
return $this->indent;
|
||||
}
|
||||
if ($this->isStaticMode() || $this->isWarmMode()) {
|
||||
return '';
|
||||
}
|
||||
return str_repeat(' ', $this->isCompatMode() ? 12 : 16);
|
||||
}
|
||||
|
||||
public function setLinebreak($linebreak) {
|
||||
$lbr = array('LF' => "\n", 'CR' => "\r", 'CRLF' => "\r\n" );
|
||||
if (isset($lbr[$linebreak])) {
|
||||
$this->linebreak = $lbr[$linebreak];
|
||||
} else {
|
||||
$this->linebreak = $linebreak;
|
||||
}
|
||||
}
|
||||
|
||||
public function getLinebreak() {
|
||||
return $this->linebreak;
|
||||
}
|
||||
|
||||
public function setLintMode($lint) {
|
||||
$this->lint = (boolean)$lint;
|
||||
}
|
||||
|
||||
public function isLintMode() {
|
||||
return $this->lint;
|
||||
}
|
||||
|
||||
public function setLowercaseMode($lowercase) {
|
||||
$this->lowercase = (boolean)$lowercase;
|
||||
}
|
||||
|
||||
public function isLowercaseMode() {
|
||||
return $this->lowercase;
|
||||
}
|
||||
|
||||
public function setOnceMode($once) {
|
||||
$this->once = (boolean)$once;
|
||||
}
|
||||
|
||||
public function isOnceMode() {
|
||||
return $this->once;
|
||||
}
|
||||
|
||||
public function setOutputFile($outputFile) {
|
||||
$this->outputFile = $outputFile;
|
||||
}
|
||||
|
||||
public function getOutputFile() {
|
||||
return $this->outputFile;
|
||||
}
|
||||
|
||||
public function enablePharMode($compression = 'NONE', $all = true, $key = NULL, $alias = NULL) {
|
||||
$this->pharMode = true;
|
||||
$this->pharCompression = $compression;
|
||||
$this->pharAll = (boolean)$all;
|
||||
$this->pharKey = $key;
|
||||
$this->pharAliasName = $alias;
|
||||
}
|
||||
|
||||
public function isPharMode() {
|
||||
return $this->pharMode;
|
||||
}
|
||||
|
||||
public function isPharAllMode() {
|
||||
return $this->pharAll;
|
||||
}
|
||||
|
||||
public function getPharCompression() {
|
||||
return $this->pharCompression;
|
||||
}
|
||||
|
||||
public function getPharKey() {
|
||||
return $this->pharKey;
|
||||
}
|
||||
|
||||
public function getPharAliasName() {
|
||||
return $this->pharAliasName;
|
||||
}
|
||||
|
||||
public function hasPharHashAlgorithm() {
|
||||
return $this->pharHashAlgorithm !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPharHashAlgorithm() {
|
||||
return $this->pharHashAlgorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pharHashAlgorithm
|
||||
*/
|
||||
public function setPharHashAlgorithm($pharHashAlgorithm) {
|
||||
if (!in_array($pharHashAlgorithm, array('SHA-512','SHA-256','SHA-1'))) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf('Algorithm %s not supported', $pharHashAlgorithm)
|
||||
);
|
||||
}
|
||||
$this->pharHashAlgorithm = $pharHashAlgorithm;
|
||||
}
|
||||
|
||||
public function setPhp($php) {
|
||||
$this->php = $php;
|
||||
}
|
||||
|
||||
public function getPhp() {
|
||||
return $this->php;
|
||||
}
|
||||
|
||||
public function setQuietMode($quietMode) {
|
||||
$this->quietMode = (boolean)$quietMode;
|
||||
}
|
||||
|
||||
public function setStaticMode($staticMode) {
|
||||
$this->staticMode = (boolean)$staticMode;
|
||||
$this->warmMode = FALSE;
|
||||
}
|
||||
|
||||
public function isStaticMode() {
|
||||
return $this->staticMode;
|
||||
}
|
||||
|
||||
public function setWarmMode($warmMode) {
|
||||
$this->warmMode = (boolean)$warmMode;
|
||||
$this->staticMode = FALSE;
|
||||
}
|
||||
|
||||
public function isWarmMode() {
|
||||
return $this->warmMode;
|
||||
}
|
||||
|
||||
public function setResetMode($resetMode) {
|
||||
$this->reset = (boolean)$resetMode;
|
||||
}
|
||||
|
||||
public function isResetMode() {
|
||||
return $this->reset;
|
||||
}
|
||||
|
||||
public function setTemplate($template) {
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
public function getTemplate() {
|
||||
$tplType = $this->isLowercaseMode() ? 'ci' : 'cs';
|
||||
$template = $this->template;
|
||||
if ($template !== NULL) {
|
||||
if (!file_exists($template)) {
|
||||
$alternative = __DIR__.'/templates/'. $tplType .'/'.$template;
|
||||
if (file_exists($alternative)) {
|
||||
$template = $alternative;
|
||||
}
|
||||
$alternative .= '.php.tpl';
|
||||
if (file_exists($alternative)) {
|
||||
$template = $alternative;
|
||||
}
|
||||
}
|
||||
return $template;
|
||||
}
|
||||
|
||||
// determine auto template to use
|
||||
$tplFile = 'default.php.tpl';
|
||||
if ($this->isCompatMode()) {
|
||||
$tplFile = 'php52.php.tpl';
|
||||
}
|
||||
|
||||
if ($this->isPharMode()) {
|
||||
if ($this->isStaticMode()) {
|
||||
$tplFile = 'staticphar.php.tpl';
|
||||
$tplType = '.';
|
||||
} else {
|
||||
$tplFile = 'phar.php.tpl';
|
||||
}
|
||||
} elseif ($this->isStaticMode() || $this->isWarmMode()) {
|
||||
$tplFile = 'static.php.tpl';
|
||||
$tplType = '.';
|
||||
}
|
||||
|
||||
return __DIR__.'/templates/'.$tplType.'/'.$tplFile;
|
||||
|
||||
}
|
||||
|
||||
public function setTolerantMode($tolerant) {
|
||||
$this->tolerant = (boolean)$tolerant;
|
||||
}
|
||||
|
||||
public function isTolerantMode() {
|
||||
return $this->tolerant;
|
||||
}
|
||||
|
||||
public function setTrusting($trusting) {
|
||||
$this->trusting = (boolean)$trusting;
|
||||
}
|
||||
|
||||
public function setFollowSymlinks($followSymlinks) {
|
||||
$this->followSymlinks = (boolean)$followSymlinks;
|
||||
}
|
||||
|
||||
public function isFollowSymlinks() {
|
||||
return $this->followSymlinks;
|
||||
}
|
||||
|
||||
public function isTrustingMode() {
|
||||
return $this->trusting;
|
||||
}
|
||||
|
||||
public function setVariable($name, $value) {
|
||||
$this->variable[$name] = $value;
|
||||
}
|
||||
|
||||
public function getVariables() {
|
||||
return $this->variable;
|
||||
}
|
||||
|
||||
public function isQuietMode() {
|
||||
return $this->quietMode;
|
||||
}
|
||||
|
||||
public function getDirectories() {
|
||||
$list = array();
|
||||
foreach($this->directories as $dir) {
|
||||
if (is_file($dir) && basename($dir) == 'composer.json') {
|
||||
foreach(new ComposerIterator(new \SplFileInfo($dir)) as $d) {
|
||||
$list[] = $d;
|
||||
}
|
||||
} else {
|
||||
foreach(glob($dir) as $match) {
|
||||
$list[] = $match;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function setCacheFile($filename) {
|
||||
$this->cacheFilename = $filename;
|
||||
}
|
||||
|
||||
public function isCacheEnabled() {
|
||||
return $this->cacheFilename !== NULL;
|
||||
}
|
||||
|
||||
public function getCacheFile() {
|
||||
return $this->cacheFilename;
|
||||
}
|
||||
|
||||
public function enablePrepend() {
|
||||
$this->prepend = true;
|
||||
}
|
||||
|
||||
public function usePrepend() {
|
||||
return $this->prepend;
|
||||
}
|
||||
|
||||
public function disableExceptions() {
|
||||
$this->exceptions = false;
|
||||
}
|
||||
|
||||
public function useExceptions() {
|
||||
return $this->exceptions;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*/
|
||||
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
/**
|
||||
* Sorting classes by depdendency for static requires
|
||||
*
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
*/
|
||||
class ClassDependencySorter {
|
||||
|
||||
private $classList;
|
||||
private $dependencies;
|
||||
|
||||
private $level;
|
||||
|
||||
private $sorted = array();
|
||||
|
||||
public function __construct(Array $classes, Array $dependencies) {
|
||||
$this->classList = $classes;
|
||||
$this->dependencies = $dependencies;
|
||||
}
|
||||
|
||||
public function process() {
|
||||
$this->level = 0;
|
||||
foreach($this->classList as $class => $file) {
|
||||
if (!in_array($class, $this->sorted)) {
|
||||
$this->resolve($class);
|
||||
}
|
||||
}
|
||||
|
||||
$res = array();
|
||||
foreach($this->sorted as $class) {
|
||||
if (!isset($this->classList[$class])) {
|
||||
continue;
|
||||
}
|
||||
$res[$class] = $this->classList[$class];
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function resolve($class) {
|
||||
$this->level++;
|
||||
if ($this->level == 50) {
|
||||
throw new ClassDependencySorterException("Can't resolve more than 50 levels of dependencies", ClassDependencySorterException::TooManyDependencyLevels);
|
||||
}
|
||||
if (isset($this->dependencies[$class])) {
|
||||
foreach($this->dependencies[$class] as $depclass) {
|
||||
if (!in_array($depclass, $this->sorted)) {
|
||||
$this->resolve($depclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->sorted[] = $class;
|
||||
$this->level--;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassDependencySorterException extends \Exception {
|
||||
|
||||
const TooManyDependencyLevels = 1;
|
||||
|
||||
}
|
||||
}
|
242
src/ncc/ThirdParty/theseer/Autoload/Factory.php
vendored
242
src/ncc/ThirdParty/theseer/Autoload/Factory.php
vendored
|
@ -1,242 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*
|
||||
*/
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
|
||||
use ncc\ThirdParty\theseer\DirectoryScanner\IncludeExcludeFilterIterator;
|
||||
|
||||
class Factory {
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @param \ncc\ThirdParty\theseer\Autoload\Config $config
|
||||
*/
|
||||
public function setConfig(Config $config) {
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CLI
|
||||
*/
|
||||
public function getCLI() {
|
||||
return new CLI($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Application
|
||||
*/
|
||||
public function getApplication() {
|
||||
return new Application($this->getLogger(), $this->config, $this);
|
||||
}
|
||||
|
||||
public function getLogger() {
|
||||
return new Logger($this->config->isQuietMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Parser
|
||||
*/
|
||||
public function getParser() {
|
||||
$parser = new Parser(
|
||||
$this->config->isLowercaseMode()
|
||||
);
|
||||
if (!$this->config->isCacheEnabled()) {
|
||||
return $parser;
|
||||
}
|
||||
return new CachingParser(
|
||||
$this->getCache(),
|
||||
$parser
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Cache
|
||||
*/
|
||||
public function getCache() {
|
||||
if (!$this->cache instanceof Cache) {
|
||||
$fname = $this->config->getCacheFile();
|
||||
if (file_exists($fname)) {
|
||||
$data = unserialize(file_get_contents($fname));
|
||||
} else {
|
||||
$data = array();
|
||||
}
|
||||
$this->cache = new Cache($data);
|
||||
}
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
public function getCollector() {
|
||||
return new Collector(
|
||||
$this->getParser(),
|
||||
$this->config->isTolerantMode(),
|
||||
$this->config->isTrustingMode(),
|
||||
$this->config->getWhitelist(),
|
||||
$this->config->getBlacklist()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance of DirectoryScanner with filter options applied
|
||||
*
|
||||
* @param bool $filter
|
||||
* @return DirectoryScanner
|
||||
*/
|
||||
public function getScanner($filter = TRUE) {
|
||||
$scanner = new DirectoryScanner;
|
||||
if ($filter) {
|
||||
$scanner->setIncludes($this->config->getInclude());
|
||||
$scanner->setExcludes($this->config->getExclude());
|
||||
}
|
||||
if ($this->config->isFollowSymlinks()) {
|
||||
$scanner->setFlag(\FilesystemIterator::FOLLOW_SYMLINKS);
|
||||
}
|
||||
return $scanner;
|
||||
}
|
||||
|
||||
public function getFilter(\Iterator $files) {
|
||||
$filter = new IncludeExcludeFilterIterator($files);
|
||||
$filter->setInclude($this->config->getInclude());
|
||||
$filter->setExclude($this->config->getExclude());
|
||||
return $filter;
|
||||
}
|
||||
|
||||
|
||||
public function getPharBuilder() {
|
||||
$builder = new PharBuilder(
|
||||
$this->getScanner(!$this->config->isPharAllMode()),
|
||||
$this->config->getBaseDirectory()
|
||||
);
|
||||
$builder->setCompressionMode($this->config->getPharCompression());
|
||||
foreach($this->config->getDirectories() as $directory) {
|
||||
$builder->addDirectory($directory);
|
||||
}
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get instance of AutoloadRenderer with cli options applied
|
||||
*
|
||||
* @param CollectorResult $result
|
||||
*
|
||||
* @return \ncc\ThirdParty\theseer\Autoload\AutoloadRenderer|\ncc\ThirdParty\theseer\Autoload\StaticRenderer
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getRenderer(CollectorResult $result) {
|
||||
$isStatic = $this->config->isStaticMode();
|
||||
$isPhar = $this->config->isPharMode();
|
||||
$isCompat = $this->config->isCompatMode();
|
||||
$isOnce = $this->config->isOnceMode();
|
||||
$isWarm = $this->config->isWarmMode();
|
||||
$isReset = $this->config->isResetMode();
|
||||
|
||||
if ($isWarm === TRUE) {
|
||||
$renderer = new StaticRenderer(
|
||||
$result->getUnits(),
|
||||
$this->getCacheWarmingListRenderer($isReset)
|
||||
);
|
||||
$renderer->setDependencies($result->getDependencies());
|
||||
$renderer->setPharMode($isPhar);
|
||||
} else if ($isStatic === TRUE) {
|
||||
$renderer = new StaticRenderer(
|
||||
$result->getUnits(),
|
||||
$this->getStaticRequireListRenderer($isOnce)
|
||||
);
|
||||
$renderer->setDependencies($result->getDependencies());
|
||||
$renderer->setPharMode($isPhar);
|
||||
} else {
|
||||
$renderer = new AutoloadRenderer($result->getUnits());
|
||||
if ($this->config->usePrepend()) {
|
||||
$renderer->prependAutoloader();
|
||||
}
|
||||
if ($this->config->useExceptions()) {
|
||||
$renderer->enableExceptions();
|
||||
}
|
||||
}
|
||||
|
||||
$renderer->setCompat($isCompat);
|
||||
|
||||
$basedir = $this->config->getBaseDirectory();
|
||||
if (!$basedir || !is_dir($basedir)) {
|
||||
throw new \RuntimeException("Given basedir '{$basedir}' does not exist or is not a directory");
|
||||
}
|
||||
$renderer->setBaseDir($basedir);
|
||||
|
||||
$format = $this->config->getDateFormat();
|
||||
if ($format) {
|
||||
$renderer->setDateTimeFormat($format);
|
||||
}
|
||||
|
||||
$renderer->setIndent($this->config->getIndent());
|
||||
$renderer->setLineBreak($this->config->getLinebreak());
|
||||
|
||||
foreach($this->config->getVariables() as $name => $value) {
|
||||
$renderer->setVariable($name, $value);
|
||||
}
|
||||
|
||||
return $renderer;
|
||||
}
|
||||
|
||||
private function getStaticRequireListRenderer($useOnce) {
|
||||
return new StaticRequireListRenderer(
|
||||
$useOnce,
|
||||
$this->config->getIndent(),
|
||||
$this->config->getLinebreak()
|
||||
);
|
||||
}
|
||||
|
||||
private function getCacheWarmingListRenderer($addReset) {
|
||||
return new CacheWarmingListRenderer(
|
||||
$addReset,
|
||||
$this->config->getIndent(),
|
||||
$this->config->getLinebreak()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
31
src/ncc/ThirdParty/theseer/Autoload/LICENSE
vendored
31
src/ncc/ThirdParty/theseer/Autoload/LICENSE
vendored
|
@ -1,31 +0,0 @@
|
|||
Autoload Builder
|
||||
|
||||
Copyright (c) 2010-2016 Arne Blankerts <arne@blankerts.de> and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Arne Blankerts nor the names of contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
59
src/ncc/ThirdParty/theseer/Autoload/Logger.php
vendored
59
src/ncc/ThirdParty/theseer/Autoload/Logger.php
vendored
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*
|
||||
*/
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class Logger {
|
||||
|
||||
private $quiet = FALSE;
|
||||
|
||||
/**
|
||||
* @param bool $quietMode
|
||||
*/
|
||||
public function __construct($quietMode = FALSE) {
|
||||
$this->quiet = $quietMode;
|
||||
}
|
||||
|
||||
public function log($message, $target = STDOUT) {
|
||||
if ($this->quiet) {
|
||||
return;
|
||||
}
|
||||
fwrite($target, $message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class ParseResult {
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $units = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $dependencies = array();
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $redeclarations = array();
|
||||
|
||||
public function __construct(Array $units, Array $dependencies, Array $redeclarations) {
|
||||
$this->units = $units;
|
||||
$this->dependencies = $dependencies;
|
||||
$this->redeclarations = $redeclarations;
|
||||
}
|
||||
|
||||
public function hasUnits() {
|
||||
return count($this->units) > 0;
|
||||
}
|
||||
|
||||
public function hasRedeclarations() {
|
||||
return count($this->redeclarations) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $unit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDependenciesForUnit($unit) {
|
||||
if (!isset($this->dependencies[$unit])) {
|
||||
return array();
|
||||
}
|
||||
return $this->dependencies[$unit];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \string[]
|
||||
*/
|
||||
public function getRedeclarations() {
|
||||
return $this->redeclarations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \string[]
|
||||
*/
|
||||
public function getUnits() {
|
||||
return $this->units;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
598
src/ncc/ThirdParty/theseer/Autoload/Parser.php
vendored
598
src/ncc/ThirdParty/theseer/Autoload/Parser.php
vendored
|
@ -1,598 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of Arne Blankerts nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @package Autoload
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
* @license BSD License
|
||||
*/
|
||||
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
// PHP 5.3 compat
|
||||
define('T_TRAIT_53', 10355);
|
||||
if (!defined('T_TRAIT')) {
|
||||
define('T_TRAIT', -1);
|
||||
}
|
||||
|
||||
// PHP 8.0 forward compat
|
||||
if (!defined('T_NAME_FULLY_QUALIFIED')) {
|
||||
define('T_NAME_FULLY_QUALIFIED', -1);
|
||||
define('T_NAME_QUALIFIED', -1);
|
||||
}
|
||||
|
||||
// PHP 8.1 forward compat
|
||||
if (!defined('T_ENUM')) {
|
||||
define('T_ENUM', -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Namespace aware parser to find and extract defined classes within php source files
|
||||
*
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
*/
|
||||
class Parser implements ParserInterface {
|
||||
|
||||
private $methodMap = array(
|
||||
T_TRAIT => 'processClass',
|
||||
T_TRAIT_53 => 'processClass',
|
||||
T_CLASS => 'processClass',
|
||||
T_ENUM => 'processEnum',
|
||||
//T_CASE => 'processEnumCase',
|
||||
T_INTERFACE => 'processInterface',
|
||||
T_NAMESPACE => 'processNamespace',
|
||||
T_USE => 'processUse',
|
||||
'}' => 'processBracketClose',
|
||||
'{' => 'processBracketOpen',
|
||||
T_CURLY_OPEN => 'processBracketOpen',
|
||||
T_DOLLAR_OPEN_CURLY_BRACES => 'processBracketOpen'
|
||||
);
|
||||
|
||||
private $typeMap = array(
|
||||
T_INTERFACE => 'interface',
|
||||
T_CLASS => 'class',
|
||||
T_ENUM => 'enum',
|
||||
T_TRAIT => 'trait',
|
||||
T_TRAIT_53 => 'trait'
|
||||
);
|
||||
|
||||
private $caseInsensitive;
|
||||
|
||||
private $tokenArray = array();
|
||||
|
||||
private $inNamespace = '';
|
||||
private $inUnit = '';
|
||||
|
||||
private $nsBracket = 0;
|
||||
private $classBracket = 0;
|
||||
|
||||
private $bracketLevel = 0;
|
||||
private $aliases = array();
|
||||
|
||||
private $found = array();
|
||||
private $dependencies = array();
|
||||
private $redeclarations = array();
|
||||
|
||||
public function __construct($caseInsensitive = true) {
|
||||
$this->caseInsensitive = $caseInsensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a given file for defintions of classes, traits and interfaces
|
||||
*
|
||||
* @param SourceFile $source file to process
|
||||
*
|
||||
* @return ParseResult
|
||||
*/
|
||||
public function parse(SourceFile $source) {
|
||||
$this->found = array();
|
||||
$this->redeclarations = array();
|
||||
$this->inNamespace = '';
|
||||
$this->aliases = array();
|
||||
$this->bracketLevel = 0;
|
||||
$this->inUnit = '';
|
||||
$this->nsBracket = 0;
|
||||
$this->classBracket = 0;
|
||||
$this->tokenArray = $source->getTokens();
|
||||
$tokenCount = count($this->tokenArray);
|
||||
$tokList = array_keys($this->methodMap);
|
||||
for($t=0; $t<$tokenCount; $t++) {
|
||||
$current = (array)$this->tokenArray[$t];
|
||||
|
||||
if ($current[0]===T_STRING && $current[1]==='trait' && T_TRAIT===-1) {
|
||||
// PHP < 5.4 compat fix
|
||||
$current[0] = T_TRAIT_53;
|
||||
$this->tokenArray[$t] = $current;
|
||||
}
|
||||
if (!in_array($current[0], $tokList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$t = call_user_func(array($this, $this->methodMap[$current[0]]), $t);
|
||||
}
|
||||
return new ParseResult($this->found, $this->dependencies, $this->redeclarations);
|
||||
}
|
||||
|
||||
private function processBracketOpen($pos) {
|
||||
$this->bracketLevel++;
|
||||
return $pos + 1;
|
||||
}
|
||||
|
||||
private function processBracketClose($pos) {
|
||||
$this->bracketLevel--;
|
||||
if ($this->nsBracket !== 0 && $this->bracketLevel < $this->nsBracket) {
|
||||
$this->inNamespace = '';
|
||||
$this->nsBracket = 0;
|
||||
$this->aliases = array();
|
||||
}
|
||||
if ($this->bracketLevel <= $this->classBracket) {
|
||||
$this->classBracket = 0;
|
||||
$this->inUnit = '';
|
||||
}
|
||||
return $pos + 1;
|
||||
}
|
||||
|
||||
private function processClass($pos) {
|
||||
if (!$this->classTokenNeedsProcessing($pos)) {
|
||||
return $pos;
|
||||
}
|
||||
$list = array('{');
|
||||
$stack = $this->getTokensTill($pos, $list);
|
||||
$stackSize = count($stack);
|
||||
$classname = $this->inNamespace !== '' ? $this->inNamespace . '\\' : '';
|
||||
$extends = '';
|
||||
$extendsFound = false;
|
||||
$implementsFound = false;
|
||||
$implementsList = array();
|
||||
$implements = '';
|
||||
$mode = 'classname';
|
||||
foreach(array_slice($stack, 1, -1) as $tok) {
|
||||
switch ($tok[0]) {
|
||||
case T_COMMENT:
|
||||
case T_DOC_COMMENT:
|
||||
case T_WHITESPACE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case T_NAME_FULLY_QUALIFIED:
|
||||
case T_NAME_QUALIFIED:
|
||||
case T_STRING: {
|
||||
$$mode .= $tok[1];
|
||||
break;
|
||||
}
|
||||
case T_NS_SEPARATOR: {
|
||||
$$mode .= '\\';
|
||||
break;
|
||||
}
|
||||
case T_EXTENDS: {
|
||||
$extendsFound = true;
|
||||
$mode = 'extends';
|
||||
break;
|
||||
}
|
||||
case T_IMPLEMENTS: {
|
||||
$implementsFound = true;
|
||||
$mode = 'implements';
|
||||
break;
|
||||
}
|
||||
|
||||
case ',': {
|
||||
if ($mode === 'implements') {
|
||||
$implementsList[] = $this->resolveDependencyName($implements);
|
||||
$implements = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new ParserException(sprintf(
|
||||
'Parse error while trying to process class definition (unexpected token "%s" in name).',
|
||||
\token_name($tok[0])
|
||||
), ParserException::ParseError
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($implements != '') {
|
||||
$implementsList[] = $this->resolveDependencyName($implements);
|
||||
}
|
||||
if ($implementsFound && count($implementsList)==0) {
|
||||
throw new ParserException(sprintf(
|
||||
'Parse error while trying to process class definition (extends or implements).'
|
||||
), ParserException::ParseError
|
||||
);
|
||||
}
|
||||
$classname = $this->registerUnit($classname, $stack[0][0]);
|
||||
$this->dependencies[$classname] = $implementsList;
|
||||
if ($extendsFound) {
|
||||
$this->dependencies[$classname][] = $this->resolveDependencyName($extends);
|
||||
}
|
||||
$this->inUnit = $classname;
|
||||
$this->classBracket = $this->bracketLevel + 1;
|
||||
return $pos + $stackSize - 1;
|
||||
}
|
||||
|
||||
private function processEnum($pos) {
|
||||
$list = array('{');
|
||||
$stack = $this->getTokensTill($pos, $list);
|
||||
$stackSize = count($stack);
|
||||
$enumName = $this->inNamespace !== '' ? $this->inNamespace . '\\' : '';
|
||||
$implementsFound = false;
|
||||
$implementsList = array();
|
||||
$implements = '';
|
||||
$backType = '';
|
||||
$mode = 'enumName';
|
||||
foreach(array_slice($stack, 1, -1) as $tok) {
|
||||
switch ($tok[0]) {
|
||||
case T_COMMENT:
|
||||
case T_DOC_COMMENT:
|
||||
case T_WHITESPACE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case T_NAME_FULLY_QUALIFIED:
|
||||
case T_NAME_QUALIFIED:
|
||||
case T_STRING: {
|
||||
$$mode .= $tok[1];
|
||||
break;
|
||||
}
|
||||
case T_NS_SEPARATOR: {
|
||||
$$mode .= '\\';
|
||||
break;
|
||||
}
|
||||
case T_IMPLEMENTS: {
|
||||
$implementsFound = true;
|
||||
$mode = 'implements';
|
||||
break;
|
||||
}
|
||||
|
||||
case ':': {
|
||||
$isBacked = true;
|
||||
$mode = 'backType';
|
||||
break;
|
||||
}
|
||||
|
||||
case ',': {
|
||||
if ($mode === 'implements') {
|
||||
$implementsList[] = $this->resolveDependencyName($implements);
|
||||
$implements = '';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new ParserException(sprintf(
|
||||
'Parse error while trying to process class definition (unexpected token "%s" in name).',
|
||||
is_int($tok[0]) ? \token_name($tok[0]) : $tok[0]
|
||||
), ParserException::ParseError
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($implements != '') {
|
||||
$implementsList[] = $this->resolveDependencyName($implements);
|
||||
}
|
||||
if ($implementsFound && count($implementsList)==0) {
|
||||
throw new ParserException(sprintf(
|
||||
'Parse error while trying to process enum definition (implements).'
|
||||
), ParserException::ParseError
|
||||
);
|
||||
}
|
||||
|
||||
$enumName = $this->registerUnit($enumName, $stack[0][0]);
|
||||
$this->dependencies[$enumName] = $implementsList;
|
||||
|
||||
return $pos + $stackSize - 1;
|
||||
}
|
||||
|
||||
private function processInterface($pos) {
|
||||
$list = array('{');
|
||||
$stack = $this->getTokensTill($pos, $list);
|
||||
$stackSize = count($stack);
|
||||
$next = $stack[1];
|
||||
if (is_array($next) && $next[0] === '(') {
|
||||
// sort of inline use - ignore
|
||||
return $pos + $stackSize;
|
||||
}
|
||||
|
||||
$name = $this->inNamespace != '' ? $this->inNamespace . '\\' : '';
|
||||
$extends = '';
|
||||
$extendsList = array();
|
||||
$mode = 'name';
|
||||
foreach(array_slice($stack, 1, -1) as $tok) {
|
||||
switch ($tok[0]) {
|
||||
case T_NS_SEPARATOR:
|
||||
case T_NAME_QUALIFIED:
|
||||
case T_NAME_FULLY_QUALIFIED:
|
||||
case T_STRING: {
|
||||
$$mode .= $tok[1];
|
||||
break;
|
||||
}
|
||||
case T_EXTENDS: {
|
||||
$mode = 'extends';
|
||||
break;
|
||||
}
|
||||
case ',': {
|
||||
if ($mode == 'extends') {
|
||||
$extendsList[] = $this->resolveDependencyName($extends);
|
||||
$extends = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$name = $this->registerUnit($name, T_INTERFACE);
|
||||
if ($extends != '') {
|
||||
$extendsList[] = $this->resolveDependencyName($extends);
|
||||
}
|
||||
$this->dependencies[$name] = $extendsList;
|
||||
$this->inUnit = $name;
|
||||
return $pos + $stackSize - 1;
|
||||
}
|
||||
|
||||
private function resolveDependencyName($name) {
|
||||
if ($name == '') {
|
||||
throw new ParserException(sprintf(
|
||||
'Parse error while trying to process class definition (extends or implements).'
|
||||
), ParserException::ParseError
|
||||
);
|
||||
}
|
||||
if ($name[0] == '\\') {
|
||||
$name = substr($name, 1);
|
||||
} else {
|
||||
$parts = explode('\\', $name, 2);
|
||||
$search = $this->caseInsensitive ? strtolower($parts[0]) : $parts[0];
|
||||
$key = array_search($search, $this->aliases);
|
||||
if (!$key) {
|
||||
$name = ($this->inNamespace != '' ? $this->inNamespace . '\\' : ''). $name;
|
||||
} else {
|
||||
$name = $key;
|
||||
if (isset($parts[1])) {
|
||||
$name .= '\\' . $parts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->caseInsensitive) {
|
||||
$name = strtolower($name);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function registerUnit($name, $type) {
|
||||
if ($name == '' || substr($name, -1) == '\\') {
|
||||
throw new ParserException(sprintf(
|
||||
'Parse error while trying to process %s definition.',
|
||||
$this->typeMap[$type]
|
||||
), ParserException::ParseError
|
||||
);
|
||||
}
|
||||
if ($this->caseInsensitive) {
|
||||
$name = strtolower($name);
|
||||
}
|
||||
if (in_array($name, $this->found)) {
|
||||
$this->redeclarations[] = $name;
|
||||
} else {
|
||||
$this->found[] = $name;
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function processNamespace($pos) {
|
||||
$list = array(';', '{');
|
||||
$stack = $this->getTokensTill($pos, $list);
|
||||
$stackSize = count($stack);
|
||||
$newpos = $pos + $stackSize;
|
||||
if ($stackSize < 3) { // empty namespace defintion == root namespace
|
||||
$this->inNamespace = '';
|
||||
$this->aliases = array();
|
||||
return $newpos - 1;
|
||||
}
|
||||
$next = $stack[1];
|
||||
if (is_array($next) && ($next[0] === T_NS_SEPARATOR || $next[0] === '(')) {
|
||||
// sort of inline use - ignore
|
||||
return $newpos;
|
||||
}
|
||||
|
||||
$this->inNamespace = '';
|
||||
foreach(array_slice($stack, 1, -1) as $tok) {
|
||||
$this->inNamespace .= $tok[1];
|
||||
}
|
||||
$this->aliases = array();
|
||||
|
||||
return $pos + $stackSize - 1;
|
||||
}
|
||||
|
||||
private function processUse($pos) {
|
||||
$list = array(';','(');
|
||||
$stack = $this->getTokensTill($pos, $list);
|
||||
$stackSize = count($stack);
|
||||
$ignore = array(
|
||||
'(', // closue use
|
||||
T_CONST, // use const foo\bar;
|
||||
T_FUNCTION // use function foo\bar;
|
||||
);
|
||||
if (in_array($stack[1][0], $ignore)) {
|
||||
return $pos + $stackSize - 1;
|
||||
}
|
||||
|
||||
if ($this->classBracket > 0) {
|
||||
$this->parseUseOfTrait($stackSize, $stack);
|
||||
|
||||
} else {
|
||||
$this->parseUseAsImport($stack);
|
||||
|
||||
}
|
||||
return $pos + $stackSize - 1;
|
||||
}
|
||||
|
||||
private function getTokensTill($start, $list) {
|
||||
$list = (array)$list;
|
||||
$stack = array();
|
||||
$skip = array(
|
||||
T_WHITESPACE,
|
||||
T_COMMENT,
|
||||
T_DOC_COMMENT
|
||||
);
|
||||
$limit = count($this->tokenArray);
|
||||
for ($t=$start; $t<$limit; $t++) {
|
||||
$current = (array)$this->tokenArray[$t];
|
||||
if (in_array($current[0], $skip)) {
|
||||
continue;
|
||||
}
|
||||
$stack[] = $current;
|
||||
if (in_array($current[0], $list)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $stackSize
|
||||
* @param $stack
|
||||
*/
|
||||
private function parseUseOfTrait($stackSize, $stack) {
|
||||
$use = '';
|
||||
for ($t = 0; $t < $stackSize; $t++) {
|
||||
$current = (array)$stack[$t];
|
||||
switch ($current[0]) {
|
||||
case '{': {
|
||||
// find closing bracket to skip contents
|
||||
for ($x = $t + 1; $x < $stackSize; $x++) {
|
||||
$tok = $stack[$x];
|
||||
if ($tok[0] == '}') {
|
||||
$t = $x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ';':
|
||||
case ',': {
|
||||
$this->dependencies[$this->inUnit][] = $this->resolveDependencyName($use);
|
||||
$use = '';
|
||||
break;
|
||||
}
|
||||
case T_NS_SEPARATOR:
|
||||
case T_NAME_QUALIFIED:
|
||||
case T_NAME_FULLY_QUALIFIED:
|
||||
case T_STRING: {
|
||||
$use .= $current[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $stack
|
||||
*/
|
||||
private function parseUseAsImport($stack) {
|
||||
$use = '';
|
||||
$alias = '';
|
||||
$mode = 'use';
|
||||
$group = '';
|
||||
$ignore = false;
|
||||
foreach ($stack as $tok) {
|
||||
$current = $tok;
|
||||
switch ($current[0]) {
|
||||
case T_CONST:
|
||||
case T_FUNCTION: {
|
||||
$ignore = true;
|
||||
break;
|
||||
}
|
||||
case '{': {
|
||||
$group = $use;
|
||||
break;
|
||||
}
|
||||
case ';':
|
||||
case ',': {
|
||||
if (!$ignore) {
|
||||
if ($alias == '') {
|
||||
$nss = strrpos($use, '\\');
|
||||
if ($nss !== FALSE) {
|
||||
$alias = substr($use, $nss + 1);
|
||||
} else {
|
||||
$alias = $use;
|
||||
}
|
||||
}
|
||||
if ($this->caseInsensitive) {
|
||||
$alias = strtolower($alias);
|
||||
}
|
||||
$this->aliases[$use] = $alias;
|
||||
}
|
||||
$alias = '';
|
||||
$use = $group;
|
||||
$mode = 'use';
|
||||
$ignore = false;
|
||||
break;
|
||||
}
|
||||
case T_NS_SEPARATOR:
|
||||
case T_NAME_QUALIFIED:
|
||||
case T_NAME_FULLY_QUALIFIED:
|
||||
case T_STRING: {
|
||||
$$mode .= $current[1];
|
||||
break;
|
||||
}
|
||||
case T_AS: {
|
||||
$mode = 'alias';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function classTokenNeedsProcessing($position) {
|
||||
|
||||
// PHP 5.5 has classname::class, reusing T_CLASS
|
||||
if ($this->tokenArray[$position-1][0] == T_DOUBLE_COLON) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PHP 7 has anonymous classes: $x = new class { ... }
|
||||
if ($position > 2 && $this->tokenArray[$position-2][0] === T_NEW) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->tokenArray[$position + 1] === '(' || $this->tokenArray[$position + 2] === '(') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ParserException extends \Exception {
|
||||
|
||||
const ParseError = 1;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload;
|
||||
|
||||
/**
|
||||
* Namespace aware parser to find and extract defined classes within php source files
|
||||
*
|
||||
* @author Arne Blankerts <arne@blankerts.de>
|
||||
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
|
||||
*/
|
||||
interface ParserInterface {
|
||||
|
||||
/**
|
||||
* Parse a given file for defintions of classes, traits and interfaces
|
||||
*
|
||||
* @param SourceFile $source file to process
|
||||
*
|
||||
* @return ParseResult
|
||||
*/
|
||||
public function parse(SourceFile $source);
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
namespace ncc\ThirdParty\theseer\Autoload {
|
||||
|
||||
class PathComparator {
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $directories = array();
|
||||
|
||||
/**
|
||||
* PathComparator constructor.
|
||||
*
|
||||
* @param array $directories
|
||||
*/
|
||||
public function __construct(array $directories) {
|
||||
foreach($directories as $dir) {
|
||||
$this->directories[] = realpath($dir).'/';
|
||||
}
|
||||
}
|
||||
|
||||
public function getCommonBase() {
|
||||
if (count($this->directories) == 0) {
|
||||
return '/';
|
||||
}
|
||||
$result = $this->directories[0];
|
||||
foreach($this->directories as $dir) {
|
||||
$result = substr($dir, 0, $this->commonPrefix($result, $dir));
|
||||
}
|
||||
return ($result ?: '/');
|
||||
}
|
||||
|
||||
|
||||
private function commonPrefix( $s1, $s2 ) {
|
||||
$l1 = strlen($s1);
|
||||
$l2 = strlen($s2);
|
||||
$i=0;
|
||||
while($i < $l1 && $i < $l2 && $s1[$i] == $s2[$i]) {
|
||||
$i++;
|
||||
}
|
||||
return strrpos(substr($s1, 0, $i), '/');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue