Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php namespace Swoole\Memory; use Swoole\Exception\InvalidParam; /** * CstructCC pack(..
Decoded Output download
<?php
namespace Swoole\Memory;
use Swoole\Exception\InvalidParam;
/**
* CstructCC pack(1)
* [@fieldtype $type]opcache
*
* int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, long, ulong
* float, double
* char[n], uchar[n]
* @package Swoole\Memory
* @author Tianfeng.Han (Rango)
*/
abstract class Struct
{
protected $size = 0;
protected $fileds = array();
protected $is32bit;
protected $class;
/**
*
*/
protected $assoc;
/**
*
*/
protected $convertBigEndian;
const REGX_FIELDTYPE = '#@fieldtype\s+([a-z0-9]+(\[[a-z0-9_\\]+\])?)\s+#i';
const REGX_FILEINFO = '#\[([a-z0-9_\\]+)\]#i';
/**
* @param bool $convertBigEndian
* @param bool $assoc
* @throws InvalidParam
*/
function __construct($convertBigEndian = true, $assoc = false)
{
$this->is32bit = (PHP_INT_SIZE === 4);
$this->convertBigEndian = $convertBigEndian;
$this->class = get_class($this);
$this->assoc = $assoc;
$rClass = new \ReflectionClass($this->class);
$props = $rClass->getProperties(\ReflectionProperty::IS_PUBLIC);
foreach ($props as $p)
{
if (preg_match(self::REGX_FIELDTYPE, $p->getDocComment(), $match))
{
$field = $this->parseFieldType($match[1]);
$field->name = $p->getName();
if ($this->assoc)
{
$this->fileds[$field->name] = $field;
}
else
{
$this->fileds[] = $field;
}
$this->size += $field->size;
}
}
}
/**
* @return int
*/
function size()
{
return $this->size;
}
/**
* @param $fieldType
* @return Field
* @throws InvalidParam
*/
protected function parseFieldType($fieldType)
{
$signed = false;
$struct = null;
start_switch:
switch (strtolower($fieldType[0]))
{
case 'u':
$signed = true;
$fieldType = substr($fieldType, 1);
goto start_switch;
case 'i':
if ($fieldType == 'int')
{
$size = 4;
}
else
{
$size = substr($fieldType, 3) / 8;
}
$type = Field::INT;
break;
case 'l':
$size = $this->is32bit ? 4 : 8;
$type = Field::INT;
break;
case 'f':
$size = 4;
$type = Field::FLOAT;
break;
case 'd':
$size = $this->is32bit ? 4 : 8;
$type = Field::FLOAT;
break;
case 'c':
$size = intval(substr($fieldType, 5));
$type = Field::CHAR;
break;
/**
*
*/
case 's':
if (preg_match(self::REGX_FILEINFO, $fieldType, $match))
{
$class = '\'.$match[1];
/**
* @var $struct Struct
*/
$struct = new $class($this->convertBigEndian, $this->assoc);
$type = Field::STRUCT;
$size = $struct->size();
}
else
{
throw new InvalidParam("require struct class name.");
}
break;
default:
throw new InvalidParam("invalid field type [{$fieldType[0]}].");
}
$field = new Field();
$field->size = $size;
$field->signed = $signed;
$field->type = $type;
$field->struct = $struct;
$field->fieldType = $fieldType;
return $field;
}
/**
*
* @param array $data
* @return string
* @throws InvalidParam
*/
function pack(array $data)
{
if (count($data) != count($this->fileds))
{
throw new InvalidParam("{$this->class}: invalid data.");
}
$_binStr = '';
foreach ($this->fileds as $k => $field)
{
if (!isset($data[$k]))
{
throw new InvalidParam("{$this->class}: item[key=$k] is not exists.");
}
/**
* @var $field Field
*/
switch ($field->type)
{
case Field::INT:
$value = intval($data[$k]);
switch ($field->size)
{
case 1:
$_binStr .= pack($field->signed ? 'c' : 'C', $value);
break;
case 2:
if ($this->convertBigEndian)
{
//
$_binStr .= pack('n', $value);
}
else
{
$_binStr .= pack($field->signed ? 's' : 'S', $value);
}
break;
case 4:
if ($this->convertBigEndian)
{
//
$_binStr .= pack('N', $value);
}
else
{
$_binStr .= pack($field->signed ? 'l' : 'L', $value);
}
break;
case 8:
if ($this->convertBigEndian)
{
//
$_binStr .= pack('J', $value);
}
else
{
$_binStr .= pack($field->signed ? 'q' : 'Q', $value);
}
break;
default:
break;
}
break;
case Field::FLOAT:
$value = floatval($data[$k]);
$_binStr .= pack($field->size == 4 ? 'f' : 'd', $value);
break;
case Field::CHAR:
$value = strval($data[$k]);
//C(size-1)
if (strlen($value) > $field->size - 1)
{
throw new InvalidParam("string is too long.");
}
$_binStr .= pack('a' . ($field->size - 1) . 'x', $value);
break;
/**
*
*/
case Field::STRUCT:
//
if (!is_array($data[$k]) or count($data[$k]) != count($field->struct->fileds))
{
throw new InvalidParam("struct size invalid.");
}
$_binStr .= $field->struct->pack($data[$k]);
break;
default:
break;
}
}
return $_binStr;
}
/**
*
* @param $str
* @return array
*/
function unpack($str)
{
$data = array();
foreach ($this->fileds as $k => $field)
{
/**
* @var $field Field
*/
switch ($field->type)
{
case Field::INT:
switch ($field->size)
{
case 1:
list(, $data[$k]) = unpack($field->signed ? 'c' : 'C', $str);
break;
case 2:
if ($this->convertBigEndian)
{
//
list(, $data[$k]) = unpack('n', $str);
}
else
{
list(, $data[$k]) = unpack($field->signed ? 's' : 'S', $str);
}
break;
case 4:
if ($this->convertBigEndian)
{
//
list(, $data[$k]) = unpack('N', $str);
}
else
{
list(, $data[$k]) = unpack($field->signed ? 'l' : 'L', $str);
}
break;
case 8:
if ($this->convertBigEndian)
{
//
list(, $data[$k]) = unpack('J', $str);
}
else
{
list(, $data[$k]) = unpack($field->signed ? 'q' : 'Q', $str);
}
break;
default:
break;
}
break;
case Field::FLOAT:
list(, $data[$k]) = unpack($field->size == 4 ? 'f' : 'd', $str);
break;
case Field::CHAR:
$data[$k] = substr($str, 0, strpos($str, ""));
break;
case Field::STRUCT:
$data[$k] = $field->struct->unpack($str);
break;
default:
break;
}
$str = substr($str, $field->size);
}
return $data;
}
}
class Field
{
public $name;
public $type;
public $size;
public $signed;
public $fieldType;
/**
* @var Struct
*/
public $struct;
const INT = 1;
const FLOAT = 2;
const CHAR = 3;
const STRUCT = 4;
} ?>
Did this file decode correctly?
Original Code
<?php
namespace Swoole\Memory;
use Swoole\Exception\InvalidParam;
/**
* CstructCC pack(1)
* [@fieldtype $type]opcache
*
* int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, long, ulong
* float, double
* char[n], uchar[n]
* @package Swoole\Memory
* @author Tianfeng.Han (Rango)
*/
abstract class Struct
{
protected $size = 0;
protected $fileds = array();
protected $is32bit;
protected $class;
/**
*
*/
protected $assoc;
/**
*
*/
protected $convertBigEndian;
const REGX_FIELDTYPE = '#@fieldtype\s+([a-z0-9]+(\[[a-z0-9_\\\]+\])?)\s+#i';
const REGX_FILEINFO = '#\[([a-z0-9_\\\]+)\]#i';
/**
* @param bool $convertBigEndian
* @param bool $assoc
* @throws InvalidParam
*/
function __construct($convertBigEndian = true, $assoc = false)
{
$this->is32bit = (PHP_INT_SIZE === 4);
$this->convertBigEndian = $convertBigEndian;
$this->class = get_class($this);
$this->assoc = $assoc;
$rClass = new \ReflectionClass($this->class);
$props = $rClass->getProperties(\ReflectionProperty::IS_PUBLIC);
foreach ($props as $p)
{
if (preg_match(self::REGX_FIELDTYPE, $p->getDocComment(), $match))
{
$field = $this->parseFieldType($match[1]);
$field->name = $p->getName();
if ($this->assoc)
{
$this->fileds[$field->name] = $field;
}
else
{
$this->fileds[] = $field;
}
$this->size += $field->size;
}
}
}
/**
* @return int
*/
function size()
{
return $this->size;
}
/**
* @param $fieldType
* @return Field
* @throws InvalidParam
*/
protected function parseFieldType($fieldType)
{
$signed = false;
$struct = null;
start_switch:
switch (strtolower($fieldType[0]))
{
case 'u':
$signed = true;
$fieldType = substr($fieldType, 1);
goto start_switch;
case 'i':
if ($fieldType == 'int')
{
$size = 4;
}
else
{
$size = substr($fieldType, 3) / 8;
}
$type = Field::INT;
break;
case 'l':
$size = $this->is32bit ? 4 : 8;
$type = Field::INT;
break;
case 'f':
$size = 4;
$type = Field::FLOAT;
break;
case 'd':
$size = $this->is32bit ? 4 : 8;
$type = Field::FLOAT;
break;
case 'c':
$size = intval(substr($fieldType, 5));
$type = Field::CHAR;
break;
/**
*
*/
case 's':
if (preg_match(self::REGX_FILEINFO, $fieldType, $match))
{
$class = '\\'.$match[1];
/**
* @var $struct Struct
*/
$struct = new $class($this->convertBigEndian, $this->assoc);
$type = Field::STRUCT;
$size = $struct->size();
}
else
{
throw new InvalidParam("require struct class name.");
}
break;
default:
throw new InvalidParam("invalid field type [{$fieldType[0]}].");
}
$field = new Field();
$field->size = $size;
$field->signed = $signed;
$field->type = $type;
$field->struct = $struct;
$field->fieldType = $fieldType;
return $field;
}
/**
*
* @param array $data
* @return string
* @throws InvalidParam
*/
function pack(array $data)
{
if (count($data) != count($this->fileds))
{
throw new InvalidParam("{$this->class}: invalid data.");
}
$_binStr = '';
foreach ($this->fileds as $k => $field)
{
if (!isset($data[$k]))
{
throw new InvalidParam("{$this->class}: item[key=$k] is not exists.");
}
/**
* @var $field Field
*/
switch ($field->type)
{
case Field::INT:
$value = intval($data[$k]);
switch ($field->size)
{
case 1:
$_binStr .= pack($field->signed ? 'c' : 'C', $value);
break;
case 2:
if ($this->convertBigEndian)
{
//
$_binStr .= pack('n', $value);
}
else
{
$_binStr .= pack($field->signed ? 's' : 'S', $value);
}
break;
case 4:
if ($this->convertBigEndian)
{
//
$_binStr .= pack('N', $value);
}
else
{
$_binStr .= pack($field->signed ? 'l' : 'L', $value);
}
break;
case 8:
if ($this->convertBigEndian)
{
//
$_binStr .= pack('J', $value);
}
else
{
$_binStr .= pack($field->signed ? 'q' : 'Q', $value);
}
break;
default:
break;
}
break;
case Field::FLOAT:
$value = floatval($data[$k]);
$_binStr .= pack($field->size == 4 ? 'f' : 'd', $value);
break;
case Field::CHAR:
$value = strval($data[$k]);
//C\0(size-1)
if (strlen($value) > $field->size - 1)
{
throw new InvalidParam("string is too long.");
}
$_binStr .= pack('a' . ($field->size - 1) . 'x', $value);
break;
/**
*
*/
case Field::STRUCT:
//
if (!is_array($data[$k]) or count($data[$k]) != count($field->struct->fileds))
{
throw new InvalidParam("struct size invalid.");
}
$_binStr .= $field->struct->pack($data[$k]);
break;
default:
break;
}
}
return $_binStr;
}
/**
*
* @param $str
* @return array
*/
function unpack($str)
{
$data = array();
foreach ($this->fileds as $k => $field)
{
/**
* @var $field Field
*/
switch ($field->type)
{
case Field::INT:
switch ($field->size)
{
case 1:
list(, $data[$k]) = unpack($field->signed ? 'c' : 'C', $str);
break;
case 2:
if ($this->convertBigEndian)
{
//
list(, $data[$k]) = unpack('n', $str);
}
else
{
list(, $data[$k]) = unpack($field->signed ? 's' : 'S', $str);
}
break;
case 4:
if ($this->convertBigEndian)
{
//
list(, $data[$k]) = unpack('N', $str);
}
else
{
list(, $data[$k]) = unpack($field->signed ? 'l' : 'L', $str);
}
break;
case 8:
if ($this->convertBigEndian)
{
//
list(, $data[$k]) = unpack('J', $str);
}
else
{
list(, $data[$k]) = unpack($field->signed ? 'q' : 'Q', $str);
}
break;
default:
break;
}
break;
case Field::FLOAT:
list(, $data[$k]) = unpack($field->size == 4 ? 'f' : 'd', $str);
break;
case Field::CHAR:
$data[$k] = substr($str, 0, strpos($str, "\0"));
break;
case Field::STRUCT:
$data[$k] = $field->struct->unpack($str);
break;
default:
break;
}
$str = substr($str, $field->size);
}
return $data;
}
}
class Field
{
public $name;
public $type;
public $size;
public $signed;
public $fieldType;
/**
* @var Struct
*/
public $struct;
const INT = 1;
const FLOAT = 2;
const CHAR = 3;
const STRUCT = 4;
}
Function Calls
None |
Stats
MD5 | 8510fcfb54e8cca354f822c0563be143 |
Eval Count | 0 |
Decode Time | 103 ms |