@ 2013-07-31T17:55:55Z <?php
class ContentTypeBuilder
{
private $contentTypeFactory;
private $CTLs = [
"\x00" => 1, "\x01" => 1, "\x02" => 1, "\x03" => 1, "\x04" => 1, "\x05" => 1, "\x06" => 1, "\x07" => 1,
"\x08" => 1, /* "\x09" */ /* "\x0A" */ "\x0B" => 1, "\x0C" => 1, /* "\x0D" */ "\x0E" => 1, "\x0F" => 1,
"\x10" => 1, "\x11" => 1, "\x12" => 1, "\x13" => 1, "\x14" => 1, "\x15" => 1, "\x16" => 1, "\x17" => 1,
"\x18" => 1, "\x19" => 1, "\x1A" => 1, "\x1B" => 1, "\x1C" => 1, "\x1D" => 1, "\x1E" => 1, "\x1F" => 1,
"\x7F" => 1,
];
private $LWS = [
"\x09" => 1, "\x0A" => 1, "\x0D" => 1, "\x20" => 1,
];
private $separators = [
"\x28" => '(', "\x29" => ')', "\x3C" => '<', "\x3E" => '>', "\x40" => '@', "\x2C" => ',', "\x3A" => ':',
"\x5C" => '\\', "\x22" => '"', "\x5B" => '[', "\x5D" => ']', "\x3F" => '?', "\x7B" => '{', "\x7D" => '}',
];
public function __construct(ContentTypeFactory $contentTypeFactory)
{
$this->contentTypeFactory = $contentTypeFactory;
}
public function build($typeDef, &$qValue = null)
{
/* Note:
*
* This routine favours speed and efficiency over readability and DRY. Deal with it.
*
* All chars are written as hex literals, to avoid any breakage if some idiot changes the
* encoding of this source file to something that doesn't use ASCII code points for the
* lower 128. AFAIK the PHP interpreter doesn't yet support this, but this code is a
* literal implementation of a concrete spec and doesn't need to be maintainable in the
* traditional sense, so I don't want to have to come back here to maintain it.
*/
$typeDefBytes = (string) $typeDef;
$totalLength = strlen($typeDefBytes);
$bytePos = 0;
// Skip leading LWS
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
$type = "\x00";
for (; $bytePos < $totalLength; $bytePos++) {
if (
isset($this->CTLs[$typeDefBytes[$bytePos]]) // CTL
|| isset($this->LWS[$typeDefBytes[$bytePos]]) // LWS
|| isset($this->separators[$typeDefBytes[$bytePos]]) // separator
|| ($typeDefBytes[$bytePos] & "\x80") === "\x80" // >127
|| $typeDefBytes[$bytePos] === "\x3B" // ;
|| $typeDefBytes[$bytePos] === "\x3D" // =
) {
trigger_error(
'Syntax error in Accept header value:'
. ' invalid token character ' . $typeDefBytes[$bytePos]
. ' (0x' . sprintf('%02X', ord($typeDefBytes[$bytePos])) . ')'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null;
} else if ($typeDefBytes[$bytePos] === "\x2F") { // /
$bytePos++;
break;
} else {
$type[$bytePos] = $typeDefBytes[$bytePos];
}
}
$subType = "\x00";
for ($valuePos = 0; $bytePos < $totalLength; $bytePos++) {
if (
isset($this->CTLs[$typeDefBytes[$bytePos]]) // CTL
|| isset($this->separators[$typeDefBytes[$bytePos]]) // separator
|| ($typeDefBytes[$bytePos] & "\x80") === "\x80" // >127
|| $typeDefBytes[$bytePos] === "\x2F" // /
|| $typeDefBytes[$bytePos] === "\x3D" // =
) { // invalid char for token
trigger_error(
'Syntax error in Accept header value:'
. ' invalid token character ' . $typeDefBytes[$bytePos]
. ' (0x' . sprintf('%02X', ord($typeDefBytes[$bytePos])) . ')'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null;
} else if (isset($this->LWS[$typeDefBytes[$bytePos]])) { // LWS
$bytePos++;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
if ($typeDefBytes[$bytePos] === "\x3B") $bytePos++; // ;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
break;
} else if ($typeDefBytes[$bytePos] === "\x3B") { // ;
$bytePos++;
while ($bytePos < $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
break;
} else {
$subType[$valuePos++] = $typeDefBytes[$bytePos];
}
}
// */something is not valid
if ($type === "\x2A" && $subType !== "\x2A") { // *
trigger_error(
'Semantic error in Accept header value:'
. ' */' . $subType . ' is not a valid media-type'
, E_USER_NOTICE);
return null;
}
$params = [];
$qValue = 1;
while ($bytePos < $totalLength) {
$name = "\x00";
for ($valuePos = 0; $bytePos < $totalLength; $bytePos++) {
if (
isset($this->CTLs[$typeDefBytes[$bytePos]]) // CTL
|| isset($this->LWS[$typeDefBytes[$bytePos]]) // LWS
|| isset($this->separators[$typeDefBytes[$bytePos]]) // separator
|| ($typeDefBytes[$bytePos] & "\x80") === "\x80" // >127
|| $typeDefBytes[$bytePos] === "\x3B" // ;
|| $typeDefBytes[$bytePos] === "\x2F" // /
) { // invalid char for token
trigger_error(
'Syntax error in Accept header value:'
. ' invalid token character ' . $typeDefBytes[$bytePos]
. ' (0x' . sprintf('%02X', ord($typeDefBytes[$bytePos])) . ')'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null;
} else if ($typeDefBytes[$bytePos] === "\x3D") { // =
$bytePos++;
break;
} else {
$name[$valuePos++] = $typeDefBytes[$bytePos];
}
}
if ($bytePos === $totalLength) {
trigger_error(
'Syntax error in Accept header value:'
. ' media-type parameter ' . $name . ' has no value'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null;
}
if (isset($this->LWS[$typeDefBytes[$bytePos]])) {
trigger_error(
'Syntax error in Accept header value:'
. ' LWS is not legal between a media-type parameter name and its value'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null;
}
if ($typeDefBytes[$bytePos] === "\x22") { // " quoted-string
if ($typeDefBytes[++$bytePos] === "\x22") { // " empty string
$value = '';
$bytePos++;
} else {
$value = "\x00";
for ($valuePos = 0; $bytePos < $totalLength; $bytePos++) {
switch ($typeDefBytes[$bytePos]) {
case "\x0D": case "\x0A": case "\x20": case "\x09": // LWS
while (isset($this->LWS[$typeDefBytes[$bytePos + 1]])) $bytePos++;
$value[$valuePos++] = ' '; // collapse LWS to a single SP
break;
case "\x22": // "
$bytePos++;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
if ($typeDefBytes[$bytePos] === "\x3B") $bytePos++; // ;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
break 2; // end of value
case "\x5C": // \
if (($typeDefBytes[++$bytePos] & "\x80") !== "\x00") {
trigger_error(
'Syntax error in Accept header value:'
. ' invalid quoted single character ' . $typeDefBytes[$bytePos]
. ' (0x' . sprintf('%02X', ord($typeDefBytes[$bytePos])) . ')'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null; // >127 not a valid escape sequence
}
// break; intentionally omitted
default:
$value[$valuePos++] = $typeDefBytes[$bytePos];
}
}
}
} else { // token
$value = "\x00";
for ($valuePos = 0; $bytePos < $totalLength; $bytePos++) {
if (
isset($this->CTLs[$typeDefBytes[$bytePos]]) // CTL
|| isset($this->separators[$typeDefBytes[$bytePos]]) // separator
|| ($typeDefBytes[$bytePos] & "\x80") === "\x80" // >127
|| $typeDefBytes[$bytePos] === "\x2F" // /
|| $typeDefBytes[$bytePos] === "\x3D" // =
) {
trigger_error(
'Syntax error in Accept header value:'
. ' invalid token character ' . $typeDefBytes[$bytePos]
. ' (0x' . sprintf('%02X', ord($typeDefBytes[$bytePos])) . ')'
. ' at offset ' . $bytePos
, E_USER_NOTICE);
return null;
} else if (isset($this->LWS[$typeDefBytes[$bytePos]])) { // LWS
$bytePos++;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
if ($typeDefBytes[$bytePos] === "\x3B") $bytePos++; // ;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
break;
} else if ($typeDefBytes[$bytePos] === "\x3B") { // ;
$bytePos++;
while ($bytePos !== $totalLength && isset($this->LWS[$typeDefBytes[$bytePos]])) $bytePos++;
break;
} else {
$value[$valuePos++] = $typeDefBytes[$bytePos];
}
}
}
if (($name | "\x20") === "\x71") { // q
$qValue = (float) $value;
} else {
$params[strtolower($name)] = $value;
}
}
return $this->contentTypeFactory->create($type, $subType, $params);
}
}
class ContentTypeFactory
{
public function create($type, $subType, array $params = [])
{
return new ContentType($type, $subType, $params);
}
}
class ContentType
{
private $type;
private $subType;
private $params;
public function __construct($type, $subType, array $params = [])
{
$this->type = strtolower($type);
$this->subType = strtolower($subType);
$this->params = $params;
}
public function __toString()
{
$params = [];
foreach ($this->params as $key => $val) {
$params[] = $key . '=' . $val;
}
return $this->getType() . ($params ? ';' . implode(';', $params) : '');
}
public function getFullType()
{
return $this->type . '/' . $this->subType;
}
public function setType($type)
{
$this->type = strtolower($type);
}
public function getType()
{
return $this->type;
}
public function setSubType($subType)
{
$this->subType = strtolower($subType);
}
public function getSubType()
{
return $this->subType;
}
public function setParam($name, $value)
{
if ($value === null) {
unset($this->params[strtolower($name)]);
} else {
$this->params[strtolower($name)] = $value;
}
}
public function getParam($name)
{
return isset($this->params[$name = strtolower($name)]) ? $this->params[$name] : null;
}
public function hasParam($name)
{
return isset($this->params[$name = strtolower($name)]);
}
public function getParams()
{
return $this->params;
}
}
$f = new ContentTypeBuilder(new ContentTypeFactory);
var_dump($f->build('text/html; test= "a test"; things=stuff ; q=0.8'));
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 8.3.6 0.013 0.010 16.85 8.3.5 0.014 0.007 21.95 8.3.4 0.011 0.004 18.95 8.3.3 0.004 0.011 19.34 8.3.2 0.000 0.009 20.45 8.3.1 0.000 0.008 23.52 8.3.0 0.004 0.004 19.51 8.2.18 0.009 0.013 18.16 8.2.17 0.016 0.000 22.96 8.2.16 0.004 0.011 20.51 8.2.15 0.006 0.003 24.18 8.2.14 0.008 0.000 24.66 8.2.13 0.005 0.003 26.16 8.2.12 0.004 0.004 22.25 8.2.11 0.007 0.003 22.23 8.2.10 0.012 0.000 18.03 8.2.9 0.003 0.005 19.32 8.2.8 0.004 0.004 17.97 8.2.7 0.006 0.003 17.88 8.2.6 0.009 0.000 18.05 8.2.5 0.003 0.006 18.07 8.2.4 0.008 0.000 19.93 8.2.3 0.000 0.008 18.41 8.2.2 0.003 0.006 17.97 8.2.1 0.005 0.003 18.27 8.2.0 0.005 0.003 18.00 8.1.28 0.012 0.006 25.92 8.1.27 0.005 0.003 23.96 8.1.26 0.008 0.000 26.35 8.1.25 0.005 0.003 28.09 8.1.24 0.007 0.003 23.92 8.1.23 0.004 0.008 19.09 8.1.22 0.004 0.004 17.93 8.1.21 0.005 0.003 18.77 8.1.20 0.006 0.003 17.48 8.1.19 0.004 0.004 17.48 8.1.18 0.005 0.005 18.10 8.1.17 0.003 0.006 18.67 8.1.16 0.000 0.007 22.18 8.1.15 0.009 0.000 18.81 8.1.14 0.006 0.003 17.62 8.1.13 0.003 0.005 17.99 8.1.12 0.003 0.005 17.61 8.1.11 0.003 0.005 17.54 8.1.10 0.004 0.004 17.67 8.1.9 0.004 0.004 17.50 8.1.8 0.004 0.004 17.65 8.1.7 0.002 0.005 17.54 8.1.6 0.006 0.003 17.75 8.1.5 0.003 0.006 17.71 8.1.4 0.000 0.008 17.67 8.1.3 0.003 0.005 17.66 8.1.2 0.000 0.008 17.82 8.1.1 0.005 0.003 17.73 8.1.0 0.004 0.004 17.68 8.0.30 0.000 0.008 20.65 8.0.29 0.005 0.003 17.13 8.0.28 0.005 0.006 18.62 8.0.27 0.000 0.007 17.39 8.0.26 0.007 0.000 17.51 8.0.25 0.000 0.007 17.16 8.0.24 0.000 0.007 17.13 8.0.23 0.003 0.005 17.23 8.0.22 0.000 0.007 17.15 8.0.21 0.002 0.005 17.00 8.0.20 0.000 0.007 17.08 8.0.19 0.000 0.009 17.02 8.0.18 0.004 0.004 17.04 8.0.17 0.000 0.008 17.05 8.0.16 0.000 0.008 17.24 8.0.15 0.003 0.006 17.03 8.0.14 0.003 0.005 17.10 8.0.13 0.003 0.003 13.58 8.0.12 0.004 0.004 17.10 8.0.11 0.004 0.004 17.14 8.0.10 0.004 0.004 17.14 8.0.9 0.004 0.004 16.91 8.0.8 0.003 0.012 17.14 8.0.7 0.000 0.008 17.17 8.0.6 0.004 0.004 17.08 8.0.5 0.000 0.008 17.24 8.0.3 0.013 0.007 17.37 8.0.2 0.010 0.009 17.40 8.0.1 0.004 0.004 17.02 8.0.0 0.011 0.008 16.83 7.4.33 0.006 0.000 15.15 7.4.32 0.000 0.007 16.86 7.4.30 0.004 0.004 16.82 7.4.29 0.005 0.003 16.70 7.4.28 0.000 0.008 16.66 7.4.27 0.000 0.007 16.66 7.4.26 0.004 0.004 16.80 7.4.25 0.000 0.008 16.63 7.4.24 0.003 0.005 16.73 7.4.23 0.000 0.007 16.86 7.4.22 0.009 0.009 16.63 7.4.21 0.009 0.011 16.69 7.4.20 0.005 0.003 16.78 7.4.19 0.004 0.004 16.86 7.4.16 0.007 0.010 16.82 7.4.15 0.007 0.014 17.40 7.4.14 0.009 0.009 17.86 7.4.13 0.005 0.012 16.74 7.4.12 0.009 0.009 16.78 7.4.11 0.006 0.011 16.58 7.4.10 0.009 0.012 16.62 7.4.9 0.006 0.014 16.65 7.4.8 0.009 0.012 19.39 7.4.7 0.011 0.011 16.69 7.4.6 0.010 0.009 16.60 7.4.5 0.004 0.004 16.80 7.4.4 0.003 0.013 16.63 7.4.3 0.009 0.010 16.69 7.4.0 0.012 0.003 15.40 7.3.33 0.003 0.003 13.45 7.3.32 0.000 0.006 13.60 7.3.31 0.004 0.004 16.48 7.3.30 0.000 0.007 16.60 7.3.29 0.003 0.010 16.59 7.3.28 0.006 0.013 16.61 7.3.27 0.019 0.000 17.40 7.3.26 0.010 0.010 16.61 7.3.25 0.005 0.018 16.70 7.3.24 0.017 0.007 16.66 7.3.23 0.006 0.012 16.80 7.3.21 0.003 0.022 16.69 7.3.20 0.009 0.009 19.39 7.3.19 0.013 0.010 16.75 7.3.18 0.009 0.009 16.79 7.3.17 0.010 0.007 16.65 7.3.16 0.006 0.016 16.53 7.3.12 0.009 0.009 15.17 7.2.33 0.013 0.010 16.96 7.2.32 0.010 0.007 16.82 7.2.31 0.010 0.014 16.75 7.2.30 0.010 0.008 16.76 7.2.29 0.006 0.020 16.97 7.2.6 0.003 0.012 16.98 7.1.20 0.007 0.007 15.90 7.1.10 0.007 0.007 17.78 7.1.7 0.003 0.009 17.34 7.1.6 0.006 0.019 19.46 7.1.5 0.024 0.014 34.93 7.1.0 0.000 0.080 22.41 7.0.20 0.004 0.004 16.78 7.0.14 0.010 0.067 22.11 7.0.10 0.007 0.070 20.03 7.0.9 0.010 0.083 20.01 7.0.8 0.010 0.073 20.07 7.0.7 0.010 0.073 20.07 7.0.6 0.003 0.087 20.02 7.0.5 0.000 0.093 20.41 7.0.4 0.003 0.087 20.10 7.0.3 0.010 0.083 20.04 7.0.2 0.007 0.077 20.08 7.0.1 0.013 0.080 19.95 7.0.0 0.013 0.063 20.09 5.6.28 0.000 0.080 21.21 5.6.25 0.003 0.063 20.75 5.6.24 0.013 0.077 20.75 5.6.23 0.003 0.070 20.76 5.6.22 0.000 0.090 20.52 5.6.21 0.007 0.073 20.65 5.6.20 0.013 0.037 21.17 5.6.19 0.007 0.073 21.06 5.6.18 0.013 0.077 21.07 5.6.17 0.010 0.073 21.16 5.6.16 0.010 0.083 21.14 5.6.15 0.007 0.077 21.14 5.6.14 0.013 0.070 21.07 5.6.13 0.017 0.070 21.07 5.6.12 0.007 0.080 21.07 5.6.11 0.003 0.053 21.02 5.6.10 0.010 0.080 21.18 5.6.9 0.010 0.050 21.03 5.6.8 0.007 0.073 20.52 5.6.7 0.007 0.063 20.34 5.6.6 0.003 0.060 20.48 5.6.5 0.010 0.040 20.58 5.6.4 0.000 0.083 20.46 5.6.3 0.020 0.067 20.48 5.6.2 0.010 0.073 20.40 5.6.1 0.007 0.047 20.40 5.6.0 0.007 0.087 20.32 5.5.38 0.003 0.080 20.46 5.5.37 0.007 0.073 20.48 5.5.36 0.000 0.053 20.44 5.5.35 0.007 0.063 20.46 5.5.34 0.007 0.083 20.94 5.5.33 0.010 0.050 20.91 5.5.32 0.010 0.077 20.91 5.5.31 0.013 0.073 20.67 5.5.30 0.020 0.080 20.91 5.5.29 0.013 0.073 20.86 5.5.28 0.010 0.087 20.96 5.5.27 0.013 0.073 20.73 5.5.26 0.007 0.047 20.78 5.5.25 0.027 0.057 20.45 5.5.24 0.013 0.067 20.22 5.5.23 0.007 0.083 20.01 5.5.22 0.010 0.073 20.27 5.5.21 0.003 0.060 20.15 5.5.20 0.007 0.067 19.98 5.5.19 0.007 0.077 20.30 5.5.18 0.010 0.067 20.21 5.5.16 0.017 0.070 20.02 5.5.15 0.010 0.057 20.18 5.5.14 0.007 0.073 20.14 5.5.13 0.010 0.080 20.30 5.5.12 0.003 0.043 20.17 5.5.11 0.010 0.073 20.25 5.5.10 0.003 0.067 20.08 5.5.9 0.003 0.073 20.10 5.5.8 0.010 0.073 20.14 5.5.7 0.020 0.067 20.09 5.5.6 0.010 0.067 20.07 5.5.5 0.000 0.053 20.09 5.5.4 0.007 0.060 20.10 5.5.3 0.010 0.077 20.16 5.5.2 0.013 0.067 20.03 5.5.1 0.010 0.047 20.17 5.5.0 0.013 0.077 20.14 5.4.45 0.007 0.080 19.37 5.4.44 0.010 0.060 19.41 5.4.43 0.003 0.083 19.28 5.4.42 0.000 0.050 19.38 5.4.41 0.010 0.043 19.33 5.4.40 0.003 0.050 18.87 5.4.39 0.003 0.063 18.90 5.4.38 0.003 0.060 19.07 5.4.37 0.007 0.073 19.10 5.4.36 0.007 0.040 19.23 5.4.35 0.007 0.043 18.90 5.4.34 0.007 0.067 19.06 5.4.32 0.003 0.070 19.17 5.4.31 0.010 0.070 19.23 5.4.30 0.007 0.077 19.13 5.4.29 0.007 0.047 19.13 5.4.28 0.017 0.070 19.23 5.4.27 0.010 0.073 19.13 5.4.26 0.020 0.063 19.09 5.4.25 0.007 0.067 18.98 5.4.24 0.010 0.043 19.09 5.4.23 0.000 0.077 18.87 5.4.22 0.003 0.067 18.90 5.4.21 0.013 0.047 19.05 5.4.20 0.017 0.070 19.13 5.4.19 0.007 0.063 19.04 5.4.18 0.007 0.077 19.17 5.4.17 0.013 0.077 19.05 5.4.16 0.007 0.073 19.07 5.4.15 0.007 0.043 19.20 5.4.14 0.003 0.073 16.46 5.4.13 0.007 0.040 16.50 5.4.12 0.003 0.077 16.46 5.4.11 0.010 0.050 16.34 5.4.10 0.003 0.063 16.54 5.4.9 0.017 0.063 16.45 5.4.8 0.007 0.040 16.51 5.4.7 0.010 0.063 16.50 5.4.6 0.000 0.053 16.55 5.4.5 0.003 0.043 16.52 5.4.4 0.007 0.077 16.43 5.4.3 0.017 0.023 16.50 5.4.2 0.007 0.067 16.36 5.4.1 0.003 0.073 16.46 5.4.0 0.010 0.067 15.91 5.3.29 0.007 0.077 14.69 5.3.28 0.003 0.073 14.62 5.3.27 0.013 0.030 14.66 5.3.26 0.007 0.077 14.66 5.3.25 0.003 0.080 14.71 5.3.24 0.010 0.073 14.58 5.3.23 0.000 0.060 14.58 5.3.22 0.023 0.033 14.64 5.3.21 0.007 0.077 14.58 5.3.20 0.007 0.067 14.66 5.3.19 0.010 0.043 14.63 5.3.18 0.000 0.047 14.50 5.3.17 0.007 0.043 14.59 5.3.16 0.013 0.060 14.54 5.3.15 0.010 0.040 14.63 5.3.14 0.013 0.070 14.49 5.3.13 0.010 0.073 14.50 5.3.12 0.017 0.060 14.50 5.3.11 0.013 0.043 14.62 5.3.10 0.007 0.057 14.17 5.3.9 0.007 0.073 14.04 5.3.8 0.010 0.037 14.08 5.3.7 0.010 0.073 14.11 5.3.6 0.020 0.060 13.92 5.3.5 0.007 0.080 13.86 5.3.4 0.013 0.070 13.96 5.3.3 0.013 0.033 13.93 5.3.2 0.010 0.047 13.68 5.3.1 0.003 0.073 13.79 5.3.0 0.003 0.057 13.77
preferences:dark mode live preview
40.78 ms | 401 KiB | 5 Q