Обновление клиента (apps, 3rdparty, install)
This commit is contained in:
@@ -0,0 +1,907 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* LICENSE: The MIT License (the "License")
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* https://github.com/azure/azure-storage-php/LICENSE
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @ignore
|
||||
* @category Microsoft
|
||||
* @package MicrosoftAzure\Storage\Common\Internal
|
||||
* @author Azure Storage PHP SDK <dmsh@microsoft.com>
|
||||
* @copyright 2016 Microsoft Corporation
|
||||
* @license https://github.com/azure/azure-storage-php/LICENSE
|
||||
* @link https://github.com/azure/azure-storage-php
|
||||
*/
|
||||
|
||||
namespace MicrosoftAzure\Storage\Common\Internal;
|
||||
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* Utilities for the project
|
||||
*
|
||||
* @category Microsoft
|
||||
* @package MicrosoftAzure\Storage\Common\Internal
|
||||
* @author Azure Storage PHP SDK <dmsh@microsoft.com>
|
||||
* @copyright 2016 Microsoft Corporation
|
||||
* @license https://github.com/azure/azure-storage-php/LICENSE
|
||||
* @link https://github.com/azure/azure-storage-php
|
||||
*/
|
||||
class Utilities
|
||||
{
|
||||
/**
|
||||
* Returns the specified value of the $key passed from $array and in case that
|
||||
* this $key doesn't exist, the default value is returned.
|
||||
*
|
||||
* @param array $array The array to be used.
|
||||
* @param mixed $key The array key.
|
||||
* @param mixed $default The value to return if $key is not found in $array.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function tryGetValue($array, $key, $default = null)
|
||||
{
|
||||
return (!is_null($array)) && is_array($array) && array_key_exists($key, $array)
|
||||
? $array[$key]
|
||||
: $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a url scheme if there is no scheme. Return null if input URL is null.
|
||||
*
|
||||
* @param string $url The URL.
|
||||
* @param string $scheme The scheme. By default HTTP
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function tryAddUrlScheme($url, $scheme = 'http')
|
||||
{
|
||||
if ($url == null) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$urlScheme = parse_url($url, PHP_URL_SCHEME);
|
||||
|
||||
if (empty($urlScheme)) {
|
||||
$url = "$scheme://" . $url;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse storage account name from an endpoint url.
|
||||
*
|
||||
* @param string $url The endpoint $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function tryParseAccountNameFromUrl($url)
|
||||
{
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
|
||||
// first token of the url host is account name
|
||||
return explode('.', $host)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse secondary endpoint url string from a primary endpoint url.
|
||||
*
|
||||
* Return null if the primary endpoint url is invalid.
|
||||
*
|
||||
* @param string $uri The primary endpoint url string.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function tryGetSecondaryEndpointFromPrimaryEndpoint($uri)
|
||||
{
|
||||
$splitTokens = explode('.', $uri);
|
||||
if (count($splitTokens) > 0 && $splitTokens[0] != '') {
|
||||
$schemaAccountToken = $splitTokens[0];
|
||||
$schemaAccountSplitTokens = explode('/', $schemaAccountToken);
|
||||
if (count($schemaAccountSplitTokens) > 0 &&
|
||||
$schemaAccountSplitTokens[0] != '') {
|
||||
$accountName = $schemaAccountSplitTokens[
|
||||
count($schemaAccountSplitTokens) - 1
|
||||
];
|
||||
$schemaAccountSplitTokens[count($schemaAccountSplitTokens) - 1] =
|
||||
$accountName . Resources::SECONDARY_STRING;
|
||||
|
||||
$splitTokens[0] = implode('/', $schemaAccountSplitTokens);
|
||||
$secondaryUri = implode('.', $splitTokens);
|
||||
return $secondaryUri;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* tries to get nested array with index name $key from $array.
|
||||
*
|
||||
* Returns empty array object if the value is NULL.
|
||||
*
|
||||
* @param string $key The index name.
|
||||
* @param array $array The array object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function tryGetArray($key, array $array)
|
||||
{
|
||||
return Utilities::getArray(Utilities::tryGetValue($array, $key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given key/value pair into array if the value doesn't satisfy empty().
|
||||
*
|
||||
* This function just validates that the given $array is actually array. If it's
|
||||
* NULL the function treats it as array.
|
||||
*
|
||||
* @param string $key The key.
|
||||
* @param string $value The value.
|
||||
* @param array &$array The array. If NULL will be used as array.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function addIfNotEmpty($key, $value, array &$array)
|
||||
{
|
||||
if (!is_null($array)) {
|
||||
Validate::isArray($array, 'array');
|
||||
}
|
||||
|
||||
if (!empty($value)) {
|
||||
$array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified value of the key chain passed from $array and in case
|
||||
* that key chain doesn't exist, null is returned.
|
||||
*
|
||||
* @param array $array Array to be used.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function tryGetKeysChainValue(array $array)
|
||||
{
|
||||
$arguments = func_get_args();
|
||||
$numArguments = func_num_args();
|
||||
|
||||
$currentArray = $array;
|
||||
for ($i = 1; $i < $numArguments; $i++) {
|
||||
if (is_array($currentArray)) {
|
||||
if (array_key_exists($arguments[$i], $currentArray)) {
|
||||
$currentArray = $currentArray[$arguments[$i]];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $currentArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed $string starts with $prefix
|
||||
*
|
||||
* @param string $string word to seaech in
|
||||
* @param string $prefix prefix to be matched
|
||||
* @param boolean $ignoreCase true to ignore case during the comparison;
|
||||
* otherwise, false
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function startsWith($string, $prefix, $ignoreCase = false)
|
||||
{
|
||||
if ($ignoreCase) {
|
||||
$string = strtolower($string);
|
||||
$prefix = strtolower($prefix);
|
||||
}
|
||||
return ($prefix == substr($string, 0, strlen($prefix)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns grouped items from passed $var
|
||||
*
|
||||
* @param array $var item to group
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getArray(array $var)
|
||||
{
|
||||
if (is_null($var) || empty($var)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($var as $value) {
|
||||
if ((gettype($value) == 'object')
|
||||
&& (get_class($value) == 'SimpleXMLElement')
|
||||
) {
|
||||
return (array) $var;
|
||||
} elseif (!is_array($value)) {
|
||||
return array($var);
|
||||
}
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes the passed $xml into array.
|
||||
*
|
||||
* @param string $xml XML to be parsed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function unserialize($xml)
|
||||
{
|
||||
$sxml = new \SimpleXMLElement($xml);
|
||||
|
||||
return self::_sxml2arr($sxml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a SimpleXML object to an Array recursively
|
||||
* ensuring all sub-elements are arrays as well.
|
||||
*
|
||||
* @param string $sxml SimpleXML object
|
||||
* @param array $arr Array into which to store results
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function _sxml2arr($sxml, array $arr = null)
|
||||
{
|
||||
foreach ((array) $sxml as $key => $value) {
|
||||
if (is_object($value) || (is_array($value))) {
|
||||
$arr[$key] = self::_sxml2arr($value);
|
||||
} else {
|
||||
$arr[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes given array into xml. The array indices must be string to use
|
||||
* them as XML tags.
|
||||
*
|
||||
* @param array $array object to serialize represented in array.
|
||||
* @param string $rootName name of the XML root element.
|
||||
* @param string $defaultTag default tag for non-tagged elements.
|
||||
* @param string $standalone adds 'standalone' header tag, values 'yes'/'no'
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function serialize(
|
||||
array $array,
|
||||
$rootName,
|
||||
$defaultTag = null,
|
||||
$standalone = null
|
||||
) {
|
||||
$xmlVersion = '1.0';
|
||||
$xmlEncoding = 'UTF-8';
|
||||
|
||||
if (!is_array($array)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$xmlw = new \XmlWriter();
|
||||
$xmlw->openMemory();
|
||||
$xmlw->startDocument($xmlVersion, $xmlEncoding, $standalone);
|
||||
|
||||
$xmlw->startElement($rootName);
|
||||
|
||||
self::_arr2xml($xmlw, $array, $defaultTag);
|
||||
|
||||
$xmlw->endElement();
|
||||
|
||||
return $xmlw->outputMemory(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an array and produces XML based on it.
|
||||
*
|
||||
* @param XMLWriter $xmlw XMLWriter object that was previously instanted
|
||||
* and is used for creating the XML.
|
||||
* @param array $data Array to be converted to XML
|
||||
* @param string $defaultTag Default XML tag to be used if none specified.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function _arr2xml(
|
||||
\XMLWriter $xmlw,
|
||||
array $data,
|
||||
$defaultTag = null
|
||||
) {
|
||||
foreach ($data as $key => $value) {
|
||||
if (strcmp($key, '@attributes') == 0) {
|
||||
foreach ($value as $attributeName => $attributeValue) {
|
||||
$xmlw->writeAttribute($attributeName, $attributeValue);
|
||||
}
|
||||
} elseif (is_array($value)) {
|
||||
if (!is_int($key)) {
|
||||
if ($key != Resources::EMPTY_STRING) {
|
||||
$xmlw->startElement($key);
|
||||
} else {
|
||||
$xmlw->startElement($defaultTag);
|
||||
}
|
||||
}
|
||||
|
||||
self::_arr2xml($xmlw, $value);
|
||||
|
||||
if (!is_int($key)) {
|
||||
$xmlw->endElement();
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
$xmlw->writeElement($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string into boolean value.
|
||||
*
|
||||
* @param string $obj boolean value in string format.
|
||||
* @param bool $skipNull If $skipNull is set, will return NULL directly
|
||||
* when $obj is NULL.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function toBoolean($obj, $skipNull = false)
|
||||
{
|
||||
if ($skipNull && is_null($obj)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return filter_var($obj, FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string into boolean value.
|
||||
*
|
||||
* @param bool $obj boolean value to convert.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function booleanToString($obj)
|
||||
{
|
||||
return $obj ? 'true' : 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given date string into \DateTime object
|
||||
*
|
||||
* @param string $date windows azure date ins string representation.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public static function rfc1123ToDateTime($date)
|
||||
{
|
||||
$timeZone = new \DateTimeZone('GMT');
|
||||
$format = Resources::AZURE_DATE_FORMAT;
|
||||
|
||||
return \DateTime::createFromFormat($format, $date, $timeZone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate ISO 8601 compliant date string in UTC time zone
|
||||
*
|
||||
* @param \DateTimeInterface $date The date value to convert
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function isoDate(\DateTimeInterface $date)
|
||||
{
|
||||
$date = clone $date;
|
||||
$date = $date->setTimezone(new \DateTimeZone('UTC'));
|
||||
|
||||
return str_replace('+00:00', 'Z', $date->format('c'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DateTime object into an Edm.DaeTime value in UTC timezone,
|
||||
* represented as a string.
|
||||
*
|
||||
* @param mixed $value The datetime value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function convertToEdmDateTime($value)
|
||||
{
|
||||
if (empty($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
$value = self::convertToDateTime($value);
|
||||
}
|
||||
|
||||
Validate::isDate($value);
|
||||
|
||||
$cloned = clone $value;
|
||||
$cloned->setTimezone(new \DateTimeZone('UTC'));
|
||||
return str_replace('+00:00', 'Z', $cloned->format("Y-m-d\TH:i:s.u0P"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to a \DateTime object. Returns false on failure.
|
||||
*
|
||||
* @param string $value The string value to parse.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public static function convertToDateTime($value)
|
||||
{
|
||||
if ($value instanceof \DateTime) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (substr($value, -1) == 'Z') {
|
||||
$value = substr($value, 0, strlen($value) - 1);
|
||||
}
|
||||
|
||||
return new \DateTime($value, new \DateTimeZone('UTC'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string to stream handle.
|
||||
*
|
||||
* @param string $string The string contents.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public static function stringToStream($string)
|
||||
{
|
||||
return fopen('data://text/plain,' . urlencode($string), 'rb');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array based on given keys order.
|
||||
*
|
||||
* @param array $array The array to sort.
|
||||
* @param array $order The keys order array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function orderArray(array $array, array $order)
|
||||
{
|
||||
$ordered = array();
|
||||
|
||||
foreach ($order as $key) {
|
||||
if (array_key_exists($key, $array)) {
|
||||
$ordered[$key] = $array[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $ordered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a value exists in an array. The comparison is done in a case
|
||||
* insensitive manner.
|
||||
*
|
||||
* @param string $needle The searched value.
|
||||
* @param array $haystack The array.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function inArrayInsensitive($needle, array $haystack)
|
||||
{
|
||||
return in_array(strtolower($needle), array_map('strtolower', $haystack));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given key exists in the array. The comparison is done in a case
|
||||
* insensitive manner.
|
||||
*
|
||||
* @param string $key The value to check.
|
||||
* @param array $search The array with keys to check.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function arrayKeyExistsInsensitive($key, array $search)
|
||||
{
|
||||
return array_key_exists(strtolower($key), array_change_key_case($search));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified value of the $key passed from $array and in case that
|
||||
* this $key doesn't exist, the default value is returned. The key matching is
|
||||
* done in a case insensitive manner.
|
||||
*
|
||||
* @param string $key The array key.
|
||||
* @param array $haystack The array to be used.
|
||||
* @param mixed $default The value to return if $key is not found in $array.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function tryGetValueInsensitive($key, $haystack, $default = null)
|
||||
{
|
||||
$array = array_change_key_case($haystack);
|
||||
return Utilities::tryGetValue($array, strtolower($key), $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of a version 4 GUID, which uses random
|
||||
* numbers.There are 6 reserved bits, and the GUIDs have this format:
|
||||
* xxxxxxxx-xxxx-4xxx-[8|9|a|b]xxx-xxxxxxxxxxxx
|
||||
* where 'x' is a hexadecimal digit, 0-9a-f.
|
||||
*
|
||||
* See http://tools.ietf.org/html/rfc4122 for more information.
|
||||
*
|
||||
* Note: This function is available on all platforms, while the
|
||||
* com_create_guid() is only available for Windows.
|
||||
*
|
||||
* @return string A new GUID.
|
||||
*/
|
||||
public static function getGuid()
|
||||
{
|
||||
// @codingStandardsIgnoreStart
|
||||
|
||||
return sprintf(
|
||||
'%04x%04x-%04x-%04x-%02x%02x-%04x%04x%04x',
|
||||
mt_rand(0, 65535),
|
||||
mt_rand(0, 65535), // 32 bits for "time_low"
|
||||
mt_rand(0, 65535), // 16 bits for "time_mid"
|
||||
mt_rand(0, 4096) + 16384, // 16 bits for "time_hi_and_version", with
|
||||
// the most significant 4 bits being 0100
|
||||
// to indicate randomly generated version
|
||||
mt_rand(0, 64) + 128, // 8 bits for "clock_seq_hi", with
|
||||
// the most significant 2 bits being 10,
|
||||
// required by version 4 GUIDs.
|
||||
mt_rand(0, 255), // 8 bits for "clock_seq_low"
|
||||
mt_rand(0, 65535), // 16 bits for "node 0" and "node 1"
|
||||
mt_rand(0, 65535), // 16 bits for "node 2" and "node 3"
|
||||
mt_rand(0, 65535) // 16 bits for "node 4" and "node 5"
|
||||
);
|
||||
|
||||
// @codingStandardsIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of objects of type $class from the provided array using static
|
||||
* create method.
|
||||
*
|
||||
* @param array $parsed The object in array representation
|
||||
* @param string $class The class name. Must have static method create.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function createInstanceList(array $parsed, $class)
|
||||
{
|
||||
$list = array();
|
||||
|
||||
foreach ($parsed as $value) {
|
||||
$list[] = $class::create($value);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a string and return if it ends with the specified character/string.
|
||||
*
|
||||
* @param string $haystack The string to search in.
|
||||
* @param string $needle postfix to match.
|
||||
* @param boolean $ignoreCase Set true to ignore case during the comparison;
|
||||
* otherwise, false
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function endsWith($haystack, $needle, $ignoreCase = false)
|
||||
{
|
||||
if ($ignoreCase) {
|
||||
$haystack = strtolower($haystack);
|
||||
$needle = strtolower($needle);
|
||||
}
|
||||
$length = strlen($needle);
|
||||
if ($length == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (substr($haystack, -$length) === $needle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id from entity object or string.
|
||||
* If entity is object than validate type and return $entity->$method()
|
||||
* If entity is string than return this string
|
||||
*
|
||||
* @param object|string $entity Entity with id property
|
||||
* @param string $type Entity type to validate
|
||||
* @param string $method Methods that gets id (getId by default)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getEntityId($entity, $type, $method = 'getId')
|
||||
{
|
||||
if (is_string($entity)) {
|
||||
return $entity;
|
||||
} else {
|
||||
Validate::isA($entity, $type, 'entity');
|
||||
Validate::methodExists($entity, $method, $type);
|
||||
|
||||
return $entity->$method();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a pseudo-random string of bytes using a cryptographically strong
|
||||
* algorithm.
|
||||
*
|
||||
* @param int $length Length of the string in bytes
|
||||
*
|
||||
* @return string|boolean Generated string of bytes on success, or FALSE on
|
||||
* failure.
|
||||
*/
|
||||
public static function generateCryptoKey($length)
|
||||
{
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert base 256 number to decimal number.
|
||||
*
|
||||
* @param string $number Base 256 number
|
||||
*
|
||||
* @return string Decimal number
|
||||
*/
|
||||
public static function base256ToDec($number)
|
||||
{
|
||||
Validate::canCastAsString($number, 'number');
|
||||
|
||||
$result = 0;
|
||||
$base = 1;
|
||||
for ($i = strlen($number) - 1; $i >= 0; $i--) {
|
||||
$result = bcadd($result, bcmul(ord($number[$i]), $base));
|
||||
$base = bcmul($base, 256);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* To evaluate if the stream is larger than a certain size. To restore
|
||||
* the stream, it has to be seekable, so will return true if the stream
|
||||
* is not seekable.
|
||||
* @param StreamInterface $stream The stream to be evaluated.
|
||||
* @param int $size The size if the string is larger than.
|
||||
*
|
||||
* @return boolean true if the stream is larger than the given size.
|
||||
*/
|
||||
public static function isStreamLargerThanSizeOrNotSeekable(StreamInterface $stream, $size)
|
||||
{
|
||||
Validate::isInteger($size, 'size');
|
||||
Validate::isTrue(
|
||||
$stream instanceof StreamInterface,
|
||||
sprintf(Resources::INVALID_PARAM_MSG, 'stream', 'Psr\Http\Message\StreamInterface')
|
||||
);
|
||||
$result = true;
|
||||
if ($stream->isSeekable()) {
|
||||
$position = $stream->tell();
|
||||
try {
|
||||
$stream->seek($size);
|
||||
} catch (\RuntimeException $e) {
|
||||
$pos = strpos(
|
||||
$e->getMessage(),
|
||||
'to seek to stream position '
|
||||
);
|
||||
if ($pos == null) {
|
||||
throw $e;
|
||||
}
|
||||
$result = false;
|
||||
}
|
||||
if ($stream->eof()) {
|
||||
$result = false;
|
||||
} elseif ($stream->read(1) == '') {
|
||||
$result = false;
|
||||
}
|
||||
$stream->seek($position);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets metadata array by parsing them from given headers.
|
||||
*
|
||||
* @param array $headers HTTP headers containing metadata elements.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getMetadataArray(array $headers)
|
||||
{
|
||||
$metadata = array();
|
||||
foreach ($headers as $key => $value) {
|
||||
$isMetadataHeader = Utilities::startsWith(
|
||||
strtolower($key),
|
||||
Resources::X_MS_META_HEADER_PREFIX
|
||||
);
|
||||
|
||||
if ($isMetadataHeader) {
|
||||
// Metadata name is case-presrved and case insensitive
|
||||
$MetadataName = str_ireplace(
|
||||
Resources::X_MS_META_HEADER_PREFIX,
|
||||
Resources::EMPTY_STRING,
|
||||
$key
|
||||
);
|
||||
$metadata[$MetadataName] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the provided metadata array.
|
||||
*
|
||||
* @param array $metadata The metadata array.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function validateMetadata(array $metadata = null)
|
||||
{
|
||||
if (!is_null($metadata)) {
|
||||
Validate::isArray($metadata, 'metadata');
|
||||
} else {
|
||||
$metadata = array();
|
||||
}
|
||||
|
||||
foreach ($metadata as $key => $value) {
|
||||
Validate::canCastAsString($key, 'metadata key');
|
||||
Validate::canCastAsString($value, 'metadata value');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the content to file.
|
||||
* @param string $path The file to append to.
|
||||
* @param string $content The content to append.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function appendToFile($path, $content)
|
||||
{
|
||||
$resource = @fopen($path, 'a+');
|
||||
if ($resource != null) {
|
||||
fwrite($resource, $content);
|
||||
fclose($resource);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all the bytes are zero.
|
||||
*
|
||||
* @param string $content The content.
|
||||
* @return bool
|
||||
*/
|
||||
public static function allZero($content)
|
||||
{
|
||||
$size = strlen($content);
|
||||
|
||||
// If all Zero, skip this range
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
if (ord($content[$i]) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the delimiter to the string. The delimiter will not be added if
|
||||
* the string already ends with this delimiter.
|
||||
*
|
||||
* @param string $string The string to add delimiter to.
|
||||
* @param string $delimiter The delimiter to be added.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function appendDelimiter($string, $delimiter)
|
||||
{
|
||||
if (!self::endsWith($string, $delimiter)) {
|
||||
$string .= $delimiter;
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static function used to determine if the request is performed against
|
||||
* secondary endpoint.
|
||||
*
|
||||
* @param Psr\Http\Message\RequestInterface $request The request performed.
|
||||
* @param array $options The options of the
|
||||
* request. Must contain
|
||||
* Resources::ROS_SECONDARY_URI
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function requestSentToSecondary(
|
||||
\Psr\Http\Message\RequestInterface $request,
|
||||
array $options
|
||||
) {
|
||||
$uri = $request->getUri();
|
||||
$secondaryUri = $options[Resources::ROS_SECONDARY_URI];
|
||||
$isSecondary = false;
|
||||
if (strpos((string)$uri, (string)$secondaryUri) !== false) {
|
||||
$isSecondary = true;
|
||||
}
|
||||
return $isSecondary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location value from the headers.
|
||||
*
|
||||
* @param array $headers request/response headers.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getLocationFromHeaders(array $headers)
|
||||
{
|
||||
$value = Utilities::tryGetValue(
|
||||
$headers,
|
||||
Resources::X_MS_CONTINUATION_LOCATION_MODE
|
||||
);
|
||||
|
||||
$result = '';
|
||||
if (\is_string($value)) {
|
||||
$result = $value;
|
||||
} elseif (!empty($value)) {
|
||||
$result = $value[0];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the value is a double value or string representation of a double
|
||||
* value
|
||||
*
|
||||
* @param mixed $value The value to be verified.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isDouble($value)
|
||||
{
|
||||
return is_numeric($value) && is_double($value + 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the content MD5 which is base64 encoded. This should be align
|
||||
* with the server calculated MD5.
|
||||
*
|
||||
* @param string $content the content to be calculated.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function calculateContentMD5($content)
|
||||
{
|
||||
Validate::notNull($content, 'content');
|
||||
Validate::canCastAsString($content, 'content');
|
||||
|
||||
return base64_encode(md5($content, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the environment is in 64 bit PHP.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is64BitPHP()
|
||||
{
|
||||
return PHP_INT_SIZE == 8;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user