public static function readMetadata($value, $types = false)
{
$offset = 0;
$m = [];
$b = ord($value[$offset]);
++$offset;
while ($b !== 127 and isset($value[$offset])) {
$bottom = $b & 0x1f;
$type = $b >> 5;
switch ($type) {
case Entity::DATA_TYPE_BYTE:
$r = self::readByte($value[$offset]);
++$offset;
break;
case Entity::DATA_TYPE_SHORT:
$r = self::readLShort(substr($value, $offset, 2));
$offset += 2;
break;
case Entity::DATA_TYPE_INT:
$r = self::readLInt(substr($value, $offset, 4));
$offset += 4;
break;
case Entity::DATA_TYPE_FLOAT:
$r = self::readLFloat(substr($value, $offset, 4));
$offset += 4;
break;
case Entity::DATA_TYPE_STRING:
$len = self::readLShort(substr($value, $offset, 2));
$offset += 2;
$r = substr($value, $offset, $len);
$offset += $len;
break;
case Entity::DATA_TYPE_SLOT:
$r = [];
$r[] = self::readLShort(substr($value, $offset, 2));
$offset += 2;
$r[] = ord($value[$offset]);
++$offset;
$r[] = self::readLShort(substr($value, $offset, 2));
$offset += 2;
break;
case Entity::DATA_TYPE_POS:
$r = [];
for ($i = 0; $i < 3; ++$i) {
$r[] = self::readLInt(substr($value, $offset, 4));
$offset += 4;
}
break;
case Entity::DATA_TYPE_LONG:
$r = self::readLLong(substr($value, $offset, 4));
$offset += 8;
break;
default:
return [];
}
if ($types === true) {
$m[$bottom] = [$r, $type];
} else {
$m[$bottom] = $r;
}
$b = ord($value[$offset]);
++$offset;
}
return $m;
}